【优选算法】分治

一:颜色分类

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

二:排序数组

cpp 复制代码
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        srand(time(nullptr));
        qsort(nums, 0, nums.size()-1);
        return nums;
    }
    void qsort(vector<int>& nums, int left, int right)
    {
        // 快速排序------三区间[<key][=key][>key]
        if(left >= right) return;
        // 选择随机数 Key
        int key = GetRand(nums, left, right);
        // 三指针排法
        int i = left, l = left-1, r = right+1;
        while(i < r)
        {
            if(nums[i] < key) swap(nums[++l], nums[i++]);
            else if(nums[i] > key) swap(nums[--r], nums[i]);
            else i++;
        } 
        // // 开始往下快排
        // [left, l][l+1, r-1][r, right]
        qsort(nums, left, l);
        qsort(nums, r, right);
    }
    int GetRand(vector<int>& nums, int left, int right)
    {
        int r = rand();
        return nums[r%(right-left+1)+left];
    }
};

三:数组中的第K个最大元素

cpp 复制代码
class Solution {
    int GetRand(vector<int>& nums, int left, int right)
    {
        int r = rand();
        return nums[r%(right-left+1) + left];        
    }

    void quickSort(vector<int>& nums, int left, int right)
    {
        if(left > right)
            return;
        // 随机数选key
        int key = GetRand(nums, left, right);
        // 三指针操作法
        // [<key][=key][>key]
        int l = left-1, i = left, r = right+1;
        while(i < r)
        {
            if(nums[i] < key)
                swap(nums[++l], nums[i++]);
            else if(nums[i] > key)
                swap(nums[--r], nums[i]);
            else
                i++;
        }
        // [left, l][l+1, r-1][r, right]
        quickSort(nums, left, l);
        quickSort(nums, r, right);
    }
public:
    int findKthLargest(vector<int>& nums, int k) {
        srand(time(0));
        quickSort(nums, 0, nums.size()-1);
        return nums[nums.size() - k];
    }
};

四:库存管理III

cpp 复制代码
class Solution {
private:
    int GetRand(vector<int>& nums, int left, int right)
    {
        int r = rand();
        return nums[r%(right-left+1) + left];
    }
    void quickSort(vector<int>& nums, int left, int right)
    {
        if(left > right)
            return;
        // 获取随机数
        int key = GetRand(nums, left, right);
        // 三指针法
        int i = left, l = left-1, r = right+1;
        while(i < r)
        {
            if(nums[i] > key)
                swap(nums[--r], nums[i]);
            else if(nums[i] < key)
                swap(nums[++l], nums[i++]);
            else
                i++;
        }
        // []][][]
        quickSort(nums, left, l);
        quickSort(nums, r, right);
    }
public:
    vector<int> inventoryManagement(vector<int>& stock, int cnt) {
        srand(time(0));
        quickSort(stock, 0, stock.size()-1);
        vector<int> ret(stock.begin(), stock.begin() + cnt);
        return ret;
    }
};

五:交易逆序对的总数

cpp 复制代码
class Solution {
    int tmp[50010];
private:
    int mergeSort(vector<int>& nums, int left, int right)
    {
        if(left >= right)
            return 0;
        // 找中间点
        int mid = (left+right)>>1;
        int ret = 0;    // 要返回的结果
        // [left, mid][mid+1, right]

        // 2. 左边的个数 + 排序 +  右边的个数 + 排序
        ret += mergeSort(nums, left, mid);
        ret += mergeSort(nums, mid + 1, right);

        // 3. 一左一右的个数
        int cur1 = left, cur2 = mid + 1, i = 0;
        while(cur1 <= mid && cur2 <= right)
        {
            if(nums[cur1] <= nums[cur2])
                tmp[i++] = nums[cur1++];
            else
            {
                ret += (mid - cur1 + 1);
                tmp[i++] = nums[cur2++];
            }
        }

        // 4. 处理一下排序
        while(cur1 <= mid) tmp[i++] = nums[cur1++];
        while(cur2 <= right) tmp[i++] = nums[cur2++];
        for(int i = left; i <= right; i++)
            nums[i] = tmp[i-left];
        return ret;
    }
public:
    int reversePairs(vector<int>& record) {
        return mergeSort(record, 0, record.size()-1);
    }
};

六:计算右侧小于当前元素的个数

