此problem要求在未排序的非负整数数组中找到第k个最小元素。
这里的主要问题是内存限制:(这里我们可以使用恒定的额外空间。
首先,我尝试了O(n^2)
方法[没有任何额外的记忆]给了我TLE
然后我尝试使用priority queue
[额外记忆]给了我MLE
:(
任何想法如何在持续的额外空间和时间限制内解决问题。
答案 0 :(得分:2)
您可以使用O(n^2)
方法进行一些修剪,这会使程序像O(nlogn)
:)
low = maximum value which position is less than k
和high = lowest value which position is greater than k
low
和high
值。[low , high]
边界内。如果yes
则处理它,否则跳过该值。那就是:)我认为它会通过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];
}
}
答案 1 :(得分:0)
您可以执行就地Selection Algorithm。
这个想法类似于quicksort,但只能在数组的相关部分进行递归,而不是全部。请注意,该算法可以很容易地用O(1)额外空间实现 - 因为它的递归调用是tail call。
这导致O(n)
解决方案的平均情况(只需确保随机选择一个支点,以确保您不会陷入预先设计的边缘情况,例如排序列表) 。使用median of median technique可以将其改进为最差情况O(n)
,但常量会更差。
答案 2 :(得分:0)
二进制搜索问题的答案。
这里有2个主要观察结果:
粗略的伪代码:
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
希望这会有所帮助。
答案 3 :(得分:0)
我相信我找到了一个类似于@AliAkber的解决方案,但稍微容易理解(我跟踪的变量较少)。
它通过了InterviewBit的所有测试
这里是代码(Java):
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;
}