我最近在一次采访中被问到这个问题,我可以给出一个O(nlogn)解决方案,但找不到O(n)的逻辑。有人可以用O(n)解决方案帮助我吗?
在数组中找到最长数字序列的长度
示例: 输入:2 4 6 7 3 1 输出:4(因为1,2,3,4是一个序列,即使它们不在连续的位置)
在消耗的空间方面,解决方案也应该是现实的。即使使用10亿个数组
,解决方案也应该是现实的答案 0 :(得分:3)
对于非连续数字,您需要在O(n)
中对它们进行排序。在这种情况下,您可以使用BitSet。
int[] ints = {2, 4, 6, 7, 3, 1};
BitSet bs = new BitSet();
IntStream.of(ints).forEach(bs::set);
// you can search for the longer consecutive sequence.
int last = 0, max = 0;
do {
int set = bs.nextSetBit(last);
int clear = bs.nextClearBit(set + 1);
int len = clear - set;
if (len > max)
max = len;
last = clear;
} while (last > 0);
System.out.println(max);
答案 1 :(得分:1)
遍历数组并构建哈希映射,其键是输入数组中的数字,值是一个布尔变量,指示元素是否已被处理(最初都是假的)。再次遍历并执行以下操作:当您检查数字a
时,在哈希映射中为该元素设置值true,并立即检查哈希映射是否存在元素a-1
和{{1} }。如果找到,则将它们在哈希映射中的值表示为true,并继续检查它们的邻居,增加当前连续子序列的长度。没有邻居时停止,并更新最长。在数组中向前移动并继续检查未处理的元素。乍一看这个解决方案是a+1
并不明显,但只有两个数组遍历和哈希映射确保输入的每个元素只处理一次。
主要教训 - 如果必须减少时间复杂度,通常需要使用额外的空间。