乱序数列保序输出
在CSDN上面看到一道题目要求设计一个乱序的序列保序输出,例如,假设起始序号是1,对于{1,2,5,8,10,4,3,6,9,7}这个序列,保序输出的结果是:
1
2
3,4,5
6
7,8,9,10
上述例子中,3来到的的时候会发现4,5已经在了,因此将已经满足顺序的整个序列(3,4,5)输出
分析上面的要求,不难得到,假设当前该输出的起始值为start,而当前正好在第k位,那么是否输出,决定于当前的arr[k]的值是否等于start,而输出的内容则是,从arr[k]开始,在0~k-1之间的依次递增的值,ok,程序说到这里,已经不难写了,代码如下:
void solve(vector<int> &data) { int start = 1; int len = data.size(); int i = 0; int k; vector<int>::iterator it; vector<int>::iterator be = data.begin(); while (i < len) { if (data[i] == start) { k = data[i]; cout << setw(5) << k; it = be + i; while (1){ k++; if (find(be, it, k) == it){ break; } else{ cout << setw(5) << k; } } cout << endl; start = k; } i++; } }
这样的效率并不是最好的,所以我们可以想到用map来做记录,然后通过比对记录,来加快输出,由于map的实现机制是依赖于红黑树,所以从map中查找数据的时间不会超过logn,代码如下:
void solution(vector<int> &data) { int start = 1; int len = data.size(); int i = 0; bool flag = 0; map<int, int> mp; while (i < len) { mp[data[i]] = 1; while (mp[start] == 1) { flag = 1; cout << setw(5) << start; start++; } if (flag) { cout << endl; flag = 0; } i++; } }
如果我们能够得到这样一个前提,就是能够在处理数据的时候确定该数据的长度len,并且,该数据的内容为1~len不间断,那么还有一种更为快捷的方法:
void solutionByVec(vector<int> &data) { int start = 1; int len = data.size(); int i = 0; bool flag = 0; vector<int> mp(len, 0); while (i < len) { mp[data[i]] = 1; while (mp[start] == 1) { flag = 1; cout << setw(5) << start; start++; } if (flag) { cout << endl; flag = 0; } i++; } }
由于vector的实现机制是数组,也就是在使用下标访问vector的时候的时间复杂度可以不用考虑,那么该算法的复杂度接近线性。