leetcode75_颜色分类_三分数组

文章介绍了如何使用三分数组策略解决LeetCode75题,即对包含红、白、蓝三种颜色的数组进行原地排序,使其按颜色顺序排列。此外,还展示了如何将此策略应用于快速排序,如在寻找数组中第K个最大元素的问题上。
摘要由CSDN通过智能技术生成

1. 题目

leetcode75_颜色分类
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

例:

输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]

输入:nums = [2,0,1]
输出:[0,1,2]

2. 解法:三分数组

定义循环不变量p0p2i,即在循环遍历数组的过程中,这些变量的含义是不变的。
下标在[0, p0)范围内的数组元素全是0
下标在[p0, i)范围内的数组元素全是1
下标在(p2, nums.size() - 1]范围内的数组元素全是2

class Solution {
public:
    void sortColors(vector<int>& nums)
    {
        int p0 = 0;
        int p2 = nums.size() - 1;
        for (int i = p0; i <= p2;) {
            // [0, p0)是0
            // [p0, i)是1
            // (p2, nums.size() - 1]是2
            if (nums[i] == 0) {
                swap(nums[i], nums[p0]);
                ++i;
                ++p0;
            } else if (nums[i] == 2) {
                swap(nums[i], nums[p2]);
                --p2;
            } else {
                ++i;
            }
        }
    }
};

3. 拓展

相同的三分数组的思路也可以用在快速排序上。即把数组分成小于x的部分、等于x的部分、大于x的部分。
leetcode215_数组中的第K个最大元素,用快速排序的方式实现如下:

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        return FindNum(nums, 0, nums.size() - 1, nums.size() - k);
    }

private:
    int FindNum(vector<int>& nums, int left, int right, int k)
    {
        int pivot = nums[(left + right) / 2];
        int less = left;
        int equal = left;
        int bigger = right;
        while (equal <= bigger) {
            if (nums[equal] < pivot) {
                swap(nums[equal], nums[less]);
                ++equal;
                ++less;
            } else if (nums[equal] > pivot) {
                swap(nums[equal], nums[bigger]);
                --bigger;
            } else {
                ++equal;
            }
        }

        --equal;
        if (equal < k) {
            return FindNum(nums, equal + 1, right, k);
        } else if (equal > k) {
            return FindNum(nums, left, equal - 1, k);
        } else {
            return nums[equal];
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值