让我们假设我有一个像这样的圆形列表
circularList = [12, 62, 76, 92, 3, 7, 12, 19].
从上面的列表中获取最小数字的最有效方法是什么。
答案 0 :(得分:3)
在列表中移动,记住并比较第一个项目,记住目前为止最小的数字,并在我们回到列表的开头时将其返回
here你可以看到它是如何完成的。
int findMinimum(Node* start)
{
int min = start -> data;
Node* t = start -> link;
while(t != start)
{
if(t -> data < min)
min = t -> data;
t = t -> link;
}
return min;
}
答案 1 :(得分:3)
根据您在其中存储这些元素的数据结构类型,可以:
1)遍历列表并将每个值与当前最小值进行比较:
int compareValue = Integer.MAX_VALUE;
for(int value: circularList){
if(value < compareValue);
compareValue = value;
}
2)如果数据类型实现了Collections.sort,则对列表进行排序,只提取最小值。
Collections.sort(circularList);
答案 2 :(得分:2)
除了@No Idea For Name:Collections.min(yourCollection)
答案 3 :(得分:2)
我必须在回答之前说些什么:
首先,你说的和你的例子不符。 [12, 62, 76, 92, 3, 7]
是循环排序数组。但是你的例子:
[12, 62, 76, 92, 3, 7, 12, 19]
不是循环,只是two sorted arrays
的组合。
第二,如果你谈论抽象的方式来做到这一点。您需要修改一些搜索算法方法。方法的效率取决于你拥有的情况。因此该算法将具有最坏情况,最佳情况和平均案例性能。所以你所谓的“最有效的方式”就是你需要尝试自己的测试用例。
然后我的答案,如果您需要从两个排序数组的组合获得最小数字,我有一些比粗体比较更有效的方法:
int a;
int b = 0;\\your minimum possible value
//l= your array
for(int i=1; i<l.size;i++){
b=l[i-1];
a=l[i];
if(b>a) // find the break point of the two sorted arrays
if(a<l[0])
return a;
else
return l[0];
}
return l[0]; // in case the array already sorted(break point in 0 and l.size)
这样你的循环将在找到数组的断点时停止,并通过比较第一个数字(12)和第二个数组的第一个数字(3)来返回最小的数字。
答案 4 :(得分:1)
从根本上只有一种算法可以从任意列表中获取最小元素:
smallest = unset
for each element in list:
if smallest is unset OR element less than smallest:
smallest = element
这如何映射到代码取决于特定的列表数据结构,甚至特定的编程语言也可能有所不同。但基本结构是一样的,并没有特别有效的方法。 (复杂性为O(N)
,其中N
是列表长度。)
唯一可以改进的方法是约束列表。例如,如果列表已经以最小的第一个排序,则获取最小元素只是获取第一个元素的问题。
(但是对列表进行排序的成本至少为O(N)
...并且可能为O(NlogN)
。排序以获得最小值将更少高效而不仅仅是迭代和测试,如上所述。)
答案 5 :(得分:0)
通用列表的单线程解决方案是:
int minValue= Integer.MAX_VALUE ;
for(int e: circularList )
if( e < minValue ) minValue= e ;
对于基于数组的排序循环列表,其中第一个元素的位置是已知的:
minValue= circularList[firstElement] ;
对于基于数组的已排序循环列表,其中已知最后一个元素的位置:
if( lastElement+1 >= circularList.length )
minValue= circularList[0] ;
else
minValue= circularList[lastElement+1] ;
对于基于数组的排序循环列表,其中第一个和最后一个元素的位置是未知的:
int minValue= Integer.MAX_VALUE ;
int prevValue= Integer.MIN_VALUE ;
for(int e: circularList ) {
if( e < minValue )
minValue= e ;
if( e < prevValue ) {
break;
}
prevValue= e ;
}
对通用列表的多处理器友好解决方案是:
int threadCount= 8 ;
int nextStart= 0 ;
MinimumFindingThread[] threads= MinimumFindingThread[threadCount] ;
while( threadCount > 0 ) {
count= ( circularList.size() - nextStart ) / threadCount ;
threads[threadCount-1]= new MinimumFindingThread(circularList,nextStart,nextStart+count) ;
threads[threadCount-1].start();
nextStart= nextStart+count ;
threadCount--;
}
int threadCount= 8 ;
int minValue= Integer.MAX_VALUE ;
while( threadCount > 0 ) {
threads[threadCount-1].join();
theadMin= threads[threadCount-1].getResult() ;
if( theadMin < minValue ) minValue= theadMin ;
threadCount--;
}
class MinimumFindingThread extends Thread {
int[] list;
int from;
int to;
int minValue;
public MinimumFindingThread(int[] list,int from,int to) {
this.list= list ;
this.from= from ;
this.to= this.to ;
}
public void run() {
int minValue= Integer.MAX_VALUE ;
for(int e: this.list[this.from:this.to] )
if( e < minValue ) minValue= e ;
this.minValue= minValue ; ;
}
public int getResult() {
return this.minValue ;
}
}