zoukankan      html  css  js  c++  java
  • 第k大元素

    在数组中找到第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);
  • 相关阅读:
    WINDOWS SERVER 2008 RD服务器搭建
    EXCEL技巧——SUBTOTAL函数巧妙应用
    快速理解几种常用的RAID磁盘阵列级别
    有道云笔记去除左下角广告
    git教程
    .Net导出pdf文件,C#实现pdf导出
    时间控件只显示年月
    C#中日期和时间相加的方法
    JS获取当前时间
    六大设计原则
  • 原文地址:https://www.cnblogs.com/573583868wuy/p/8934679.html
Copyright © 2011-2022 走看看