从两个排序数组

时间:2017-03-10 22:31:10

标签: java arrays algorithm sorting

我正在解决以下问题,并且在了解了作为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]。

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

1 个答案:

答案 0 :(得分:0)

请注意,每次调用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]

堆栈为[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]

堆栈为[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推送和+1弹出(上面的每个参数),使堆栈保持不变。