LeetCode——1576.替换所有的问号

通过万岁!!!

  • 题目:给一个字符串,然后将里面的所有的?,替换为小写字母。要求,这个问号替换时,不能与前面和后面的字母重复。
  • 思路:遍历字符串,找到问号就进行替换。这里可以替换成随意的,只要不是跟前面和后面的一样就行。我们最后定义一个规则,就是让她等于前面字母的下一个,如果超过z,就变成a。然后这样保证与前面的不一样,再去判断是不是与后面的不一样,如果一样也是变成下一个字母,也要判断是不是超过z。因为我们需要判断前一个和后一个,所以需要对最开始和最后的位置进行初始化。
  • 技巧:
    • 主要是定义一个规则,而这个规则尽量简单一点。
    • 使用StringBuilder,因为我们要不断对字符串进行追加。或者是用一个char的数组应该也可以,数组长度为s的长度,最后将数组转成String返回,String有构造方法将char数组转成String。
  • 注意:
    • 我们要变成的是前面字母+1的位置,但是这个前面字母是我们最后要返回的结果(StringBuilder对象)的最后一位,这时候不能用题目中给定的字符串,因为前面的字符可能是?。
    • 判断最后一位的时候,可能存在特殊问题,就是字符串长度为1,则考虑第一个的时候考虑了她,最后一个的时候也考虑了她,就会产生问题。

伪代码

定义StringBuilder的字符串sb
定义追加的字符temp
如果0是位置是?
    如果长度大于或者等于2
        temp='a';
        然后判断是不是跟1位置的冲突,要是冲突就temp++,使其不冲突
        然后temp追加到sb即可
        否则,也就是长度等于1的时候
                直接随便返回一个字母就可以了
否则,也就是0位置不是?
        sb追加一下这个字符

然后遍历字符串,从1开始,到s的倒数第二位
        如果是问号
                temp=sb的最后位置+1,并且判断是不是超过了z(也就是122),超过了就改成a,没超过就不变,用三目表达式即可
                判断temp是不是跟后面的字符一样,要是一样则temp也要++
                这时候还需要再判断,因为++以后可能又超过z了。
                然后再将temp追加到sb上
        否则,也就是这个不是?,则直接之家即可
然后就是最后一个位置的判断了,如果是?
        则temp变成sb的最后一个位置+1,并且这个也需要判断是不是超过z
        然后temp追加到sb上即可
否则,应该就是直接追加,但是还有需要判断原字符串长度不能等于1,要求等于1的时候,才再考虑最后一个
        sb追加原字符串的最后一个
return sb的toString()即可。

java代码

class Solution {
    public String modifyString(String s) {
        StringBuilder sb = new StringBuilder();
        char temp;
        if (s.charAt(0) == '?') {
            if (s.length() >= 2) {
                temp = 'a';
                if (temp == s.charAt(1)) {// 与后面字母不同
                    temp++;
                }
                sb.append(temp);
            } else {
                return "a";
            }
        } else
            sb.append(s.charAt(0));

        for (int i = 1; i < s.length() - 1; i++) {
            if (s.charAt(i) == '?') {
                // 不与前面的相同
                temp = (sb.charAt(sb.length() - 1) + 1) > 122 ? 'a' : (char) (sb.charAt(sb.length() - 1) + 1);
                if (temp == s.charAt(i + 1)) {// 与后面字母不同
                    temp++;
                }
                temp = temp > 122 ? 'a' : temp;
                sb.append(temp);
            } else {
                sb.append(s.charAt(i));
            }
        }
        if (s.charAt(s.length() - 1) == '?') {
            temp = (sb.charAt(sb.length() - 1) + 1) > 122 ? 'a' : (char) (sb.charAt(sb.length() - 1) + 1);
            sb.append(temp);
        } else if (s.length() != 1) {
            sb.append(s.charAt(s.length() - 1));
        }
        return sb.toString();
    }
}
  • 总结:题目不复杂,就是比较麻烦而已。首先是自己定义一个选取的规则,然后就是判断前后。

接下来是不适用StringBuilder,而是使用char的数组的代码,这种的空间复杂度回降低很多。

class Solution {
    public String modifyString(String s) {
        char sb[] = new char[s.length()];
        char temp;
        if (s.charAt(0) == '?') {
            if (s.length() >= 2) {
                temp = 'a';
                if (temp == s.charAt(1)) {// 与后面字母不同
                    temp++;
                }
                sb[0] = temp;
            } else
                return "a";
        } else
            sb[0] = s.charAt(0);

        for (int i = 1; i < s.length() - 1; i++) {
            if (s.charAt(i) == '?') {
                // 不与前面的相同
                temp = (sb[i - 1] + 1) > 122 ? 'a' : (char) (sb[i - 1] + 1);
                if (temp == s.charAt(i + 1)) {// 与后面字母不同
                    temp++;
                }
                temp = temp > 122 ? 'a' : temp;
                sb[i] = temp;
            } else {
                sb[i] = s.charAt(i);
            }
        }
        if (s.charAt(s.length() - 1) == '?') {
            temp = (sb[s.length() - 2] + 1) > 122 ? 'a' : (char) (sb[s.length() - 2] + 1);
            sb[s.length() - 1] = temp;
        } else if (s.length() != 1) {
            sb[s.length() - 1] = s.charAt(s.length() - 1);
        }
        return new String(sb);
    }
}

然后我又对多余的代码行删除了一下,得到了最终版。

class Solution {
    public String modifyString(String s) {
        char sb[] = new char[s.length()];
        char temp;
        if (s.charAt(0) == '?') {// 第一个是就是问号
            if (s.length() >= 2) {// 还有后面字母
                if ('a' == s.charAt(1)) // 后面字母是a
                    sb[0] = 'b';// 换个字母
                else
                    sb[0] = 'a';// 用a就行
            } else// 只有一个字符,并且还是问号
                return "a";
        } else// 第一个不是问好
            sb[0] = s.charAt(0);

        // 从第二个到倒数第二个开始遍历
        for (int i = 1; i < s.length() - 1; i++) {
            if (s.charAt(i) == '?') {
                // 不与前面的相同
                temp = (sb[i - 1] + 1) > 122 ? 'a' : (char) (sb[i - 1] + 1);
                if (temp == s.charAt(i + 1)) {// 与后面字母不同
                    temp++;
                }
                sb[i] = temp > 122 ? 'a' : temp;
            } else
                sb[i] = s.charAt(i);
        }
        if (s.charAt(s.length() - 1) == '?') {// 下面不会越界,因为只有s=?的时候才会越界,而这时候,上面已经return了
            sb[s.length() - 1] = (sb[s.length() - 2] + 1) > 122 ? 'a' : (char) (sb[s.length() - 2] + 1);
        } else if (s.length() != 1) {
            sb[s.length() - 1] = s.charAt(s.length() - 1);
        }
        return new String(sb);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值