1.对一个字符串s,有两种操作,a是奇数位增加a,b是把整个字符串右移b位。本以为要技巧,没想到就是暴力美学,以后想不出技巧就先暴力做吧,尤其是这题限制长度100以内,先看下数据范围就可判断能否暴力了。
奇数位增加涉及数值运算,s[i]=(s[i]-'0'+a)%10+'0';简练的完成了,字符和数值转化,加数字,比10大下标处理,恢复字符。
在移位时,直接用substr虽然也可,但用t[i]=s[(i-b+n)%n] 通过计算移位前后的数值关系,直接操作避免了复杂的函数运算,和n取余
本题思维困局在于:
允许无限次操作——》何时是个头
两种操作的顺序可以不固定——》怎么判断何种方式组合操作
第一个:
最后把数值都用set判断是否已经出现,出现了并把vector遍历完的就停——》因为后面就是对其完全相同的操作,一定还会回来。vector存所有可能性
第二个:
顺序不固定——》每次两种结果都放到存储里,对其再进行两种操作,操作种类相当于二叉树的形式分布,就可保证所有两种操作的排列组合都遍历到
ps:多用define减少操作数
#define pb push_back class Solution { public: string findLexSmallestString(string s, int a, int b) { //vector set 2 store first insert int n = s.size(); vector<string> q; q.pb(s); set<string> st; st.insert(s); //operation part range q.size() for(int op = 0; op < (int)q.size(); op++) { string s = q[op]; //after initialize two operation between them count whether exist for(int i = 1; i < n; i += 2) { s[i] = (s[i] - '0' + a) % 10 + '0'; } cout<<"s1:"<<s<<endl; if(st.count(s) == 0) { q.pb(s); st.insert(s); } s = q[op]; string t(s); for(int i = 0; i < n; i++) { t[i] = s[(i - b + n) % n]; } cout<<"s2:"<<s<<endl; if(st.count(t) == 0) { q.pb(t); st.insert(t); } } return *st.begin(); } };
愿为天下目,萃聚六路华