【问题标题】:Moving and merging elements in array?移动和合并数组中的元素?
【发布时间】:2016-05-29 02:35:25
【问题描述】:

我对 Java 很陌生,但我已经掌握了基础知识...

所以我有一个包含 4 个整数的数组,我需要将它们移到数组的前面,或者如果它们相等则合并它们:

  • {0,1,0,2} 变成 {1,2,0,0}
  • {2,1,0,2} 变成 {2,1,2,0}
  • {1,1,0,0} 变成 {2,0,0,0}
  • {0,2,0,2} 变成 {4,0,0,0}
  • {1,1,3,3} 变成 {2,6,0,0}
  • {2,2,2,2} 变成 {4,4,0,0} 等等...

这是我目前所拥有的:

public void combine(int[] row)
{  
    for (int i = 0; i < row.length-1; i++)
    {
        if (row[i] == 0 && row[i+1] > 0) //move
        {
           row[i] = row[i+1];
           row[i+1] = 0;
        }
        if (row [i] == row[i+1] && row[i] > 0) //merge
        {
            row[i] = 2 * row[i];
            row[i+1] = 0;
        }
    }
    System.out.println(row[0]);
    System.out.println(row[1]);
    System.out.println(row[2]);
    System.out.println(row[3]);
}

问题是:

  • {0,1,0,2} 变为 {1,0,2,0}
  • {0,2,0,2} 变为 {2,0,2,0}
  • {1,1,3,3} 变为 {2,3,3,0}
  • {2,2,2,2} 变为 {4,2,2,0}

它没有完全合并,或者由于某种原因它只移动和合并一次?我想知道我做错了什么,以便我学习,谢谢!

请问,谁能帮我解决这个问题?非常感谢...谢谢!

【问题讨论】:

  • 我认为您的问题有两个步骤。首先,您需要对数组进行排序以将所有零推到右侧。这种有冒泡排序的味道。接下来,您需要执行一个合并步骤,您可以选择合并两个条目。

标签: java arrays for-loop


【解决方案1】:

您似乎需要先移动到前面,然后合并您的元素,然后再次移动到前面。合并实现起来比较简单,检查数组中的偶数索引;如果两个相邻元素相等,则乘以 2 并将另一个设置为 0。类似于,

private static void merge(int[] arr) {
    for (int i = 0; i + 1 < arr.length; i += 2) {
        if (arr[i] == arr[i + 1]) {
            arr[i] *= 2;
            arr[i + 1] = 0;
        }
    }
}

我会从swap 开始,像这样移动数组中的元素

private static void swap(int[] arr, int i, int j) {
    if (i == j) {
        return;
    }
    int t = arr[i];
    arr[i] = arr[j];
    arr[j] = t;
}

然后对于移到前面,从左边开始检查每个元素;当我们得到一个0 时,开始从右边寻找一个非零然后swap

private static void moveToFront(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] == 0) {
            for (int j = arr.length - 1; j > i; j--) {
                if (arr[j] != 0) {
                    swap(arr, i, j);
                }
            }
        }
    }
}

接下来,combine; 移到前面合并然后移到前面再次

public static void combine(int[] row) {
    moveToFront(row);
    merge(row);
    moveToFront(row);
}

最后,我们可以像这样测试它

public static void main(String[] args) {
    int[][] arr = { { 0, 1, 0, 2 }, // turns into {1,2,0,0}
            { 2, 1, 0, 2 }, // turns into {2,1,2,0}
            { 1, 1, 0, 0 }, // turns into {2,0,0,0}
            { 0, 2, 0, 2 }, // turns into {4,0,0,0}
            { 1, 1, 3, 3 }, // turns into {2,6,0,0}
            { 2, 2, 2, 2 } };// turns into {4,4,0,0}
    for (int[] a : arr) {
        combine(a);
        System.out.println(Arrays.toString(a));
    }
}

我得到(按要求)

[1, 2, 0, 0]
[2, 1, 2, 0]
[2, 0, 0, 0]
[4, 0, 0, 0]
[2, 6, 0, 0]
[4, 4, 0, 0]

【讨论】:

    【解决方案2】:

    问题是您的代码中的移动和合并仅移动了 1 步,而移动和合并可能移动了 2 步或更多步。这不是 java 问题,而是算法问题。

    这是一个使用i和j的两点问题,i是记录你要移动数字的位置,j是你伸出最远的位置来获取数字。

    【讨论】:

    • 好的,谢谢!我将如何实现这一点,究竟是什么?所以我需要一个嵌套的for循环,j从数组的末尾开始?
    • 是的。一个嵌套循环,但实际上仍然具有 O(n) 复杂度。
    猜你喜欢
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多