cpp 复制代码
class Solution {
    vector<int> ret;
    vector<int> index;  // 记录 nums 下当前元素的原始下标
    int tmpNums[50010];
    int tmpIndex[50010];    
private:
    void mergeSort(vector<int>& nums, int left, int right)
    {
        if(left >= right)
            return ;
        int mid = (left + right) >> 1;
        // [left, mid][mid+1, right]
        
        // 1. 先处理 左右两部分
        mergeSort(nums, left, mid);
        mergeSort(nums, mid + 1, right);

        // 2. 处理一左一右的情况
        int cur1 = left, cur2 = mid + 1, i = 0;
        while(cur1 <= mid && cur2 <= right)
        {
            if(nums[cur1] <= nums[cur2])
            {
                tmpNums[i] = nums[cur2];
                tmpIndex[i++] = index[cur2++];
            }
            else
            {
                ret[index[cur1]] = right-cur2 + 1;
                tmpNums[i] = nums[cur1];
                tmpIndex[i++] = index[cur1++];
            }
        }
        
        // 3. 处理剩下的排序
        while(cur1 <= mid)
        {
            tmpNums[i] = nums[cur1];
            tmpIndex[i++] = index[cur1++];
        }
        while(cur2 <= right)
        {
            tmpNums[i] = nums[cur2++];
            tmpIndex[i++] = index[cur2++];
        }
        for(int i = left; i <= right; i++)
        {
            nums[i] = tmpNums[i-left];
            index[i] = tmpIndex[i-left];
        }
    }
public:
    vector<int> countSmaller(vector<int>& nums) {
        int n = nums.size();
        ret.resize(n);

        // 初始化 index 按钮
        for(int i = 0; i < n; i++)
        {
            index[i] = i;
        }
        mergeSort(nums, 0, n-1);
        return ret;
    }
};

七:翻转对

cpp 复制代码
class Solution {
    int tmp[50010];
    int mergeSort(vector<int>& nums, int left, int right)
    {
        if(left >= right)
            return 0;
        
        //1
        int mid = (left + right)>>1;
        // [left, mid][mid+1, right]
        int ret = 0;
        ret += mergeSort(nums, left, mid);
        ret += mergeSort(nums, mid + 1, right);

        // 2. 
        int cur1 = left, cur2 = mid +1, i = left;
        while(cur1 <= mid)  // 降序的情况
        {
            while(cur2 <= right && nums[cur2] >= nums[cur1]/2.0)
                cur2++;
            if(cur2 > right)
                break;
            ret += right - cur2 + 1;
            cur1++;
        }

        // 4. 
        cur1 = left, cur2 = mid+1;
        while(cur1 <= mid && cur2 <= right)
            tmp[i++] = nums[cur1]<nums[cur2]? nums[cur2++] : nums[cur1++];
        while(cur1 <= mid)
            tmp[i++] = nums[cur1++];
        while(cur2 <= right)
            tmp[i++] = nums[cur2++];
        
        // 5
        for(int i = left; i <= right; i++)
            nums[i] = tmp[i];
        
        // 6
        return ret;
    }
public:
    int reversePairs(vector<int>& nums) {
        return mergeSort(nums, 0, nums.size()-1);
    }
};
相关推荐
不爱吃炸鸡柳1 小时前
单链表专题(完整代码版)
数据结构·算法·链表
CylMK1 小时前
题解:AT_abc382_d [ABC382D] Keep Distance
算法
Dfreedom.1 小时前
计算机视觉全景图
人工智能·算法·计算机视觉·图像算法
Morwit2 小时前
【力扣hot100】 1. 两数之和
数据结构·c++·算法·leetcode·职场和发展
py有趣2 小时前
力扣热门100题之岛屿的数量(DFS/BFS经典题)
leetcode·深度优先·宽度优先
无小道2 小时前
算法——暴力+优化
算法·优化·暴力
Free Tester2 小时前
如何判断 LeakCanary 报告的严重程度
java·jvm·算法
zyq99101_13 小时前
DFS算法实战:经典例题代码解析
python·算法·蓝桥杯·深度优先
智者知已应修善业3 小时前
【51单片机单按键切换广告屏】2023-5-17
c++·经验分享·笔记·算法·51单片机
广州灵眸科技有限公司3 小时前
为RK3588注入澎湃算力:RK1820 AI加速卡完整适配与评测指南
linux·网络·人工智能·物联网·算法