0

Let us suppose i have a circulatList something like this

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

What will be most efficent way to get smallest number from the above list.

Ankur Lathi
  • 7,636
  • 5
  • 37
  • 49
Programmer
  • 455
  • 2
  • 8
  • 25
  • 2
    it looks like a flat array ? – sanbhat Aug 14 '13 at 06:54
  • 1
    http://stackoverflow.com/questions/15995458/how-to-find-the-minimum-value-in-an-arraylist-along-with-the-index-number-jav – Darshan Mehta Aug 14 '13 at 06:54
  • Is that a list or an array ? can you precise the type of object you want to work on ? – benzonico Aug 14 '13 at 06:54
  • I will want to know efficent algorithim to get this done i am not asking answer is coding form so its not a duplicate question – Programmer Aug 14 '13 at 06:56
  • Can you please explain a bit more? In particular, do you want to know how to implement iteration of a new (as opposed to "library") circular list type? If yes, are you interested in a linked, or array-based one? – Mario Rossi Aug 14 '13 at 08:06
  • Since it's a sorted circular array there is a O(log N) solution for it. You'd only need to locate the spot which is the border between the two sorted parts. You could perform a binary search to find the border and it takes O(log N). – Zahra Apr 07 '14 at 12:14
  • By the way, this is NOT a duplicate question since the input array in this case is a *circular array*, NOT an arbitrary array or a regular sorted array. – Zahra Apr 07 '14 at 12:19
  • though here's the actual duplicate Q on SO: http://stackoverflow.com/questions/2834652/seaching-for-an-element-in-a-circular-sorted-array – Zahra Apr 07 '14 at 12:26

6 Answers6

3

move through the list, remembering and comparing the first item, remembering the smallest number so far and returning it when we got back to the start of the list

here you can see how it is done.

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; 
}  
No Idea For Name
  • 11,411
  • 10
  • 42
  • 70
3

Depending on the type of data structure you have stored those elements in you can either:

1) Iterate through the list and compare every value with the current smallest value:

int compareValue = Integer.MAX_VALUE;
for(int value: circularList){
    if(value < compareValue);
        compareValue = value;
}

2) Sort the list if the data type implements Collections.sort and just extract the smallest value.

Collections.sort(circularList);
leigero
  • 3,233
  • 12
  • 42
  • 63
2

In addition to @No Idea For Name: Collections.min(yourCollection)

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • totally correct, but i think he is talking on the abstract way to do it... – No Idea For Name Aug 14 '13 at 06:59
  • Wouldn't work for primitive types, which seems to be the case. But I agree with No Idea ("For Name" is your last name, right? :-) ): we don't know what kind of abstraction the OP is thinking of. Or, perhaps on the contrary: he wants to know how to implement iteration for a circular list (list or array-based). – Mario Rossi Aug 14 '13 at 08:03
2

i must say something before my answer that:

first, what you say and your example doesn't match. [12, 62, 76, 92, 3, 7] is circular sorted array. however your example :

[12, 62, 76, 92, 3, 7, 12, 19]

is not a circular, that's just combination of two sorted arrays.

And second, If you talk about the abstract way to do it. You need to modify some searching algorithm method. the efficiency of the method is depend on the case you have. so the algorithm will have its Worst case, Best case, and Average case performance. So what you call "most efficent way" is something that you need to try with your own test case.

Then my answer, if what you need to get smallest number from combination of two sorted arrays, i have something that more efficient way than bold compare:

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)

with this your looping will stop when they find the break point of the array, and return the smallest number by comparing the first number(12) with second array first number(3).

Angga
  • 2,305
  • 1
  • 17
  • 21
  • Can you please explain what a "circular shorted array" is? I have the feeling I'm missing something quite big. – Mario Rossi Aug 14 '13 at 08:39
  • OK. I think I understand. They are also known as sorted lists (that also happen to be circular, and in this case array-based). In your example `[12, 62, 76, 92, 3, 7]`, the (circular) list would start on element 4 (0-based, and of value 3), and end on element 3 (of value 92). `[12, 62, 76, 92, 3, 7, 12, 19]` would be the concatenation of "shorted" list `[12, 62, 76, 92, 3, 7, 12]` and `[19]`, or `[12, 62, 76, 92, 3, 7]` and `[12, 19]`. Several other combinations being possible, of course. Or, as you say, 2 non-circular shorted arrays `[12, 62, 76, 92]` and `[3, 7, 12, 19]`. Am I right? – Mario Rossi Aug 14 '13 at 08:47
  • the first statement is yes. And for the second, `[12, 62, 76, 92, 3, 7, 12, 19]` is combination of shorted arrays [12, 62, 76, 92] and [3, 7, 12, 19] – Angga Aug 14 '13 at 08:51
  • Thanks. My impression is that several of us didn't understand what the OP and you meant by "shorted list". "Sorted list" is a much more common term. I'd suggest you both to use it in the future. – Mario Rossi Aug 14 '13 at 09:00
  • Yep, I fix that, thanks for your correction. :) – Angga Aug 14 '13 at 16:10
