题目:
给定一个有序数组 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;
}