欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

leet_75_sort_color(荷兰国旗问题)

程序员文章站 2022-07-07 11:19:01
...
  • 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指针。
    • 具体思路:
      leet_75_sort_color(荷兰国旗问题)
  • 方法二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类型的数组(或容器变量),不能是指针类型