1

There is fundamentally only one algorithm for getting the smallest element from an arbitrary list:

  smallest = unset
  for each element in list:
      if smallest is unset OR element less than smallest:
          smallest = element

How this maps to code depends on the specific list data structure, or even a specific programming language can vary. But the basic structure is the same, and there are no specially efficient ways of doing it. (The complexity is O(N) where N is the list length.)

The only way you can improve on this is by constraining the list. For instance, if the list is already sorted with smallest first, then the getting the smallest element is simply a matter of getting the first one.

(But the cost of sorting the list is going to be at least O(N) ... and probably O(NlogN). Sorting to get the smallest value is going to be less efficient than just iterating and testing, as above.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • What it mean here smallest = unset i did not get you and i am looking solution in Java – Programmer Aug 14 '13 at 07:12
  • @JavaProgrammer - if you are a Java programmer ... you don't need someone else to write this for you. Besides, you haven't shown us the code for your "circular list" data structure. – Stephen C Aug 14 '13 at 07:16
  • This is pseudo-code. *"smallest = unset"* means that the variable named "smallest" starts out in a state that doesn't hold a valid value. Depending on the type and the programming language, that would be implemented in various ways. – Stephen C Aug 14 '13 at 07:20
  • If you need someone to code this for you in Java, I suggest you visit a "rent-a-coder" site and pay for someone to do it for you. – Stephen C Aug 14 '13 at 07:22
  • thanks Stephen for information – Programmer Aug 14 '13 at 07:22
  • @DroidTeahouse - A "circular list" is not a list. It is a graph. You don't / should expect a list algorithm to apply to a different kind of data structure. And you **shouldn't** design a list algorithm to do that either: it is bad for performance. A fundamental property of a (non-broken) finite list data structure is that you can iterate the elements in a finite time. – Stephen C Oct 29 '17 at 02:01
  • Now you do technically have a point, in that the `List` api does not require the list to be finite. However, finding the largest element in an infinite (or unbounded) list is a mathematical impossibility without some foreknowledge. – Stephen C Oct 29 '17 at 02:07
  • It is a google question: You are given a list of numbers. When you reach the end of the list you will come back to the beginning of the list (a circular list). Write the most efficient algorithm to find the minimum # in this list. Find any given # in the list. The numbers in the list are always increasing but you don’t know where the circular list begins, ie: 38, 40, 55, 89, 6, 13, 20, 23, 36. – Droid Teahouse Oct 29 '17 at 02:08
  • OK. So that interpretation makes some sense. However, "circular list" is an egregious abuse of terminology. And expecting people to understand such terms **without the context** is ... ridiculous. – Stephen C Oct 29 '17 at 02:16
  • But, note that the OP's list doesn't match that definition. The numbers in the list are not always increasing. So the best we can say is that the question is too unclear to be answered. Or answer it like I did ... in the more general way. – Stephen C Oct 29 '17 at 02:19
  • I agree that graph is most versatile structure and useful always, provides isVisited state for such a situation, and that maybe it is an edge list. The question has to state that the pairs are in an edge list or it makes no sense and they are just values in a list. A greedy solution with deletion offers an alternative to the over engineered graph solution with unsorted/duplicates – Droid Teahouse Oct 29 '17 at 17:37
0

A single-thread solution to a generic list is:

int minValue= Integer.MAX_VALUE ;
for(int e: circularList )
    if( e < minValue ) minValue= e ;

For an array-based, sorted circular list where the first element's position is known:

minValue= circularList[firstElement] ;

For an array-based, sorted circular list where the last element's position is known:

if( lastElement+1 >= circularList.length )
    minValue= circularList[0] ;
else
    minValue= circularList[lastElement+1] ;

For an array-based, sorted circular list where first and last element's positions are unknown:

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

A multiprocessor-friendly solution to a generic list is:

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 ;
    }
}
Mario Rossi
  • 7,651
  • 27
  • 37