【刷题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;
    }
};
相关推荐
不去幼儿园17 分钟前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Mr_Xuhhh19 分钟前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
Ajiang28247353041 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
盼海1 小时前
排序算法(五)--归并排序
数据结构·算法·排序算法
网易独家音乐人Mike Zhou5 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
‘’林花谢了春红‘’6 小时前
C++ list (链表)容器
c++·链表·list
搬砖的小码农_Sky7 小时前
C语言:数组
c语言·数据结构
机器视觉知识推荐、就业指导8 小时前
C++设计模式:建造者模式(Builder) 房屋建造案例
c++
Swift社区8 小时前
LeetCode - #139 单词拆分
算法·leetcode·职场和发展