让我们假设我有一个类似这样的 circulatList
circularList = [12, 62, 76, 92, 3, 7, 12, 19].
从上面的列表中获得最小数字的最有效方法是什么。
让我们假设我有一个类似这样的 circulatList
circularList = [12, 62, 76, 92, 3, 7, 12, 19].
从上面的列表中获得最小数字的最有效方法是什么。
在列表中移动,记住并比较第一项,记住迄今为止最小的数字,并在我们回到列表的开头时返回它
在这里你可以看到它是如何完成的。
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)遍历列表并将每个值与当前最小值进行比较:
int compareValue = Integer.MAX_VALUE;
for(int value: circularList){
if(value < compareValue);
compareValue = value;
}
2) 如果数据类型实现 Collections.sort ,则对列表进行排序,并仅提取最小值。
Collections.sort(circularList);
除了@No Idea For Name:Collections.min(yourCollection)
在我回答之前我必须说:
首先,你说的和你的例子不匹配。[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)进行比较来返回最小的数字。
基本上只有一种算法可以从任意列表中获取最小元素:
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)
。排序以获得最小值将比仅迭代和测试效率低,如上所述。)
通用列表的单线程解决方案是:
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 ;
}
}