阵列游戏解决方案,无需重新创建阵列

时间:2018-07-02 08:07:20

标签: java arrays optimization

我正在尝试为一个问题陈述创建一个程序,该程序是一个数组游戏,其中2个人正在玩给定数组的游戏,其中人物A先行,而人物B交替玩。

由于玩家执行以下操作,因此每回合数组的长度减少1: 1.如果数组的长度为奇数,则从数组中删除中间数字。 2.如果长度是偶数,则玩家可以选择删除中间两个元素之一。

已删除元素的值将添加到当前玩家的分数中。 最后,获胜者由得分最高的人决定。如果两个人的得分都相同,则我们允许A人作为该游戏的发明者获胜。 两名球员都发挥最佳状态。

我为此编写了一个代码,但是在我的代码中,我实际上是在每个循环条件下修改现有数组,这是一项繁重的操作,需要更多的内存和时间。如果输入太大,我的程序将花费2秒钟以上的时间来运行。有什么方法可以优化下面的代码,从而避免修改/重新创建数组。

class TestClass {

    public static void main(String args[]) throws Exception {

        Scanner s = new Scanner(System.in);

        int n = s.nextInt();
        int arr[] = new int[n];

        for (int i = 0; i < n; i++) {
            arr[i] = s.nextInt();

        }

        boolean aTurn = true;
        int aScore = 0, bScore = 0;
        int middle = 0;

        while (n > 0) {
            int point = 0;
            int position = 0;
            int size = arr.length;
            if (size % 2 == 0) {

                middle = size / 2;

                if (arr[middle - 1] > arr[middle]) {
                    point = arr[middle - 1];
                    position = middle - 1;
                } else {
                    point = arr[middle];
                    position = middle;
                }
            } else {
                middle = (size) / 2;
                if (middle == 0) {
                    point = arr[0];
                    position = 0;
                } else {
                    point = arr[middle];
                    position = middle;
                }

            }

            arr = removeElement(arr, position);
            n--;

            if (aTurn) {
                aScore += point;
                aTurn = false;
            } else {
                bScore += point;
                aTurn = true;
            }

        }

        if (aScore == bScore) {
            System.out.println("Person_A 0");
        } else if (aScore > bScore) {
            System.out.println("Person_A " + (aScore - bScore));
        } else {
            System.out.println("Person_B " + (bScore - aScore));
        }

    }

    public static int[] removeElement(int[] original, int element) {
        int[] n = new int[original.length - 1];
        System.arraycopy(original, 0, n, 0, element);
        System.arraycopy(original, element + 1, n, element, original.length - element - 1);
        return n;
    }

}

2 个答案:

答案 0 :(得分:1)

基本上,您需要的是一个数组,该数组之间可以有一个孔/间隙,并且每一步中的间隙都增加1。只能从间隙的任一端除去元素,而不能从任何随机位置除去。

com.yourcompany.product_name

使用此数据结构,您的代码如下。

//an array which has a gap in between and
//elements can be removed from either end of the gap.
private static final class GapArray
{
    private final int[] array;
    private int gapStart;
    private int gapLength;

    private GapArray(int[] array)
    {
        this.array = array;
        this.gapStart = array.length;
    }

    int get(int index)
    {
        checkBounds(index);
        if (index < gapStart)
        {
            return array[index];
        }
        else
        {
            return array[index + gapLength];
        }
    }

    private void checkBounds(int index)
    {
        if (index < 0 || index >= size())
        {
            throw new ArrayIndexOutOfBoundsException(index);
        }
    }
    //index is either just before start of the gap or just after end of gap.
    int remove(int index)
    {
        checkBounds(index);
        if (gapLength == 0)
        {
            gapStart = index;
            gapLength++;
            return array[gapStart];
        }
        else
        {
            if (index == gapStart - 1)
            {
                gapStart--;
                gapLength++;
                return array[gapStart];
            }
            else if (index == gapStart)
            {
                int value = array[gapStart + gapLength];
                gapLength++;
                return value;
            }
            else
            {
                throw new IllegalArgumentException("elements can be removed either end of the gap only");
            }
        }
    }

    int size()
    {
        return array.length - gapLength;
    }
}

答案 1 :(得分:0)

还有另一种解决方案,该解决方案使用动态编程,并且可以反向进行。开始反向玩游戏。因此,在这种情况下,将从末端删除元素。实际上,您不必删除元素,只需维护新起点和终点的索引即可。尝试测试这个。

private static int[] method2(int[] arr)
{
    boolean evenSize = arr.length % 2 == 0;
    Score score = new Score(evenSize ? 1 : 0);
    int start = 0;
    int end = arr.length;
    while (start < end)
    {
        if (start + 1 == end)
        {
            score.addPoints(arr[start]);
            start++;
        }
        else
        {
            if (arr[start] < arr[end - 1])
            {
                score.addPoints(arr[start]);
                start++;
                score.addPoints(arr[end - 1]);
                end--;
            }
            else
            {
                score.addPoints(arr[end - 1]);
                end--;
                score.addPoints(arr[start]);
                start++;
            }
        }
    }
    return score.score;
}

private static class Score
{
    int[] score = new int[2];
    int turn;

    Score(int turn)
    {
        this.turn = turn;
    }

    void addPoints(int point)
    {
        score[turn] += point;
        turn = (turn + 1) % 2;
    }
}