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