【力扣刷题实战】颜色分类

大家好,我是小卡皮巴拉

文章目录

目录

力扣题目:颜色分类

题目描述

解题思路

问题理解

算法选择

具体思路

解题要点

完整代码(C++)

兄弟们共勉 !!! 


每篇前言

博客主页:小卡皮巴拉

咱的口号:小比特,大梦想

作者请求:由于博主水平有限,难免会有错误和不准之处,我也非常渴望知道这些错误,恳请大佬们批评斧正。

力扣题目:颜色分类

原题链接:75. 颜色分类 - 力扣(LeetCode)

题目描述

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

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

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

    示例 1:

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

    示例 2:

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

    解题思路

    问题理解

    本题要求对一个包含 0、1、2 三种元素的数组进行原地排序,使得相同颜色(即相同数字)的元素相邻,并且按照 0、1、2 的顺序排列,同时不能使用库内置的 sort 函数。

    算法选择

    采用三指针法使用三个指针 leftright 和 i 来对数组进行划分和排序,通过一次遍历数组,将 0 交换到数组的左边,2 交换到数组的右边,1 自然就会在中间,从而实现排序。

    具体思路

    1. 初始化指针

      • 初始化 left 指针为 -1,用于标记 0 区域的右边界。

      • 初始化 right 指针为数组的大小,用于标记 2 区域的左边界。

      • 初始化 i 指针为 0,用于遍历数组。

    2. 遍历数组

      • 当 i 小于 right 时,执行以下操作:

        • 当前元素为 0:如果 nums[i] 等于 0,将 left 指针右移一位,然后交换 nums[left] 和 nums[i],再将 i 指针右移一位。这样可以将 0 元素交换到 0 区域。

        • 当前元素为 2:如果 nums[i] 等于 2,将 right 指针左移一位,然后交换 nums[right] 和 nums[i]。注意此时 i 指针不移动,因为交换过来的元素还未处理。

        • 当前元素为 1:如果 nums[i] 等于 1,直接将 i 指针右移一位,因为 1 元素不需要交换,会自然地留在中间。

    3. 完成排序

      • 当 i 等于 right 时,遍历结束,数组已经按照 0、1、2 的顺序排列好。

    解题要点

    1. 指针的含义和移动:明确 leftright 和 i 三个指针的含义,根据当前元素的值正确移动指针,确保 0 元素在左边,2 元素在右边,1 元素在中间。

    2. 交换元素:使用 swap 函数交换元素的位置,注意交换后指针的移动情况。

    3. 遍历条件:遍历数组时,i 指针的范围是小于 right,因为 right 之后的元素已经是排好序的 2 元素。

    完整代码(C++)

    class Solution {
    public:
        void sortColors(vector& nums) 
        {
            // left 指针用于标记 0 区域的右边界,初始化为 -1,表示还没有 0 元素
            int left = -1;
            // right 指针用于标记 2 区域的左边界,初始化为数组大小,表示还没有 2 元素
            int right = nums.size();
            // i 指针用于遍历数组
            for(int i = 0; i < right;)
            {
                // 如果当前元素是 0
                if(nums[i] == 0)
                {
                    // 将 0 元素交换到 0 区域,left 指针右移一位
                    swap(nums[++left], nums[i]);
                    // 交换后 i 指针也右移一位
                    i++;
                }
                // 如果当前元素是 2
                else if(nums[i] == 2)
                {
                    // 将 2 元素交换到 2 区域,right 指针左移一位
                    swap(nums[--right], nums[i]);
                    // 注意这里 i 不移动,因为交换过来的元素还未处理
                }
                // 如果当前元素是 1
                else
                {
                    // 1 元素不需要交换,直接将 i 指针右移一位
                    i++;
                }
            }
        }
    };

    兄弟们共勉 !!! 

    码字不易,求个三连

    抱拳了兄弟们!

    你可能感兴趣的:(leetcode,算法,c++,开发语言,双指针)