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();
    }
};

 

posted on 2020-10-19 09:17  黑暗尽头的超音速炬火  阅读(141)  评论(0编辑  收藏  举报