• LintCode Kth Largest Element


    原题链接在这里:http://www.lintcode.com/en/problem/kth-largest-element/#

    在LeetCode上也有一道,采用了标准的quickSelect 方法,另外写了一篇帖子,代码更加模块化。

    采用的quickSelect方法,取出pivot, 比pivot 小的都放在左边,比pivot大的都放在右边,若是pivot左边包括pivot的个数恰巧等于k, 就返回pivot.

    若是大于k, 就在左边递归寻找第k小的数,若是大于k,就在右边递归寻找 第 (k-left)小的数。

    题目中说要找第k 大的数,其实就是找 numbers.size()-k+1小的数。

    pivot取的是最后一个数,跳出loop时l所在位置一定比pivot大,需要换回来,调换l和end上的数。

    为了保证跳出loop时l上的数比pivot大,中间的 while 循环条件是 numbers.get(l) < pivot 就移动l,另一个while loop 条件却是 number.get(r) >= pivot 移动r, 这是为了防止陷入infinite loop.

    AC Java:

     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 findK(numbers.size()-k,numbers,0,numbers.size()-1);
     7     }
     8     private int findK(int k, ArrayList<Integer> numbers, int start, int end){
     9         if(start >= end){
    10             return numbers.get(start);
    11         }
    12         int m = partition(numbers, start, end);
    13         if(m == k){
    14             return numbers.get(m);
    15         }else if(m < k){
    16             return findK(k, numbers, m+1, end);
    17         }else{
    18             return findK(k, numbers, start, m-1);
    19         }
    20     }
    21     
    22     private int partition(ArrayList<Integer> numbers, int start, int end){
    23         int pivot = numbers.get(start);
    24         int m = start;
    25         int n = start + 1;
    26         while(n<=end){
    27             if(numbers.get(n) < pivot){
    28                 swap(numbers, ++m, n);
    29             }
    30             n++;
    31         }
    32         swap(numbers, start, m);
    33         return m;
    34     }
    35     
    36     private void swap(ArrayList<Integer> numbers, int l, int r){
    37         int temp = numbers.get(l);
    38         numbers.set(l,numbers.get(r));
    39         numbers.set(r,temp);
    40     }
    41 };

    另外一种写法:

     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         if(numbers == null || numbers.size() == 0 || k<1){
     7             return 0;
     8         }
     9         return getKth(numbers.size()-k+1, numbers, 0, numbers.size()-1);
    10     }
    11     
    12     private int getKth(int k, ArrayList<Integer> numbers, int start, int end){
    13         int pivot = numbers.get(end);
    14         int l = start;
    15         int r = end;
    16         while(true){
    17             while(numbers.get(l) < pivot && l<r){
    18                 l++;
    19             }
    20             while(numbers.get(r) >= pivot && r>l){
    21                 r--;
    22             }
    23             if(l == r){
    24                 break;
    25             }
    26             swap(numbers, l, r);
    27         }
    28         //l element is larger than pivot, swap it with pivot
    29         swap(numbers, l, end); 
    30         if(k == l+1){
    31             return numbers.get(l);
    32         }else if(k < l+1){
    33             return getKth(k, numbers, start, l-1);
    34         }else{
    35             return getKth(k, numbers, l+1, end);
    36         }
    37     }
    38     
    39     private void swap(ArrayList<Integer> numbers, int l, int r){
    40         int temp = numbers.get(l);
    41         numbers.set(l,numbers.get(r));
    42         numbers.set(r,temp);
    43     }
    44 };
  • 相关阅读:
    [转载]MATLAB 图像处理命令
    html Window与document区别(轉)
    ICMP数据包结构(转)
    CString,string,char*之间的转换(转)
    word或dword区别
    VS2010 皮肤扩展
    Unicode _T和L和_TXET
    转:git 的常用命令
    git fetch 和 git pull 的区别
    mac git 命令自动补全
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4886844.html
Copyright © 2020-2023  润新知