欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 手游 > leetcode 75.颜色分类

leetcode 75.颜色分类

2024/10/24 22:20:56 来源:https://blog.csdn.net/m0_49013185/article/details/140600736  浏览:    关键词:leetcode 75.颜色分类

文章目录

    • 方法一
      • 代码实现
      • 解释
      • 关键点
      • 时间复杂度和空间复杂度
    • 方法二
      • 代码实现
      • 解释
      • 时间复杂度和空间复杂度
    • 方法三(单指针)
    • 方法四(双指针)

LeetCode第75题“颜色分类”要求对包含红色、白色和蓝色的数组进行排序,红色、白色和蓝色分别用0、1和2表示。这个问题可以通过荷兰国旗问题的解决方案来实现,该算法的时间复杂度为O(N),空间复杂度为O(1)。

方法一

代码实现

我们可以使用双指针(two-pointer)的方法来解决这个问题:

#include <vector>
#include <iostream>using namespace std;class Solution {
public:void sortColors(vector<int>& nums) {int left = 0, right = nums.size() - 1, current = 0;while (current <= right) {if (nums[current] == 0) {swap(nums[current], nums[left]);left++;current++;} else if (nums[current] == 1) {current++;} else if (nums[current] == 2) {swap(nums[current], nums[right]);right--;}}}
};int main() {Solution solution;vector<int> nums = {2, 0, 2, 1, 1, 0};solution.sortColors(nums);for (int num : nums) {cout << num << " ";}cout << endl;return 0;
}

解释

  1. 初始化三个指针

    • left 指向最左边的0的下一个位置。
    • right 指向最右边的2的前一个位置。
    • current 用于遍历数组。
  2. 遍历数组并进行交换

    • 如果 nums[current] 为0,则与 nums[left] 交换,同时将 leftcurrent 指针都向右移动一位。
    • 如果 nums[current] 为1,则仅将 current 向右移动一位。
    • 如果 nums[current] 为2,则与 nums[right] 交换,同时将 right 指针向左移动一位,但 current 不移动,因为交换过来的值还需要处理。

关键点

  • 通过交换 nums[current]nums[left],我们确保所有0都在数组的左边。
  • 通过交换 nums[current]nums[right],我们确保所有2都在数组的右边。
  • 所有1都将自动排在中间。

时间复杂度和空间复杂度

  • 时间复杂度:O(N),因为我们只需要遍历数组一次。
  • 空间复杂度:O(1),因为我们只使用了常数级别的额外空间。

这种方法高效且简单,适用于大多数情况下需要对包含少数类别的数组进行分类排序的场景。

方法二

有一个简单的思路,这种方法虽然简单直观,但它不是题目要求的单次遍历解决方案。不过,对于理解问题和学习排序的基本概念非常有帮助。可以分为两个步骤:

  1. 第一次遍历:统计数组中0、1、2的出现次数。
  2. 第二次遍历:根据统计结果重新填充数组。

代码实现

#include <vector>
#include <iostream>using namespace std;class Solution {
public:void sortColors(vector<int>& nums) {// Step 1: Count the number of 0s, 1s, and 2sint count0 = 0, count1 = 0, count2 = 0;for (int num : nums) {if (num == 0) {count0++;} else if (num == 1) {count1++;} else if (num == 2) {count2++;}}// Step 2: Overwrite the array with the sorted orderint index = 0;for (int i = 0; i < count0; i++) {nums[index++] = 0;}for (int i = 0; i < count1; i++) {nums[index++] = 1;}for (int i = 0; i < count2; i++) {nums[index++] = 2;}}
};int main() {Solution solution;vector<int> nums = {2, 0, 2, 1, 1, 0};solution.sortColors(nums);for (int num : nums) {cout << num << " ";}cout << endl;return 0;
}

解释

  1. 统计0、1、2的出现次数

    int count0 = 0, count1 = 0, count2 = 0;
    for (int num : nums) {if (num == 0) {count0++;} else if (num == 1) {count1++;} else if (num == 2) {count2++;}
    }
    
    • 遍历数组,使用三个变量 count0count1count2 分别统计0、1、2的出现次数。
  2. 重新填充数组

    int index = 0;
    for (int i = 0; i < count0; i++) {nums[index++] = 0;
    }
    for (int i = 0; i < count1; i++) {nums[index++] = 1;
    }
    for (int i = 0; i < count2; i++) {nums[index++] = 2;
    }
    
    • 使用 index 变量从头开始填充数组。
    • 先填充 count0 个0,再填充 count1 个1,最后填充 count2 个2。

时间复杂度和空间复杂度

  • 时间复杂度:O(N),因为我们遍历了数组两次。
  • 空间复杂度:O(1),因为我们只使用了常数级别的额外空间。

方法三(单指针)

#include <vector>
using std::vector;
/** @lc app=leetcode.cn id=75 lang=cpp** [75] 颜色分类*/// @lc code=start
class Solution {
public:void sortColors(vector<int>& nums) {int index = 0;for(int i = 0;i < nums.size() ;i++){if(nums[i] == 0){swap(nums,i,index);index ++;}}for(int i = 0; i < nums.size();i++){if(nums[i] == 1){swap(nums,i,index);index ++;}}}void swap(vector<int>& nums,int index1,int index2){int  temp = nums[index1];nums[index1] = nums[index2];nums[index2] = temp;}
};
// @lc code=end

方法四(双指针)

#include <vector>
using std::vector;
/** @lc app=leetcode.cn id=75 lang=cpp** [75] 颜色分类*/// @lc code=start
class Solution {
public:void sortColors(vector<int>& nums) {int left = 0;int right = nums.size() - 1;for(int i = 0;i <= right;i++){if(nums[i] == 0){swap(nums,i,left);left ++;}else if(nums[i] == 2){swap(nums,i,right);right --;if(nums[i] != 1){i --;}}}}void swap(vector<int>& nums,int index1,int index2){int  temp = nums[index1];nums[index1] = nums[index2];nums[index2] = temp;}
};
// @lc code=end

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com