题目的主要信息:
- 一共多次调查,每次调查输入的第一个数为N,后续N个数随机(1-1000)的数字
- 需要对每次调查数字排序并去重后输出,每个数字一行
方法一:暴力排序去重
具体做法:
我们每次循环优先读取下面的数组长度,即优先读取N,然后用循环连续N个数字进入数字,这就是这次调查的全部数字了,然后我们使用sort函数快排对这些数字排序,排好序后我们就可以输出了,需要注意除了第一个元素外我们都要检查是否和前一个元素相等,相等我们就不输出,这样来去重。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int n;
while(cin >> n){ //首先输入每次调查的人数n
vector<int> v(n);
for(int i = 0 ; i < n; i++) //连续输入n个整数
cin >> v[i];
sort(v.begin(), v.end()); //排序
for(int i = 0; i < n; i++){ //去重输出
if(i != 0 && v[i] == v[i - 1])
continue;
else
cout << v[i] << endl;
}
}
return 0;
}
复杂度分析:
- 时间复杂度:O(nlog2n),n为输入的总数字个数,输入输出都是一次遍历,而排序是分段排序,最坏情况下才是O(nlog2n)
- 空间复杂度:O(n),n为输入的总数字个数,中途记录数据的数组最坏情况下长度为n−1
方法二:有序集合
具体做法:
读取数据的方式和方法一一致,但是我们这里不采用数组来记录数字,而是采用set。set作为集合它可以对添加的数据自动去重,而且依赖于红黑树的它内部是有序,我们也省去了排序的操作,最后直接遍历set,输出即可。需要注意,每次要清空set中的内容,避免上次调查的数据用到了这次。
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
int main(){
int n;
set<int> s;
while(cin >> n){ //首先输入每次调查的人数n
s.clear(); //每次调查清空集合
for(int i = 0 ; i < n; i++){
int temp;
cin >> temp; //连续输入n个整数
s.insert(temp); //插入集合中,自动排序去重
}
for(auto iter = s.begin(); iter != s.end(); iter++) //遍历集合直接输出即可
cout << *iter << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:O(nlog2n),n为输入的总数字个数,set依赖于红黑树,每次插入都是O(log2n),最坏情况下只有一个数组,需要O(nlog2n)
- 空间复杂度:O(n),n为输入的总数字个数,最坏情况下set大小为n−1