简体   繁体   中英

Running several iterations in a while loop

I am trying to solve a problem of finding the smallest and second smallest element in an array.

I am thinking of putting two pointers on the 0th index of the array. Both the pointers move from left to right traversing the entire array. First pointer ptr1 determines the min element while the second pointer intends to determine the second min element. The first pointer works ok but the second pointer doesn't traverse. While loop exits only after 1 iteration of the second pointer.

Is it possible to have n pointers in a while loop & make them traverse from left to right turn by turn?

Or I am doing something wrong.

Below is the code

int arr[] = {12,13,1,10,34,1}; 
        int ptr1 = 0;
        int ptr2 =0;
        int min = Integer.MAX_VALUE;
        int minSec = Integer.MAX_VALUE;
        int arrLen=arr.length-1;

        while(ptr1<arrLen && ptr2<arrLen){

            if(arr[ptr1]<min){  // this if works great finds the min element
                min=arr[ptr1];
                ptr1++;
            }else{
                ptr1++;
            }

            //flow enters once & exits the while loop
            if(ptr1==arrLen && arr[ptr2]<minSec && arr[ptr2]>min){
                minSec=arr[ptr2];
                ptr2++;
            }else if(ptr1==arrLen){
                ptr2++;
            }
        }

      System.out.println("min: " + min + " second min: "+ minSec)

output: min: 1 second min: 12

the correct output should be min: 1 second min: 10

I am able to solve the problem with another approach, code below. I just need to know about the while loop approach.

for (int i = 0; i <= arrLen ; i ++)
        {
            /* If current element is smaller than first
              then update both first and second */
            if (arr[i] < min)
            {
                minSec = min;
                min = arr[i];
            }

            /* If arr[i] is in between first and second
               then update second  */
            else if (arr[i] < minSec && arr[i] != min)
                minSec = arr[i];
        }

Because ptr2 value is 0 until loop reach the end

if(ptr1==arrLen && arr[ptr2]<minSec && arr[ptr2]>min){
                minSec=arr[ptr2];
                ptr2++;
}

and enter into the if condition only ptr1==arrLen then you select the minSec value as minSec=arr[ptr2] . No point of putting this condition here.

So second if condition will be like

if(arr[ptr2]<minSec && arr[ptr2]>min){
   minSec=arr[ptr2];
   ptr2++;
}else{
   ptr2++;
}

Your problem is that the first if statement still works even if you found the smallest number. So all over traversed elements are either greater as or equal to the smallest number. That means pointer 1 is incremented every "while step". In your second if statement you check if pointer 1 is equal to array length but this case is present in only one "while step".

PS: Just let java sort your array. The work is already done for you ;)

You do not need two pointers

int arr[] = {12,13,1,10,34,1}; 
final int arrLen=arr.length;
int min = Integer.MAX_VALUE;
int minSec = Integer.MAX_VALUE;
for (int e=0; e<arrLen; e++) {
    final int v = arr[e];
    if (v<minSec && v>min)
        minSec = v;
    if (v<min && v<minSec)
        min = v;
}
if (min>minSec)
    min = minSec;

The problem is in this while(ptr1<arrLen && ptr2<arrLen) statement coupled with moving the second pointer only when ptr1 is at length.

What happens is ptr1 is at arrLen so the second pointer iterates once, but because you use an && when ptr1<arrLen is evalued to be false the entire loop exits. Using an or will not fix this because you have other problems in the code that will cause an IndexOutOfBoundsError.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM