我正在尝试找到从排序的整数数组(列表)的数组(或列表)中查找整数序列的最有效方法。 假设我有这个数组
{
{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在其他任何输入数组中都不会。
有什么有效的方法吗?除了对数组进行强行强制处理外,我无法提出其他任何建议。可以使用任何数据结构和算法。
谢谢。
答案 0 :(得分:1)
从第一个数组中选择第一个值,并将其另存为prevValue
。
在每个输入数组中构建一个位置(索引)数组,并将其初始化为0。
遍历输入数组:
给定输入数组的前进位置,直到值为>= prevValue
。
如果到达输入数组的末尾,请停止,操作完成。
将prevValue
更新为找到的值。
现在,位置数组存储下一个递增值序列的位置。将值保存为结果。
重复步骤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]]