0

So I think my partition method works but I cannot understand or figure out how to do the kthSmallest method. I no longer get out of bounds errors with my partition method which leads me to think that it works and with testing it seems to work. However, my kthSmallest method often gets stuck in an infinite loop and when it does return a value, it is never the correct value.

I have seen examples online that place the pivot between the two subarrays however for our assignment the pivot is always at the end so I often get confused looking at these examples.

Here is what I have:

class Median{
    static int kthSmallest(int[] arr, int left, int right, int k){
        int divider = partition(arr, left, right);
        if(divider == k-1){
            return arr[right];
        }
        else if(divider > k-1){
            return kthSmallest(arr, left, divider-1, k);
        }
        else{
            return kthSmallest(arr, divider, right, (k - divider-1));
        }
    }

    static int partition(int[] arr, int left, int right){   
        int pivot = arr[right];
        int index = left;
        for(int i = left; i < right-1; i++){
            if(arr[i] < pivot){
                swap(arr, index, i);
                index++;
            }
        }
        printArr(arr);
        System.out.println("divider: " + index);
        return index;
    }

    static void swap(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    static void printArr(int[] arr){
        System.out.println();
        for(int index = 0; index < arr.length - 1; index++){
            System.out.print(arr[index] + ", ");
        }
        System.out.print(arr[arr.length-1]);
        System.out.println();
    }

    public static void main(String[] args){
        int[] arr = {34,-1,0,5,3};
        printArr(arr);
        //System.out.println(partition(arr, 0, arr.length-1));
        //printArr(arr);
        System.out.println(kthSmallest(arr, 0, arr.length - 1, 2));

    }

}
hjskeqwe
  • 175
  • 1
  • 9

1 Answers1

0

It seems like what you are trying to do is implement the QuickSelect algorithm, so I recommend taking a look at the Wikipedia article.

Looking at your code, I think you have misinterpreted the "pivot at the end" bit. I believe that what your requirements want is to select the pivot from the end, and then place it in between the two sublists so that your list looks right. For example,

34 -1 0 5 3

should become

-1 0 3 34 5

not

-1 0 34 5 3, where your pivot is not doing its job correctly.

There are also a few problems with your kthSmallest method. Double check the values you pass along in your recursion and you also are missing a case which might cause infinite recursion. Spoilers for if you are absolutely stuck:

You since you don't re-index the list, you should change '(k - divider -1)' to just k.

If left == right then you get unnecessary recursion, so you should just return in that case.

In your partition method, make sure you iterate far enough in the part of the list you are partitioning. Again, just in case you're really stumped:

for(int i = left; i < right-1; i++) should become for(int i = left; i <= right-1; i++)

Wesley
  • 78
  • 1
  • 5
  • YAY thank you. I finally got it working and did what you said by putting the pivot in the middle of the two sub arrays. I also fixed the other two things you said (because I was absolutely stuck / really stumped). Thanks thanks thanks. – hjskeqwe Mar 22 '16 at 22:27
  • Glad the solution worked. Would you mind accepting this answer? It might help people experiencing a similar issue and will help getting your question noticed. For more information, take a look at our [FAQ](http://stackoverflow.com/help/accepted-answer). Thanks and welcome! – Wesley Mar 23 '16 at 04:23