【刷题11】分治—快速排序

目录

一、排序数组

题目:

思路:快速排序(三路划分)

  • 交换、三数取中(设置随机数,让mid更随机些)
  • 三路划分:因为数组里面可能有多个相同的数,如果全是一样的数,就影响了快排的效率

代码:

cpp 复制代码
class Solution {
public:
    int getMid(vector<int>& nums, int left, int right)
    {
        int mid = left + (rand() % (right-left));
        return mid;
    }
    // 快速排序
    void QuickSort(vector<int> &nums, int left, int right)
    {
        if(left >= right) return;
        int mid = getMid(nums, left, right);
        swap(nums[mid], nums[left]);
        int k = nums[left];
        int begin = left, end = right, cur = left;
        while(cur <= right)
        {
            if(nums[cur] < k) 
            {
                swap(nums[cur], nums[left]);
                ++cur;
                ++left;
            }
            else if(nums[cur] > k)
            {
                swap(nums[cur], nums[right]);
                --right;
            }
            else ++cur;
        } 
        QuickSort(nums, begin, left-1);
        QuickSort(nums, right+1, end);
    }
    vector<int> sortArray(vector<int>& nums) {
        srand(time(0));
        int n = nums.size();
        QuickSort(nums, 0, n-1);
        return nums;
    }
};

二、颜色分类

题目:

思路:与上题一样

代码:

cpp 复制代码
class Solution {
public:
    int getMid(vector<int> &nums, int left ,int right)
    {
        int mid = left + (rand() % (right-left));
        return mid;
    }
    void QuickSort(vector<int> &nums, int left, int right)
    {
        if(left >= right) return;
        int n=nums.size();
        int mid = getMid(nums, left, right);
        swap(nums[mid], nums[left]);
        int k = nums[left];  
        int begin = left, end = right, cur = left;
        while(cur <= right)
        {
            if(nums[cur] < k)
            {
                swap(nums[cur], nums[left]);
                cur++;
                left++;
            }
            else if(nums[cur] > k)
            {
                swap(nums[cur], nums[right]);
                right--;
            }
            else cur++;
        }        
        QuickSort(nums, begin, left-1);
        QuickSort(nums, right+1, end);
    }
    void sortColors(vector<int>& nums) {
        srand(time(0));
        QuickSort(nums, 0, nums.size()-1);
    }
};

另一种写法:

cpp 复制代码
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n = nums.size();
        int left = -1, right= n, cur= 0;
        while(cur < right)
        {
            if(nums[cur] == 0) swap(nums[cur++], nums[++left]);
            else if(nums[cur] == 2) swap(nums[cur], nums[--right]);
            else cur++;
        }
    }
};

三、数组中第k个最大元素

题目:

思路:

  • 分三块与前面两题相同
  • a,b,c是每块区间的元素个数
  • c大于等于k:第k大在右边的区间,去右边的区间找
  • b+c大于等于k:排除了在右边,那么一定在中间的区间,该区间的元素都是一样的,所以直接返回key
  • 前面两个不成立,去左边的区间找,因为第k大是相对于整个数组的,而中间的和右边的区间已经确定了(第k大不会出现在中间和右边),所以k要减去中间和右边区间的个数

代码:

cpp 复制代码
class Solution {
public:
    int getMid(vector<int> &nums, int left, int right)
    {
        int mid = left + (rand() % (right-left));
        return nums[mid];
    }
    int qsort(vector<int>& nums, int l, int r, int k)
    {
        if(l >= r) return nums[l];///
        int key = getMid(nums, l, r);
        int left = l, right = r, cur = l;
        while(cur <= right)
        {
            if(nums[cur] < key)
            {
                swap(nums[cur], nums[left]);
                left++;
                cur++;
            }
            else if(nums[cur] > key)
            {
                swap(nums[cur], nums[right]);
                right--;
            }
            else cur++;
        }
        int b = right-left+1;
        int c = r - right;
        if(c >= k) return qsort(nums, right+1, r, k);
        else if(b+c >= k) return key;
        else return qsort(nums, l, left-1, k-b-c);
    }
    int findKthLargest(vector<int>& nums, int k) {
        srand(time(0));
        int ret = qsort(nums, 0, nums.size()-1, k);
        return ret;
    }
};

解法二:堆

思路:建立一个小堆,先放k个元素,然后遍历剩余的元素,只要比堆顶大就进堆,往下沉。最后的堆顶就是第k大的元素

代码:

cpp 复制代码
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int n = nums.size();
        priority_queue<int, vector<int>, greater<int>> pq(nums.begin(), nums.begin()+k);
        for(int i=k; i<n;i++)//从k开始,不能重复比较
        {
            if(nums[i] > pq.top())
            {
                pq.pop();
                pq.push(nums[i]);
            }
        }
        return pq.top();
    }
};

四、库存管理lll

题目:

思路:快速排序---与前面相同,最后返回前cnt个元素

代码:

cpp 复制代码
class Solution {
public:
    int getMid(vector<int>& nums, int left, int right)
    {
        int mid = left+(rand()%(right-left));
        return nums[mid];
    }
    void qsort(vector<int>& nums, int l, int r)
    {
        if(l >= r) return;
        int key = getMid(nums, l, r);
        int left = l, right = r, cur = l;
        while(cur <= right)
        {
            if(nums[cur] < key) 
            {
                swap(nums[cur++], nums[left++]);
            }
            else if(nums[cur] > key) 
            {
                swap(nums[cur], nums[right--]);
            }
            else cur++;
        }
        qsort(nums, l, left-1);
        qsort(nums, right+1, r);
    }
    vector<int> inventoryManagement(vector<int>& stock, int cnt) {
        srand(time(0));
        qsort(stock, 0, stock.size()-1);
        vector<int> ret;
        for(int i=0;i<cnt;i++) ret.push_back(stock[i]);
        return ret;
    }
};
相关推荐
刘海东刘海东11 分钟前
结构型智能科技的关键可行性——信息型智能向结构型智能的转变(修改提纲)
人工智能·算法·机器学习
胖大和尚37 分钟前
clang 编译器怎么查看在编译过程中做了哪些优化
c++·clang
pumpkin8451438 分钟前
Rust 调用 C 函数的 FFI
c语言·算法·rust
挺菜的1 小时前
【算法刷题记录(简单题)003】统计大写字母个数(java代码实现)
java·数据结构·算法
mit6.8241 小时前
7.6 优先队列| dijkstra | hash | rust
算法
2401_858286111 小时前
125.【C语言】数据结构之归并排序递归解法
c语言·开发语言·数据结构·算法·排序算法·归并排序
钱彬 (Qian Bin)2 小时前
一文掌握Qt Quick数字图像处理项目开发(基于Qt 6.9 C++和QML,代码开源)
c++·开源·qml·qt quick·qt6.9·数字图像处理项目·美观界面
guygg882 小时前
基于matlab的FIR滤波器
开发语言·算法·matlab
双叶8362 小时前
(C++)学生管理系统(正式版)(map数组的应用)(string应用)(引用)(文件储存的应用)(C++教学)(C++项目)
c语言·开发语言·数据结构·c++
源代码•宸2 小时前
C++高频知识点(二)
开发语言·c++·经验分享