• LintCode-Kth Largest Element


    Find K-th largest element in an array.

    Note

    You can swap elements in the array

    Example

    In array [9,3,2,4,8], the 3th largest element is 4

    Challenge

    O(n) time, O(1) space

    Analysis:

    We use Quick partition to perform the selection. We use the method of "median of medians", i.e., median of every group of 5 elements, to select the pivot. In this way, we can guarantee that the complexity in the worst case is still O(n).

    Reference:

    http://blog.csdn.net/v_JULY_v/article/details/6370650

    http://blog.csdn.net/v_july_v/article/details/6431001

    Solution:

     1 class Solution {
     2     //param k : description of k
     3     //param numbers : array of numbers
     4     //return: description of return
     5     public int kthLargestElement(int k, ArrayList<Integer> numbers) {
     6         return selectK(numbers,0,numbers.size()-1,k);
     7     }
     8 
     9     public void insertSort(ArrayList<Integer> numbers, int start, int end){
    10         for (int i=start;i<=end;i++){
    11             int key = numbers.get(i);
    12             int ind = i-1;
    13             while (ind>=start && numbers.get(ind)<key){
    14                 numbers.set(ind+1,numbers.get(ind));
    15                 ind--;
    16             }
    17             numbers.set(ind+1,key);
    18         }
    19     }        
    20 
    21     public void swap(ArrayList<Integer> numbers, int x, int y){
    22         int temp = numbers.get(x);
    23         numbers.set(x,numbers.get(y));
    24         numbers.set(y,temp);
    25     }
    26 
    27     //This function selects the kth largest number in the range numbers[start...end].
    28     //For example, if start=8, end=11, k=2, we will select the 2nd largest number in the range numbers[8...11].
    29     //So in the code, we need be very carefull about the index of the kth largest number.
    30     public int selectK(ArrayList<Integer> numbers, int start, int end, int k){
    31         if (end-start+1<=5){
    32             insertSort(numbers,start,end);
    33             return numbers.get(start+k-1);
    34         }
    35 
    36         //Get the median of every group of 5 elements.
    37         int pos = start;
    38         int cur = start;
    39         while (true){
    40             int curEnd = Math.min(cur+4,end);
    41             //For even number, we pick up the later median, that is why there is plus one at last.
    42             int median5 = selectK(numbers,cur,curEnd,(curEnd-cur+1)/2+1);
    43             swap(numbers,pos,(curEnd+cur+1)/2);
    44             pos++;
    45             if (curEnd==end) break;
    46             else cur = curEnd+1;
    47         }
    48 
    49         //Get the median of median5s, i.e., median of [start...pos-1].
    50         int median = selectK(numbers,start,pos-1,(pos-start)/2+1);
    51         int mInd = start;
    52         for (int i=start;i<=start+4;i++) 
    53             if (numbers.get(i)==median){
    54                 mInd = i;
    55                 break;
    56             }
    57 
    58         
    59         //Use the median as the pivot to partition [start...end].
    60         swap(numbers,mInd,end);
    61         int p1 = start, p2 = end-1;
    62         while (p1<end && numbers.get(p1)>median) p1++;
    63         while (p2>0 && numbers.get(p2)<median) p2--;
    64         while (p1<p2){
    65             swap(numbers,p1,p2);
    66             p1++;
    67             p2--;
    68             while (p1<end && numbers.get(p1)>median) p1++;
    69             while (p2>0 && numbers.get(p2)<median) p2--;
    70         }
    71         swap(numbers,p1,end);
    72         if (p1-start+1==k)
    73             return numbers.get(p1);
    74         else if (p1-start+1>k)
    75             return selectK(numbers,start,p1-1,k);
    76         else 
    77             return selectK(numbers,p1+1,end,k-(p1-start+1));
    78     }
    79             
    80         
    81             
    82 };
  • 相关阅读:
    Leet_Code_567_字符串排列
    LeetCode_424_替换后的最长字符串
    LeetCode_139_单词拆分
    为Linux 添加自定义命令
    javax.validation 自定义校验器
    MYBatis 动态SQL
    SPRING BOOT 15.1 TEST
    B-树和B+树的应用:数据搜索和数据库索引
    设计模式-代理
    数据结构与算法
  • 原文地址:https://www.cnblogs.com/lishiblog/p/4190935.html
Copyright © 2020-2023  润新知