【问题标题】:generating all possible sorted arrays from alternating elements of two sorted arrays从两个排序数组的交替元素生成所有可能的排序数组
【发布时间】:2017-03-10 22:31:10
【问题描述】:

我正在解决以下问题,但在遵循作为this question in stackoverflow 的答案提供的递归解决方案后,我不明白它是如何获取所有结果数组的:

问题是: 给定两个已排序的数组 A 和 B,生成所有可能的数组,使得第一个元素从 A 中取出,然后从 B 中取出,然后从 A 中取出,依此类推,直到数组用完为止.生成的数组应以 B 中的元素结尾。

示例: A = {10, 15, 25} B = {1, 5, 20, 30}

结果数组是: [10 20]、[10 20 25 30]、[10 30]、[15 20]、[15 20 25 30]、[15 30]、[25 30] 建议的解决方案:

public static void main(String[] args) {

    int[] A = {10, 15, 25};
    int[] B = {1, 5, 20, 30};

    Stack<Integer> st = new Stack<>();

    for (int i = 0; i < A.length; i++) {
        st.push(A[i]);
        generateArrays(A, B, i, 0, st, false);
        st.clear();
    }
}

static void generateArrays(int ar1[], int ar2[], int index_of_a, int index_of_b, Stack<Integer> st, boolean first) {
    if (index_of_a >= ar1.length || index_of_b >= ar2.length) {
        st.pop();
        return;
    }

    // take from second if available
    if (!first) {
        for (int j = index_of_b; j < ar2.length; j++) {
            if (ar1[index_of_a] < ar2[j]) {
                st.push(ar2[j]);
                System.out.println(st);
                generateArrays(ar1, ar2, index_of_a + 1, j, st, true);
            }
        }
    }

    // take from first if available
    else if (first) {
        for (int i = index_of_a; i < ar1.length; i++) {
            if (ar1[i] > ar2[index_of_b]) {
                st.push(ar1[i]);
                generateArrays(ar1, ar2, i, index_of_b + 1, st, false);
            }
        }
    }

    st.pop();
}

在我自己手动使用给定的输入示例执行算法后,我没有在结果数组中得到 [10 30], [15 30]。

所以,我尝试通过调试代码来理解,发现 a 的索引b 的索引 每次 for 都递减 i 或 j 上的循环不会继续进行,并且 first 的值正在改变值,直到我们得到 a = 0 的索引和 b = 1 的索引。为什么会发生这种情况?我在算法执行流程中缺少什么?算法如何在输出中得到 [10 30], [15 30]?

【问题讨论】:

  • 我不太明白你的问题。 [10, 30] 和 [15, 30] 不会出现在您的数组输出中吗?
  • 我对我的问题进行了一些编辑,因为我认为这不清楚。它们出现了,但我不明白是如何出现的。
  • 您可以通过在每次调用时简单地切换参数来保存参数first,这样a 在每次调用时变为b,反之亦然,并且只接受具有偶数个参数的解决方案。会大大减少代码的冗余。例如:generateArray(arr1, arr2, indexA, indexB, stack){ acceptIf(stack.size() % 2 == 0); ... generateArray(arr2, arr1, indexB, indexA, stack); ... } 作为伪代码。

标签: java arrays algorithm sorting


【解决方案1】:

请注意,每次调用 generateArrays(),都会弹出堆栈(堆栈是一个对象,因此在所有方法调用中都是相同的)并因此使其回到原始状态,因此您可以假设在每次迭代之后在 for 循环中,堆栈与之前相同。

即正在做:

    st.push(ar1[i]);
    generateArrays(ar1, ar2, i, index_of_b + 1, st, false);

堆栈不受影响。

第一个电话: generateArrays(A, B, i, 0, st, false);

从此循环生成 3 个方法调用:

    for (int i = index_of_a; i < ar1.length; i++) {
        if (ar1[i] > ar2[index_of_b]) {
            st.push(ar1[i]);
            generateArrays(ar1, ar2, i, index_of_b + 1, st, false);
        }
    }

堆栈包含值 [10]、[15] 和 [25]。

[10,30]

stack 为 [10] 时,它会进入前一个循环并生成 2 个调用:

    for (int j = index_of_b; j < ar2.length; j++) {
        if (ar1[index_of_a] < ar2[j]) {
            st.push(ar2[j]);
            System.out.println(st);
            generateArrays(ar1, ar2, index_of_a + 1, j, st, true);
        }
    }

堆栈包含值 [10, 20], [10, 30] 并将它们打印出来,如您所见。

[15,30]

stack 为 [15] 时,它会进入前一个循环并生成 2 个调用:

    for (int j = index_of_b; j < ar2.length; j++) {
        if (ar1[index_of_a] < ar2[j]) {
            st.push(ar2[j]);
            System.out.println(st);
            generateArrays(ar1, ar2, index_of_a + 1, j, st, true);
        }
    }

堆栈包含值 [15, 20], [15, 30] 并将它们打印出来。

编辑:解释更多为什么generateArrays 总是以多一个pop结尾:

generateArrays 将立即弹出(基本情况):

if (index_of_a >= ar1.length || index_of_b >= ar2.length) {
    st.pop();
    return;
}

或在最后弹出:

st.pop();

所有push + generateArrays 将导致+1 push 和+1 pop(每个参数),保持堆栈不变。

【讨论】:

  • 为什么每次循环后都要弹出?我的意思是代码的最后一行。
  • 在 EDIT 中添加了更好的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
  • 2011-01-24
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多