Google interview question: selection questions

上一遍文章总结了用quickSort思想解决的问题,那么面试题中自然少不了和selection algorithm相关的题目。

Selection algorithm能在时间复杂度O(N)寻找一个数组中第K大/小的元素,也就是将数组划分成比第K元素大和比第K元素小两部分。对基本的selection algorithm,leetcode有对应的原题可以练习。

https://leetcode.com/problems/kth-largest-element-in-an-array/

 

下面的面试题可以运用selection algorithm的思想来解决。

Question: 

Given an unsorted array of integers, you need to return maximum possible n such that the array consists at least n values greater than or equals to n. Array can contain duplicate values. 
Sample input : [1, 2, 3, 4] -- output : 2 
Sample input : [900, 2, 901, 3, 1000] -- output: 3

这道题看上去似乎与selection algorithm有一些区别,因为事先并不知道要求的K的值。但是,根据题意我们知道K满足一定的条件,即K=max{n>=input[n]},其中n是每个元素在降序中的index。因此,可以用selection algorithm的原理,对K进行binary search,每一次select操作可以减少一半的元素,时间复杂度为O(N),空间复杂度为O(1)。

public class Selection {
    public static void main(String arcg[]){
        int[] array = {1,2,3,4};
        //int[] array = {900,2,901,3,1000};
        findMaxN(array);
        System.out.println(max);
    }
    private static int max;
    public static void findMaxN(int[] array){
        int low = 0, high = array.length-1;
        while(low<=high){
            int n = select(array, low, high);
            if(n+1 < array[n]){
                low = n+1;
            }
            else{
                max = Math.max(max, array[n]);
                high = n-1;
            }
        }
    }
    public static int select(int[] array, int low, int high){
        if(low == high) return low;
        int pivot = array[low], i = low+1, j = high;
        while(i<=j){
            if(array[i] <= pivot){
                swap(array,i,j);
                j--;
            }
            else i++;
        }
        swap(array, low, i-1);
        return i-1;
    }
    public static void swap(int[] array, int i, int j){
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
}

 

posted @ 2015-06-29 01:26  dshao  阅读(183)  评论(0编辑  收藏  举报