zoukankan      html  css  js  c++  java
  • 一道关于快排的题目

    这是一道来自LintCode的题目,题目原文是这样的:

    LeetCode对应的题号是215。

    我的做法:

    class Solution {
    public:
        /**
         * @param n: An integer
         * @param nums: An array
         * @return: the Kth largest element
         */
        int kthLargestElement(int n, vector<int> &nums) {
            int tmp=0;
            tmp = partition(nums, 0, nums.size()-1, nums.size() - n);
            for (int i = nums.size()-1; i >= 0; i--){
                cout << nums[i] << endl;
            }
            return tmp;
        }
    private:
        int partition(vector<int> &nums, int start, int end, int k) {
            // 一定要有这个,不然就一直递归下去了
            if (start >= end) {
                return nums[k];
            }
            
            int left = start;
            int right = end;
            int pivot = nums[(start + end) / 2];
            while(left<=right){
                while (nums[left]<pivot && left <= right)left++;
                while (nums[right]>pivot && left <= right)right--;
                if(left<=right){
                    // 其实用C++自带的swap也行,但是运行速度会慢一点
                    swap(nums, left, right);
                    left++;
                    right--;
                }
            }
            
            partition(nums, start, right, k);
            partition(nums, left, end, k);
            return nums[k];
        }    
        
        void swap(vector<int> &nums, int i, int j) {
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
        }
    };
    
    

    其实核心思想就是快排,这里粗略讲一下思路:

    1. 选取基准数字

    其实选取基准数字的方法不固定,我这里是选择了数组中间的数字作为基准(省事一点)。

    1. 开始比较

    例子来自坐在马桶上看算法:快速排序,此处略有改动。例如数组是6 1 2 7 9 3 4 5 10 8
    我们从两端开始探测:

    那两个小人就是当前在操作的数字,首先左边的小人会向右走,同时将自己脚下面的数字和基准数字进行比较,因为我们排列的目的是让数字升序排列,即最终结果为1 2 3 ... 10,所以左侧小人探测的目标是比基准数字大的数字。左侧小人找到目标并停下后,右侧小人会开始向左走,探测目标是比基准数字小的数字。两个小人都是一旦发现了目标就在目标上方停下。两个小人都找到自己对应的目标之后就会进行交换。

    如此类推,直到两个小人碰在了一起:

    这时候就应该将数组分割成两部分,然后在每个部分中单独重复上述步骤。


    注意我的程序中的判断条件,我的目的是在碰面之后再让左右的“小人”继续走一步,然后直接依据两个小人的位置将数组进行分割。

    本博客文章默认使用CC BY-SA 3.0协议。
  • 相关阅读:
    洛谷 P1284 三角形牧场WD
    luogu P3817 小A的糖果
    P3374 【模板】树状数组 1
    线程与threading模块
    socketserver模块
    python 粘包问题及解决方法
    python 网络编程
    类的进阶四 反射和内置方法
    python hashlib模块 logging模块 subprocess模块
    类的进阶三
  • 原文地址:https://www.cnblogs.com/yejianying/p/quicksort_problem.html
Copyright © 2011-2022 走看看