如何从Java中的循环列表中获取最小数字?

时间:2013-08-14 06:52:25

标签: java

让我们假设我有一个像这样的圆形列表

circularList = [12, 62, 76, 92, 3, 7, 12, 19].

从上面的列表中获取最小数字的最有效方法是什么。

6 个答案:

答案 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 ;
    }
}