算法:从多个有序列表中搜索整数的递增序列

时间:2018-10-12 00:31:44

标签: java algorithm sorting

我正在尝试找到从排序的整数数组(列表)的数组(或列表)中查找整数序列的最有效方法。 假设我有这个数组

{
{1, 3, 4, 9, 15},
{5, 10, 13},
{2, 6, 11, 17},
{7, 8, 12}
}

然后解决方案应返回连续递增数字的数组

{ {4, 5, 6, 7}, {9, 10, 11, 12} }

结果是,4和9来自第一个子数组,5和10来自第二个子数组,依此类推。约束是最终输出中的所有数组必须具有输入中数组数量的固定长度,即输入中的所有数组必须在结果中的每个数组中提供1个元素。

我们可以假设输入数组已排序,并且输入数组中没有重复项,例如,在示例中,如果9在数组1中,则可以假设9在其他任何输入数组中都不会。

有什么有效的方法吗?除了对数组进行强行强制处理外,我无法提出其他任何建议。可以使用任何数据结构和算法。

谢谢。

1 个答案:

答案 0 :(得分:1)

  1. 从第一个数组中选择第一个值,并将其另存为prevValue

  2. 在每个输入数组中构建一个位置(索引)数组,并将其初始化为0。

  3. 遍历输入数组:

    • 给定输入数组的前进位置,直到值为>= prevValue
      如果到达输入数组的末尾,请停止,操作完成。

    • prevValue更新为找到的值。

  4. 现在,位置数组存储下一个递增值序列的位置。将值保存为结果。

  5. 重复步骤3和4,直到完成。


作为代码,应该是这样的:

private static int[][] findIncrementalSequences(int[][] input) {
    int[] pos = new int[input.length];
    int prevValue = Integer.MIN_VALUE;
    List<int[]> results = new ArrayList<>();
    for (;;) {
        int[] result = new int[pos.length];
        for (int i = 0; i < pos.length; i++) {
            while (pos[i] < input[i].length && input[i][pos[i]] <= prevValue)
                pos[i]++;
            if (pos[i] == input[i].length)
                return results.toArray(new int[results.size()][]);
            prevValue = result[i] = input[i][pos[i]];
        }
        results.add(result);
    }
}

测试

int[][] input = { {1, 3, 4, 9, 15},
                  {5, 10, 13},
                  {2, 6, 11, 17},
                  {7, 8, 12} };
System.out.println(Arrays.deepToString(findIncrementalSequences(input)));

输出

[[1, 5, 6, 7], [9, 10, 11, 12]]

更新

如果每个子结果必须是连续的递增值,那么如果下一个数字不比上一个值高1,则可以将代码修改为从input[0]重新开始。

下面的代码也做了些微更改,以删除重复的数组查找。

private static int[][] findConsecutiveSequences(int[][] input) {
    int[] pos = new int[input.length];
    int nextValue = Integer.MIN_VALUE, value;
    List<int[]> results = new ArrayList<>();
    for (;;) {
        int[] result = new int[pos.length];
        for (int i = 0; i < pos.length; i++) {
            for (;;) {
                if (pos[i] == input[i].length)
                    return results.toArray(new int[results.size()][]);
                if ((value = input[i][pos[i]]) >= nextValue)
                    break;
                pos[i]++;
            }
            if (i == 0 || value == nextValue) {
                result[i] = value;
                nextValue = value + 1;
            } else {
                i = -1; // Restart with input[0]
            }
        }
        results.add(result);
    }
}

输出

[[4, 5, 6, 7], [9, 10, 11, 12]]