目录
1.排序子序列
2.倒置字符串
1.排序子序列
排序子序列_牛客笔试题_牛客网 (nowcoder.com)
首先题干中提到非递增序列和非递减序列,那么我们就要先弄明白什么是上述2种序列:
非递增序列:a[i] >= a[i+1]
如:3 2 1 或者 3 3 2 2 1
非递减序列:a[i] <= a[i+1]
如:1 2 3 或者 1 2 2 3
分析:那么如何划分序列?
可以从我上面例举的非递增或者非递减序列中发现,a[i]和a[i+1]重复完全不影响这个序列是什么序列,所以首先我们可以考虑在出现这种情况的时候直接遍历过去,再看划分子序列的关键点,是在当前这种序列中出现不符合特点的情况(出现另一种序列的特征),那么当前这种序列结束,一定可以划分出子序列。
比如题干:1 2 3 2 2 1
1 2 3是非递减序列,比较过程是:1和2比较,判断出当前是非递减序列,在这个条件下循环依次往后一直比较判断,当比较下图3和2时,此时已经不符合非递减序列的特点,此时可以划分出1个子序列。
小细节:我们使用a[i]和a[i+1]的方式进行遍历序列比较,遍历条件i<n(n为序列长度),当i=n-1时,此时i+1=n,如果只开n个空间的话,此时下标非法,所以我们要多开1个空间,即n+1。数据我们就放0,因为题干数据范围>=1,0比最小的数还小,并不影响划分子序列。
现在来看代码:(有注释很好懂)
#include <iostream>
#include<vector>
using namespace std;int main() {int n=0;cin>>n;vector<int>v;v.resize(n+1);//多开一个防止越界v[n]=0;//数据范围是1<=n<=10^5,0比最小的还小,不影响比较for(int i=0;i<n;i++){cin>>v[i];}//初始化完成int i=0,count=0;while(i<n){ //非递减序列if(v[i]<v[i+1]){//i<n是为了防止i走到n导致越界while(i<n&&v[i]<=v[i+1]){i++;}//退出while那么一定走到了边界count++;i++;}else if(v[i]==v[i+1]){i++;//相同不影响直接跳过}//非递增序列else{//i<n是为了防止i走到n导致越界while(i<n&&v[i]>=v[i+1]){i++;}//退出while那么一定走到了边界count++;i++;}}cout<<count<<endl;return 0;
}
2.倒置字符串
倒置字符串__牛客网 (nowcoder.com)
这个题相当经典,相信大家应该都做过。
倒置字符串,只需要整体先倒置一遍,再把每个单词倒置一遍就可以达到输出要求。
我们来说说细节,reverse没得说,在algorithm头文件里。读取带空格的字符串使用getline(cin,str_name),str_name是你定义的字符串名称。
我们使用迭代器来寻找要倒置的位置,string的迭代器就是指针(可以看我string类详解中访问及遍历操作中的迭代器模拟实现),迭代器在使用的过程中通常是用!=str_name.end()来实现遍历条件的。
图解:
来看代码:(有注释很好懂)
#include <iostream>
#include<string>
#include<algorithm>
using namespace std;int main() {string s;getline(cin,s);reverse(s.begin(),s.end());//直接使用auto让编译器自动识别类型auto start=s.begin();while(start!=s.end()){auto end=start;while(end!=s.end()&&*end!=' '){end++;}//出来就一定会翻转reverse(start,end);//翻转后更新迭代器//未走到末尾,即走到空格if(end!=s.end()){start=end+1; }//走到末尾else{start=end;}}cout<<s<<endl;return 0;
}