問題:
順序付けられた配列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を指すポインターと現在の要素aを指すポインターの2つのポインターが必要です。交換された要素を指すために使用されますb。
与えられた配列はすでに順序付けられているため、2つのポインターが指す要素が同じである場合、2つのポインター間のすべての要素は同じです。それらが異なる場合、順序が証明され、2つのポインターの位置が証明されます。 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;
}