面试难题:数组 size-n 包含来自 [i, i + n)
给定一个未排序的数字数组,编写一个函数,如果数组由连续数字组成,则返回 true。
示例:
如果数组为 {5, 2, 3, 1, 4},则该函数应返回 true,因为该数组具有从 1 到 5 的连续数字。
如果数组为 {83, 78, 80, 81, 79, 82},则该函数应返回 true,因为该数组具有从 78 到 83 的连续数字。
如果数组为 {34, 23, 52, 12, 3 },则该函数应返回 false,因为元素不连续。
如果数组是 {7, 6, 5, 5, 3, 4},则该函数应返回 false,因为 5 和 5 不连续。
我想出了以下算法:
查找数组的最大值和最小值
max-min+1应该是数组的大小
检查重复项
检查之间的所有连续数字
我怎样才能实现第四条路径?(复杂度应为O(n)
)
非常欢迎其他建议。
Given an unsorted array of numbers, write a function that returns true if array consists of consecutive numbers.
Examples:
If array is {5, 2, 3, 1, 4}, then the function should return true because the array has consecutive numbers from 1 to 5.
If array is {83, 78, 80, 81, 79, 82}, then the function should return true because the array has consecutive numbers from 78 to 83.
If the array is {34, 23, 52, 12, 3 }, then the function should return false because the elements are not consecutive.
If the array is {7, 6, 5, 5, 3, 4}, then the function should return false because 5 and 5 are not consecutive.
I came up with the following algo:
find the max and min of the array
max-min+1 should be the size of array
check for duplicates
check for all consecutive numbers in between
How can I achieve the 4th path? (The complexity should be O(n)
)
Other suggestions are most welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果输入数组是 A:
求 A 的最小值和最大值,如果数组大小错误,则返回 False。
创建一个相同大小的新数组 B,最初全为零
对于每个索引 i,让 B[ A[i] - min] = 1。
检查 B 是否仍包含任何零。
每一步都需要 O(n) 时间。
If the input array is A:
Find the minimum and maximum values of A, return False if the array is of the wrong size.
Create a new array, B, of the same size, initially with all zeroes
For each index i, let B[A[i] - min] = 1.
Check to see if B still contains any zeroes.
Each step takes O(n) time.
这应该没问题。 Visited[] 记录原始数组中的数字出现的次数。如果它的任何元素大于 2,则存在重复项,因此返回 false;
由于两个数组的大小都是 max-min+1,因此在循环结束时,visited[] 已满,因为我们访问了 array[] 的所有元素。所以它访问的是空的,一定有重复的地方,但我们不需要打扰,因为那时我们仍然返回 false。
This should be ok. visited[] keeps trace of how many times a number from original array appeared. If any of its elements is greater than two there's a duplicate, so return false;
Since the size of both arrays is max-min+1 at the end of the loop visited[] is full, because we visited all elements of array[]. So it visited is empty, there must be a duplicate somewhere, but we don't need to bother because at that time we're still returned false.
在我看来,这可以在 O(n) 时间内完成,并具有 O(1) 额外空间。
确定数组的最小值和最大值。如果 (max - min + 1) != n,则返回 false。
从数组中的每个元素中减去 min。我们现在有一个包含 [0, n) 范围内的 n 个元素的数组。我们现在只需检查是否有重复项。这可以通过如下代码在线性时间内完成(每个元素最多移动一次):
It seems to me this can be done in O(n) time with O(1) additional space.
Determine min and max of the array. If (max - min + 1) != n, return false.
Subtract min from each element in the array. We now have an array with n elements from the range [0, n). We now just have to check for duplicates. That can be done in linear time (each element is moved at most once) by code like the following:
我不太擅长C,但是你需要做第4步吗?当然,如果 2 为真并且没有重复项,那么它包含该序列,否则它不包含该序列?
I'm not too good at C, but do you need to do step 4? Surely if 2 is true and there are no duplicates then it contains the sequence, otherwise it doesn't?
正如您所要求的,您的算法中的第四步根本不需要(因为#2和#3将保证它们是连续的)
我们可以通过执行所有操作来保存算法的更多比较(以提高其时间复杂度)单次遍历的步骤:
As asked by you, the 4th step in your algo is not needed at all (as #2 and #3 will guarantee that they are consecutive)
We can save many more comparisons(to improve its time complexity) of the algo by doing all the steps in a single traverse:
这是适用于 1..N 的东西,你可以使用算术级数论坛来调整这个 [i,i+n]
Here's something that works for 1..N, you can just use the arithemtic series forumulae to adjust for this [i,i+n]
求数组中的最小元素、最大元素以及元素之和。
它们形成一个艺术级数,元素的总和为: (no.Of element/2)*(2*minElement+(n-1)*differnce)
差值为 1
在这种情况下,如果 sum==(array.length/2)* 则 (2*minElement+(array.length-1)*1) && maxElement==(minElement+(lenght ofArray-1)*1)
那么数字是连续的。
没有额外的空间复杂度,时间复杂度为 O(n)
感谢 @jpalecek 的纠正。现在应该没问题了
Find min element,Max element and sum of elements in the array.
They form an Arthematic Progression and sum of elements is: (no.Of element/2)*(2*minElement+(n-1)*differnce)
difference is 1 in this case
if sum==(array.length/2)*(2*minElement+(array.length-1)*1) && maxElement==(minElement+(lenght ofArray-1)*1)
Then the numbers are consecutive.
There is no additional space complexity and time complexity is O(n)
Thanks @jpalecek for correcting. This should be fine now