leet_75_sort_color(荷兰国旗问题)

本文介绍了一种在O(1)空间复杂度和O(n)时间复杂度下,对包含0、1、2的数组进行排序的方法,即荷兰国旗问题。通过使用三个指针low、mid、high,或不使用指针的创新方法,实现了高效排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • leet_code地址:点我

  • 问题描述:

    • 一个由0,1,2乱序组成的数组,使用o(1)的空间复杂度,且时间复杂度在0(n)范围内(只遍历一遍数组),将数组进行排序。
    • 因为该排序问题属于有序的三分类问题,类似于荷兰国旗(红白蓝)撕成很多条进行排序问题,所以也称为荷兰国旗问题,该题也可拓展为该类型:一直欲排序数组元素值(相同元素值有很多)的排序问题。
  • 方法一分析:

    • 一般对时间复杂度和空间复杂度要求较高的(如排序)相关问题都要考虑使用双指针,甚至三指针。
    • 该问题确定使用三个指针(low, mid, high)来实现后,就要确定问题的“主要矛盾”,抓住主要矛盾就容易解题了。三个指针中mid指针作为主要矛盾。其次,三个指针所充当的角色要定位好,如low和mid指针分别指向的是0和1元素的下一个位置,而high指针指向的是2元素的上一个位置。
  • 方法一c++代码实现:

class Solution 
{
private:
	int* data;
	int length;
public:
	Solution(int *value, int len) :data(value),length(len){};
	void sort_color_1()
	{
		int low = 0, mid = 0, high = length - 1;
		while(mid <= high)
		{
			if (data[mid] == 0)
			{
				int temp = data[mid];
				data[mid] = data[low];
				data[low] = temp;
				low++;
				mid++;
			}
			else if (data[mid] == 1)
				mid++;
			else if(data[mid] == 2)//mid == 2
			{
				int temp = data[mid];
				data[mid] = data[high];
				data[high] = temp;
				high--;
			}
		}
	}
	void get_vales()
	{
		for (int i = 0; i < length; i++)
			cout << data[i];
		cout << endl;
	}
};

主调函数:

int main(int argc, char* argv[])
{
	int data[] = { 2, 0, 2, 1, 1, 0};
	Solution solution = Solution(data, 6);
	solution.get_vales();
	clock_t start_time, end_time;
	start_time = clock();
	solution.sort_color_1();
	end_time = clock();
	solution.get_vales();
	cout << "time:" << end_time - start_time <<"ms"<<endl;
	system("pause");
	return 0;
}
  • 方法二分析:
    • 该方法不用指针、不用交换元素即可实现,的确是绝!
    • 因为是已知数组内所有元素的排序问题,那么同样定义三个指针low, mid,high分别指向0,1,2元素的元素尾部的下一个位置,遇到0三个指针都向后移,遇到1向后移动mid和high指针,遇到2向后移动high指针。
    • 具体思路:
      在这里插入图片描述
  • 方法二C++代码:
	void sort_color_2()
	{
		int low = 0, mid = 0, high = 0;
		for (int i = 0; i < length; i++)
		{
			if (data[i] == 0)
			{
				data[high++] = 2;
				data[mid++] = 1;
				data[low++] = 0;
			}
			else if (data[i] == 1)
			{
				data[high++] = 2;
				data[mid++] = 1;
			}
			else if (data[i] == 2)
			{
				data[high++] = 2;
			}
		}
	}

注:以上的for循环可以使用c++11的新特性–区间迭代,这样更加优雅:

for(int val:data)  //data 为int类型的数组(或容器变量),不能是指针类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值