持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
描述
明明生成了N个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。
数据范围:1≤n≤1000 ,输入的数字大小满足 1≤val≤500
输入描述:
第一行先输入随机整数的个数 N 。 接下来的 N 行每行输入一个整数,代表明明生成的随机数。 具体格式可以参考下面的"示例"。
输出描述:
输出多行,表示输入数据处理后的结果
示例1
输入:
3
2
2
1
输出:
1
2
说明:
输入解释:
第一个数字是3,也即这个小样例的N=3,说明用计算机生成了3个1到500之间的随机整数,接下来每行一个随机数字,共3行,也即这3个随机数字为:
2
2
1
所以样例的输出为:
1
2
题目的主要信息:
- 一共多次调查,每次调查输入的第一个数为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;
}
复杂度分析:
- 时间复杂度:,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;
}
复杂度分析:
- 时间复杂度:,n为输入的总数字个数,set依赖于红黑树,每次插入都是,最坏情况下只有一个数组,需要
- 空间复杂度:,n为输入的总数字个数,最坏情况下set大小为n−1