1576. 替换所有的问号/134. 加油站

又到了拿捏每日一题的简单题环节。
思路:

1.将字符串s转为可变字符串sb。并判断sb的第1位是不是?,如果是,则将其变为改为a。
2.判断字符串的长度是否为1,是1则直接返回sb.toString()。
3.当字符串长度大于1时,从位置1开始逐个遍历sb。此时已知位置0必不是?(就算本来是?,经过第1步的操作之后现在也不是?了)
4.定义pre为前一个位置的字符,cur为当前位置的字符,temp为前一个位置的字符在26个字符中循环后移一位(如pre=‘a’,则temp=‘b’,pre=‘b’,temp='c’,pre=‘z’,temp=‘a’)。
5.如果当前位置为?则修改当前位置为temp,如果当前位置不是?则需要先判断当前位置是否与前一个位置字符相同。
6.如果当前位置字符与前一个位置的字符相同,那么,将前一个位置的字符改为temp。这里用到题目中给定的一个条件,“题目测试用例保证 除 ‘?’ 字符
之外,不存在连续重复的字符。”,根据这句话,如果当前位置不是?,前一个位置如果本来也不是?,那么当前位置必然不可能与前一个位置字符相同。所以现在如果当前位置在不是?的情况下与前一个位置字符相同了,那前一个位置的字符必然之前是?,所以才可以对前一个位置进行修改。
7.如果当前位置字符与前一个位置字符不相同,那这是复合题意的啊,直接循环下一个位置就行。
8.最后遍历结束,返回sb.toString()。

代码:

class Solution {
    public String modifyString(String s) {
        int len = s.length();
        StringBuilder sb = new StringBuilder(s);
        if (s.charAt(0) == '?'){
            sb.setCharAt(0,'a');
        }
        if (len == 1){
            return sb.toString();
        }
        for (int i = 1; i < len; i++) {
            char pre = sb.charAt(i-1),cur = sb.charAt(i);
            char temp =(char)((pre-'a'+1)%26+'a');
            if (cur == '?'){
                sb.setCharAt(i,temp);
            }else {
                if (cur == pre){
                    sb.setCharAt(i-1,temp);
                }
            }
        }
        return sb.toString();
    }
}


每一道题都是自己先写,但凡有一点信心能写出来就不会先去看题解。这题虽然我写的很菜,用时只击败了5%,但我还是要记录。
思路:

1.如果当前加油站得到的油和到下一站要消耗的油相等,那么判断是否是起始站(用can来记录,默认为false表示没有起始站);如果不是起始站,则ans=i,标记起始站位置为当前位置。
2.如果当前加油站得到的油小于到下一站要消耗的油,那么起始站标志位置为false,表示在这个位置之前(包括这个位置)不能被当做起始站。
3.如果当前加油站得到的油大于到下一站要消耗的油,那么用have来存储到去往下一站还能剩下多少油量(到了之后先不加油),index表示下一个加油站的位置,count记录经过了几个加油站。
4.进入while循环,从当前加油站开始往后走,看能否环行一周。count++到达第2个加油站,加满油,再减掉去下一个加油站的油耗,如果have小于0,说明车里的油不够到达下一站,退出循环,继续寻找起始加油站位置(即进入外层for循环);
如果have>=0,说明可以到达下一个加油站,ok,那就去下一个加油站,更新下一个加油站的位置;如果count=len,即已经成功来到起始站前一个站,并加满油减去到达起始站的油耗,此时while循环已经退出,如果have>=0,则说明车里的油可以到达起始站,说明在这个起始站环行成功。此时如果起始站位置标记can为true,则返回标记的起始站位置,如果can为false,说明此前没有符合条件的起始站,那么就返回本层for循环中的加油站位置为起始站位置。
5.如果整个for循环结束都没有起始站位置标记 那么说明没有符合条件的位置,返回-1,或者 有起始站位置标记,且加油站个数等于1,那么此时说明只有一个加油站且加的油等于兜一圈回来的油耗,那么此时返回起始站位置ans。
或者有起始站位置标记,但加油站位置个数大于1,此时有两种情况,举例说明,第一,gas
={3,3,4},cost={3,4,4},此时返回-1,第二,gas={3,3,4} ,cost={3,3,4},此时从任意一个加油站开始都可以,即答案不唯一,但题目给定答案唯一,则第二种情况不存在。所以综上,当for循环结束时,返回can
&& len == 1? ans : -1。

代码:

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int len = gas.length,have = 0,ans = 0;
        boolean can = false;
        for (int i = 0; i < len; i++) {
           if (gas[i] == cost[i]){
                if (!can){
                    ans = i;
                    can = true;
                }
            }else if (gas[i] > cost[i]){
                have =  gas[i] - cost[i];
                int index = (i+1)%len,count = 0;
                while (count<len){
                    count++;
                    have += gas[index]-cost[index];
                    if (have<0){
                        break;
                    }
                    index = (index+1)%len;
                }
                if (have>=0){
                    return can ? ans : i;
                }
            }else {
               can = false;
           }
        }
        return can && len == 1? ans : -1;
    }
}

附上题解代码,思路分析就不写了,想看去看官方题解。

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n = gas.length;
        int i = 0;
        while (i < n) {
            int sumOfGas = 0, sumOfCost = 0;
            int cnt = 0;
            while (cnt < n) {
                int j = (i + cnt) % n;
                sumOfGas += gas[j];
                sumOfCost += cost[j];
                if (sumOfCost > sumOfGas) {
                    break;
                }
                cnt++;
            }
            if (cnt == n) {
                return i;
            } else {
                i = i + cnt + 1;
            }
        }
        return -1;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/gas-station/solution/jia-you-zhan-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值