【LeetCode 1625. 执行操作后字典序最小的字符串 】- JavaScript(dfs/bfs+暴力枚举)

235 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


【LeetCode 1625. 执行操作后字典序最小的字符串 】- JavaScript(dfs/bfs+暴力枚举)

题意描述

给你一个字符串 s 以及两个整数 a 和 b 。其中,字符串 s 的长度为偶数,且仅由数字 0 到 9 组成。

你可以在 s 上按任意顺序多次执行下面两个操作之一:

累加:将 a 加到 s 中所有下标为奇数的元素上(下标从 0 开始)。数字一旦超过 9 就会变成 0,如此循环往复。例如,s = "3456" 且 a = 5,则执行此操作后 s 变成 "3951"。 轮转:将 s 向右轮转 b 位。例如,s = "3456" 且 b = 1,则执行此操作后 s 变成 "6345"。 请你返回在 s 上执行上述操作任意次后可以得到的 字典序最小 的字符串。

如果两个字符串长度相同,那么字符串 a 字典序比字符串 b 小可以这样定义:在 a 和 b 出现不同的第一个位置上,字符串 a 中的字符出现在字母表中的时间早于 b 中的对应字符。例如,"0158” 字典序比 "0190" 小,因为不同的第一个位置是在第三个字符,显然 '5' 出现在 '9' 之前。

示例 1:

输入:s = "5525", a = 9, b = 2 输出:"2050" 解释:执行操作如下: 初态:"5525" 轮转:"2555" 累加:"2454" 累加:"2353" 轮转:"5323" 累加:"5222" 累加:"5121" 轮转:"2151" 累加:"2050" 无法获得字典序小于 "2050" 的字符串。

思路分析:

我们都知道轮转是循环的,每次从0开始,向右轮转,当再次轮转回到0的时候,所有可能轮转的都遍历过了。 每次轮转,如果轮转的b是奇数,则可以把第0位加到最小值。 同理,把第1位加到最小值。 那么这个数即是此次轮转的最小值。

我们考虑到长度为偶数 奇数偶数位可以独立考虑,再考虑 无论如何调整 当前组的相对位置是不变的 对于每种情况 我们只考虑开头一个位置变成最小值 就是整个的最小值 遍历所有的可能位于开头位置的序列,那么整个过程大概是n^2

DFS/BFS

核心思想:直接暴力搜,记录一下搜过的数字,最后没得搜了就得到了结果

var findLexSmallestString = function(s, a, b) {
    let m = [], min = s, len = s.length;
    let dfs = function(s){
        if(m.indexOf(s) > -1){
            return;
        }
        m.push(s);
        if(+s < +min){
            min = s;
        }
        s1 = [...s].map((v,i)=>i%2===1?(+v+a)%10:v).join("");
        dfs(s1);
        s2 = [...s].map((v,i)=>s[(i+b)%len]).join("");
        dfs(s2);
    }
    dfs(s);
    return min;
};

暴力枚举(给我破了它)

思想:根据题意直接模拟题干意思,如果要得到最后结果的话,只需要转两次加两次,也就是四层循环。不就n^4嘛,冲了

var findLexSmallestString = function(s, a, b) {
    function add(str, num) {
        const res = str.split('').map((item, index) => {
            if (index % 2 === num) {
                return (+item + a).toString().slice(-1);
            }
            return +item;
        }).join('');
        return res;
    }
    function change(str, b) {
        const arr = str.split('');
        const res1 = arr.splice(str.length - b, b);
        return res1.concat(arr).join('');
    }

    let str = s;
    let min = s;
    if (b % 2 === 1) {
        do {
            let str1 = str;
            do {
                let str2 = str1;
                do {
                    if (+str2 < +min) {
                        min = str2;
                    }
                    str2 = change(str2, b);
                } while (str2 !== str1);
                str1 = add(str1, 0)
            } while (str1 !== str);
            str = add(str, 1);
        } while (str !== s);
    } else {
        do {
            let str1 = str;
            do {
                if (+str1 < +min) {
                    min = str1;
                }
                str1 = change(str1, b);
            } while (str1 !== str);
            str = add(str, 1);
        } while (str !== s);
    }
    return min;
};

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