Algorithm 访谈问题-在未排序的数组中查找kthsmalle元素
这要求在非负整数的未排序数组中找到第k个最小元素 这里的主要问题是内存限制:(这里我们可以使用恒定的额外空间 首先,我尝试了一个Algorithm 访谈问题-在未排序的数组中查找kthsmalle元素,algorithm,Algorithm,这要求在非负整数的未排序数组中找到第k个最小元素 这里的主要问题是内存限制:(这里我们可以使用恒定的额外空间 首先,我尝试了一个O(n^2)方法[没有任何额外内存],它给了我TLE 然后我尝试使用优先级队列[额外内存],这给了我MLE:( 你知道如何在时间限制内用恒定的额外空间来解决这个问题吗。你可以使用一个O(n^2)方法进行一些修剪,这将使程序像O(nlogn):) 声明两个变量low=位置小于k的最大值high=位置大于k的最小值 跟踪已处理的低值和高值 每当新值出现时,检查它是否在[低、
O(n^2)
方法[没有任何额外内存],它给了我TLE
然后我尝试使用
优先级队列
[额外内存],这给了我MLE
:(
你知道如何在时间限制内用恒定的额外空间来解决这个问题吗。你可以使用一个O(n^2)
方法进行一些修剪,这将使程序像O(nlogn)
:)
low=位置小于k的最大值high=位置大于k的最小值
低值
和高值
[低、高]
边界内。如果是
则处理它,否则跳过该值TLE
和MLE
:)
看看我的代码:
int low=0,high=1e9;
for(int i=0;i<n;i++) // n is the total number of element
{
if(!(A[i]>=low&&A[i]<=high)) // A is the array in which the element are saved
continue;
int cnt=0,cnt1=0; // cnt is for the strictly less value and cnt1 for same value. Because value can be duplicate.
for(int j=0;j<n;j++)
{
if(i!=j&&A[i]>A[j])
cnt++;
if(A[i]==A[j])
cnt1++;
if(cnt>k)
break;
}
if(cnt+cnt1<k)
low=A[i]+1;
else if(cnt>=k)
high=A[i]-1;
if(cnt<k&&(cnt+cnt1)>=k)
{
return A[i];
}
}
int低=0,高=1e9;
对于(int i=0;i=low&&A[i]k)
打破
}
if(cnt+cnt1=k)
高=A[i]-1;
if(cnt=k)
{
返回一个[i];
}
}
您可以就地执行
其思想类似于,但仅在数组的相关部分递归,而不是全部递归。注意,该算法可以很容易地用O(1)额外的空间来实现,因为它的递归调用是一个复杂的过程
这将导致平均情况下的
O(n)
解决方案(请确保随机选择一个轴,以确保您不会陷入预先设计的边缘情况,如排序列表)。这可以改进为最坏情况O(n)
使用,但常数明显更差。对问题的答案进行二进制搜索
2主要观察结果如下:
- 假设数组中的所有值都是“int”类型,那么它们的范围可以定义为[0,2^31]。那就是你的搜索空间李>
- 给定一个值x,我总是可以用O(n)来判断第k个最小元素是小于x还是大于x
start = 0, end = 2^31 - 1
while start <= end
x = (start + end ) / 2
less = number of elements less than or equal to x
if less > k
end = x - 1
elif less < k
start = x + 1
else
ans = x
end = x - 1
return ans
start=0,end=2^31-1
当启动k时
结束=x-1
elif小于k
开始=x+1
其他的
ans=x
结束=x-1
返回ans
希望这有帮助 我相信我找到了一个类似于@AliAkber的解决方案,但更容易理解(我跟踪的变量更少) 它通过了InterviewBit的所有测试 下面是代码(Java):
public int kthsmallest(最终列表a,int k){
int lo=整数最小值;
int hi=整数最大值;
int champ=-1;
对于(int i=0;ilo&&iValk&&iVallo)lo=iVal;
如果(计数>=k&&(champ==-1 | | iVal
你不能对数组进行排序吗?你也在考虑递归空间吗?@GiorgiNakeuri不,我不能对数组进行排序array@sonukumar对虽然我得到了解决办法。阿里·阿克伯的回答涵盖了我的要求。现在是AC:)递归所需的空间呢?@sonukumar递归完成时-平均情况下为对数。它也可以通过记忆索引,在常量空间中进行迭代。无论如何,大多数编译器都会为您进行此优化,因为
public int kthsmallest(final List<Integer> a, int k) {
int lo = Integer.MIN_VALUE;
int hi = Integer.MAX_VALUE;
int champ = -1;
for (int i = 0; i < a.size(); i++) {
int iVal = a.get(i);
int count = 0;
if (!(iVal > lo && iVal < hi)) continue;
for (int j = 0; j < a.size(); j++) {
if (a.get(j) <= iVal) count++;
if (count > k) break;
}
if (count > k && iVal < hi) hi = iVal;
if (count < k && iVal > lo) lo = iVal;
if (count >= k && (champ == -1 || iVal < champ))
champ = iVal;
}
return champ;
}