题目链接
脑子比较笨,分三种情况考虑:
- 以a开头。
- xxa,a在中间。
对于情况2还有两种可能:
1. 全是a,最后一个元素需要替换成z,因为必须执行一次操作。
2. aaaxxa,中间有一段非a,将这段改变即可。
垃圾实现代码:
class Solution {
public:string smallestString(string s) {int fidx = -1, sidx = -1;string ans = "";for (int i = 0; i < s.size(); i ++ ) {if (s[i] == 'a') {fidx = i;break;}}if (fidx == 0) {// a 开头的int j = 0;while(s[j] == 'a') {j ++;}// j 第一个不是a的元素if (j == s.size()) { // 全是afor (int i = 0; i < s.size(); i ++ ) {ans += s[i];}ans[s.size() - 1] = 'z';return ans;} else { // aaaa xxxxx afor (; j < s.size(); j ++ ) {if (s[j] == 'a') {sidx = j;break;}}for (int i = 0; i < s.size(); i ++ ) {if (i < j && s[i] !='a') {ans += (s[i] - 1);} else {ans += s[i];}}return ans;}} else if (fidx != -1 ){ // bbb afor (int i = 0; i < s.size(); i ++ ) {if (i < fidx) {ans += (s[i] - 1);} else {ans += s[i];}}return ans;} else {for (int i = 0; i < s.size(); i ++ ) {ans += (s[i] - 1);}return ans;}}
};
灵神的代码(我的看起来好傻):
从左到右找到第一个不等于 a 的字符 s[i],然后从 i 开始,把每个字符都减一,直到遍历结束或者遇到了 a。例如 abca 操作中间的子串 bc,得到答案 aaba。
细节:如果 s 全为 a,由于题目要求必须操作一次,可以把最后一个 a 改成 z。
class Solution {
public:string smallestString(string s) {int n = s.length();for (int i = 0; i < n; i++) {if (s[i] > 'a') {// 继续向后遍历for (; i < n && s[i] > 'a'; i++) {s[i]--;}return s;}}// 所有字母均为 as.back() = 'z';return s;}
};