LeetCode11.18每日一题--134加油站

在这里插入图片描述

题解区看到一个非常好的思路,记录并分享一下

来题解区:https://leetcode-cn.com/problems/gas-station/comments/
力扣评论区: https://leetcode-cn.com/problems/gas-station/comments/

补上个人对本题的一些看法:

  1. 如果总油量大于消耗量,就一定会找到一个起始位置能跑环形,
  2. 如果以 [A, B]不能达到,那么起点应当从B+1开始
  3. 如果能从 x 达到最后一个位置,那么你车中的油会是最大值,也就是会大于[0, x) 的负油量
  4. 那么x就是我们开始的位置

补上这种思路的代码

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        length = len(cost)
        derta = [0]*length
              
        for i in range(length):
            derta[i] = gas[i] - cost[i]
        if sum(derta) < 0:
            return -1
        dertaSum = 0
        start = 0
        for j in range(length):
            dertaSum += derta[j]
            if dertaSum < 0:
                dertaSum = 0
                start = j + 1
        return start

第一种思路复杂,但是编码较简单,效率也高

第二种简单的思路,但是时间复杂度要高不少,
在这里插入图片描述

思路就很简单了, 暴力就完事了,
假设当前位置为初始位置,看能不能跑一圈。如果能,就返回当前起始位置
如果不能,就继续选择下一个
具体看代码:

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        length = len(cost)
        derta = [0]*length
              
        for i in range(length):
            derta[i] = gas[i] - cost[i]
        if sum(derta) < 0:
            return -1
        for j in range(length):
            temp = j
            tempSum = derta[temp]
            while tempSum >= 0 :
            #	判断是否跑一圈,如果跑了一圈,那么就return j
                if temp == length + j:
                    return j
                temp += 1
                # 因为是环形,所以在计算derta值的时候,需要对下标对长度取余
                tempSum += derta[temp % length]
        return -1

补上两个java版本:
第一种方法:
在这里插入图片描述

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int len = gas.length;
        int[] derta = new int[len];
        int Sum_num = 0;
        for (int i = 0; i < len; i++){
            derta[i] = gas[i] - cost[i];
            Sum_num += derta[i];
        }
        if (Sum_num < 0){
            return -1;
        }
        int dertaSum = 0;
        int start = 0;
        for (int j = 0; j < len; j++){
            dertaSum += derta[j];
            if (dertaSum < 0){
                dertaSum = 0;
                start = j + 1;
            }
        }
        return start;
    }
}

第二种:
在这里插入图片描述

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int len = gas.length;
        int[] derta = new int[len];
        int Sum_num = 0;
        for (int i = 0; i < len; i++){
            derta[i] = gas[i] - cost[i];
            Sum_num += derta[i];
        }
        if (Sum_num < 0){
            return -1;
        }
        
        
        for (int j = 0; j < len; j++){
            int temp = j;
            int dertaSum = derta[temp];
            while (dertaSum >= 0){
                if (temp == len + j){
                    return j;
                } 
                temp += 1;
                dertaSum += derta[temp % len];
            }
        }
        return -1;
    }
}

总结:
在评论区看到了这是华为秋招二面的题目,总得来说,如果是暴力法解决该问题,其实难度不高,但是要在面试的时候想到一次遍历,还是需要很扎实的基础和较快的反应能力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值