我想在数组列表中找到第二个最小值。这是我的代码。有更好的方法吗?
int main(){
int a[5]={7,5,45,89,12};
int smallest=a[0];
int index;
for(int i=0;i<5;i++){
if(a[i]<smallest){
smallest=a[i];
index=i;
}
}
smallest=a[0];
for(int i=0;i<5;i++){
cout<<i;
if((a[i]<smallest )&& (i!=index)){
smallest=a[i];
}
}
cout<<"second smallest value is: "<<smallest;
此代码在O(n)时间内运行?对于第一个循环,它需要n个步骤,而对于另一个循环,它也需要n个步骤。因此,它总共需要O(n)时间复杂度。
这是对的吗?如果我错了,有人可以纠正我吗
答案 0 :(得分:5)
您可以使用STL算法nth_element
,复杂度为 O(n):
#include <iostream>
#include <algorithm>
int main(int argc, char** argv) {
int a[5]={7,5,45,89,12};
std::nth_element(a, a + 1, a + 5);
std::cout << "second smallest value is: " << a[1];
return 0;
}
如果您想保持数组a
不变,可以改用partial_sort_copy
。
int a[5]={7,5,45,89,12}, b[2];
std::partial_sort_copy(a, a + 5, b, b + 2);
std::cout << "second smallest value is: " << b[1];
在这种情况下,复杂性也是 O(n)。
答案 1 :(得分:4)
是的,它是 O(n),但实际上没有必要两次运行该列表。
您可以通过存储最小和最小的值来完成一次。
例如,请考虑以下伪代码:
smallest = a[0]
second = a[1]
if second < smallest:
swap second with smallest
for each index 2 thru a.size - 1 inclusive:
if a[index] < smallest:
second = smallest
smallest = a[index]
else:
if a[index] < second:
second = a[index]
这也是 O(n)但它只通过列表一次,而不是两次。最后,second
保持第二高的值。
请注意,列表{1, 1, 2}
中的第二高值为1
。如果您想以不同方式处理重复项,则需要稍作修改。
在Python中使用示例作为概念证明来实现它,显示结果:
a = [1,45,2,96,4,35]
smallest = a[0]
second = a[1]
if second < smallest:
smallest, second = second, smallest
for index in range (2, len(a)):
if a[index] < smallest:
second = smallest
smallest = a[index]
else:
if a[index] < second:
second = a[index]
print smallest
print second
输出是:
1
2
作为最小和最小的数字。
答案 2 :(得分:1)
你可以用一个循环来处理它:
int smallest = max
int second = max;
for( int i = 0; i < len; ++i){
if( a[i] <= smallest){
second = smallest;
smallest = a[i];
} else if( a[i] < second){
second = a[i];
}
}
max
应该是可能的最高值。 len
数组的长度。
这也将在O(n)时间内运行。
答案 3 :(得分:1)
您可以在循环的一次迭代中执行此操作:
int main(){
int a[5]={7,5,45,89,12};
int smallest = a[0];
int smallest2 = a[0];
for(int i=1;i<5;i++){
if(a[i] < smallest2){
if(a[i] < smallest){
smallest=a[i];
}
else {
smallest2 = a[i];
}
}
}
cout<<smallest << endl;
cout<<smallest2 << endl;
return 0;
}
答案 4 :(得分:1)
解决此问题的另一个好方法是使用MINHEAP。
算法:
从数组中构建一个minheap树。复杂性= O(n)
现在再次提取根节点(最小)并最小化数组。复杂度= O(logn)
现在提取根目录上的第二个最小元素。复杂度= O(logn)。
要找到第k个最小元素,复杂度变为O(n)+ O(klogn)。
这里因为你需要第二个最小元素,所以复杂度是O(n)+ O(2logn)