【编程题】数组的 partition 调整

题目:
给定一个有序数组 arr,调整 arr 使得这个数组的左半部分没有重复元素且升序,而不用保证右部分是否有序。
例如:arr = [1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9]
调整之后 arr=[1, 2, 3, 4, 5, 6, 7, 8, 9, …]
要求:时间复杂度为 O(n),空间复杂度为 O (1)
输入描述:

第一行一个整数 N,表示数组长度,接下来一行 N 个整数,表示数组内元素

输出描述:

输出 N 个整数为答案数组

解析:
要求给的空间很吝啬,显然,我们不可能重新开一份空间进行存储,这时候我们就需要用swap()函数,为此我们需要两个指针,一个用于指向现在元素a,一个用于指向交换的元素b。

由于给的数组已经有序,所以,两个指针所指的元素若是相同,则两个指针间的所有元素都是相同的;若是不同,则证明有序,需更新两个指针的位置,使a到达b的位置(作为新的比较源),b
向后移动。

代码:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    
    
	int n;
	cin >> n;
	vector<int> v;
	for(int i=0;i<n;i++)
	{
    
    
		int x;
		cin >> x;
		v.push_back(x);
	}
	//左指针与右指针
	int a = 0, b = 1;
	//长度小于2可直接输出
	if(n<=2)
	{
    
    
		cout << v[a] << " " << v[b];
	}
	else
	{
    
    
		while (b!=n)
		{
    
    
			//如果两个数不同,则需要进行交换
		    //记得对左加一,因为左指针现在指的还是相同的数,也是第一个出现的数
			//而如果是连续不同,其交换的是自己的位置
			if(v[a]!=v[b])
			{
    
    
				swap(v[++a], v[b]);
			}
			//无论是否相同,都需要对比下一个数
			b++;
		}
	}
	for(int i=0;i<n;i++)
	{
    
    
		cout << v[i] << " ";
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43530773/article/details/115060117