在数组中找到第k大的元素
样例
给出数组[9,3,2,4,8],第三大的元素是4
给出数组 [1,2,3,4,5],第一大的元素是5,第二大的元素是4,第三大的元素是3,以此类推
注意
你可以交换数组中的元素的位置
挑战
要求时间复杂度为O(n),空间复杂度为O(1)
分析:利用快排的思想,不断partition
1 <?php 2 //第k大元素 3 4 //用快排的思想:例如找7个元素里面第2大的元素,那么按如下步骤: 5 //1.进行一次快排(将大的元素放在前半段,小的元素放在后半段), 假设得到的中轴为p 6 //2.判断 p == len - k,如果成立,直接输出a[p] 7 //3.如果 p > len - k, 则第k大的元素在前半段,此时更新high = p - 1,继续进行步骤1 8 //4.如果 p < len - k, 则第k大的元素在后半段,此时更新low = p + 1, ,继续步骤1. 9 //由于常规快排要得到整体有序的数组,而此方法每次可以去掉"一半"的元素,故实际的复杂度不是o(nlgn), 而是o(n)。 10 function solution(&$data, $low, $high, $k) 11 { 12 if($low == $high)//与快排不一致的地方,否则$low=$high的情况下会没有返回值 13 { 14 return $data[$low]; 15 } 16 $p = partition($data, $low, $high); 17 $index = count($data) - $k; 18 if($p < $index) { 19 return solution($data, $p+1, $high, $k); 20 } else if($p > $index) { 21 return solution($data, $low, $p-1, $k); 22 } else { 23 return $data[$p]; 24 } 25 } 26 27 function partition(&$data, $low, $high) 28 { 29 $key = $data[$low]; 30 while($low < $high) 31 { 32 while($low<$high && $data[$high]>$key) $high--; 33 $data[$low] = $data[$high]; 34 while($low<$high && $data[$low]<$key) $low++; 35 $data[$high] = $data[$low]; 36 } 37 $data[$low] = $key; 38 return $low; 39 } 40 41 $arr = [4, 3, 5, 6, 2, 1, 7]; 42 $k = 2; 43 $res = solution($arr, 0, count($arr)-1, $k); 44 echo "<pre>"; 45 print_r($res);