#2734 执行子串操作后的字典序最小字符串(Java)

题目:

给你一个仅由小写英文字母组成的字符串 s 。在一步操作中,你可以完成以下行为:

选择 s 的任一非空子字符串,可能是整个字符串,接着将字符串中的每一个字符替换为英文字母表中的前一个字符。例如,'b' 用 'a' 替换,'a' 用 'z' 替换。
返回执行上述操作 恰好一次 后可以获得的 字典序最小 的字符串。

子字符串 是字符串中的一个连续字符序列。

现有长度相同的两个字符串 x 和 字符串 y ,在满足 x[i] != y[i] 的第一个位置 i 上,如果 x[i] 在字母表中先于 y[i] 出现,则认为字符串 x 比字符串 y 字典序更小 。

示例 1:
输入:s = "cbabc"
输出:"baabc"
解释:我们选择从下标 0 开始、到下标 1 结束的子字符串执行操作。
可以证明最终得到的字符串是字典序最小的。

示例 2:
输入:s = "acbbc"
输出:"abaab"
解释:我们选择从下标 1 开始、到下标 4 结束的子字符串执行操作。
可以证明最终得到的字符串是字典序最小的。

示例 3:
输入:s = "leetcode"
输出:"kddsbncd"
解释:我们选择整个字符串执行操作。
可以证明最终得到的字符串是字典序最小的。

提示:
1 <= s.length <= 3 * 105
s 仅由小写英文字母组成

解题思路:

步骤:

为了解决这个问题,需要寻找一种方法,能够在对字符串 s 进行一次操作后,生成字典序最小的字符串。我们可以利用以下策略:
1.识别从哪个位置开始对字符进行替换:
需要找到从左边起的第一个非 'a' 的字符,因为替换掉最左边的字符对字典序的影响最大。
2.替换字符:
对于第一个非 'a' 的字符及其后续字符进行替换,将每个字符替换为前一个字符(例如 'b' 替换为 'a','c' 替换为 'b',等等)。
3.保持其他字符不变:
在找到的第一个非 'a' 的字符之前的所有字符和之后的所有 'a' 字符都保持不变。

复杂度分析:

时间复杂度:O(n),其中 n 是字符串的长度。只需线性扫描字符串一次。
空间复杂度:O(n),使用了一个字符数组来存储字符串。

代码:

class Solution {
    public String smallestString(String s) {
        // 将字符串 s 转换为字符数组 chars 以便进行字符操作
        char[] chars = s.toCharArray();
        // 获取字符串长度 n
        int n = chars.length;

        // 从左到右找到第一个非 'a' 的字符的位置
        int i = 0;
        while(i < n && chars[i] == 'a') {
            i++;
        }

        // 整个字符串全部字符都是 'a' ,那就将最后一个 'a' 替换成 'z'
        if(i == n) {
            chars[n - 1] = 'z';
        } else {
            // 从第一个非 'a' 字符开始替换为前一个字符,直到遇到下一个 'a' 或者到字符串结束
            while(i < n && chars[i] != 'a'){
                chars[i] = (char)(chars[i] - 1);
                i++;
            }
        }

        return new String(chars);
    }
}
posted @   KenWan  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示