1、数组/字符串

238. 除了自身以外数组的乘积

中等

解题思路:左右乘积

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        // 维护从左起的乘积,第一个元素为1
        // 维护从右起的乘积,从右起第一个元素为1
        int n = nums.length;
        int[] leftMul = new int[n];
        int[] rightMul = new int[n];
        // 从左到右
        leftMul[0] = 1;
        for (int i = 1; i < n; i++) {
            leftMul[i] = leftMul[i-1] * nums[i-1];
        }
        // 从右到左
        rightMul[n-1] = 1;
        for (int i = n - 2; i >= 0; i--) {
            rightMul[i] = rightMul[i+1] * nums[i+1];
        }
        // 计算结果
        int[] res = new int[n];
        for (int i = 0; i < n; i++) {
            res[i] = leftMul[i] * rightMul[i];
        }
        return res;
    }
}

时间复杂度O(N),空间复杂度O(N),

和接雨水这道题类似,

空间复杂度为O(N),实际上分别用数组存储左右乘积,可以省略,直接使用ans存储

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        // 维护从左起的乘积,第一个元素为1
        // 维护从右起的乘积,从右起第一个元素为1
        int n = nums.length;
        int[] res = new int[n];
        // 从左到右
        res[0] = 1;
        for (int i = 1; i < n; i++) {
            res[i] = res[i-1] * nums[i-1];
        }
        // 从右到左
        int R = 1;
        for (int i = n - 1; i >= 0; i--) {
            res[i] = res[i] * R;
            R *= nums[i];
        }
        // 计算结果
        return res;
    }
}

134. 加油站

中等

解题思路:

超时

我能想到,从每个加油站出发,尝试能不能走一圈后回来,

例如从当前i出发,则当前到达下一个位置剩余油量为cur = gasi - costi,如果cur < 0,说明从当前i出发不能绕一圈。

跳过当前下一个位置是(i + 1) % n,如何说明走了一圈了,可以统计一下步骤

java 复制代码
class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n = gas.length;
        if(n == 1) return gas[0] >= cost[0] ? 0 : -1;
        // 枚举出发位置
        for (int start = 0; start < n; start++) {
            int i = start;
            int cur = 0;
            int step = 0;
            while (step < n) {
                // 计算从i到i+1,剩下的油量
                cur += gas[i] - cost[i];
                if (cur  < 0) {
                    break;
                }
                i = (i + 1) % n;
                step++;
            }
            if (step == n) {
                return start;
            }
        }
        return -1;
    }
}

break,是终止当前的while循环。

上述方法是暴力枚举超时的,

如何从O(N^2)优化到O(N),可以用贪心,

如果从起点A无法到达B,那么从A到B之间的任何一个点出发,也绝对无法到达B,因此可以直接把起点更新为B的下一个位置。

因此由于要走一个循环,所以总的油量大于等于总消耗即可,就一定有解,反之没有,

java 复制代码
class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n = gas.length;
        // 记录总油量
        int totalSum = 0;
        // 记录当前起点出发,到当前位置的累计油量差值
        int curSum = 0;
        int start = 0;

        for (int i = 0; i < n; i++) {
            // 计算差值
            int diff = gas[i] - cost[i];
            totalSum += diff;
            curSum += diff;

            // 局部剪枝
            // 如果从当前位置出发,油量变为负
            // 说明start,i之间任意一个位置出发都不能完成
            // 直接从下一个位置出发
            if (curSum < 0) {
                start = i + 1;
                curSum = 0;
            }
        }

        return totalSum >= 0 ? start : -1;
    }
}

O(N)

相关推荐
mldong2 小时前
一个 App,十三套后端:手机审批端 uni-jeeflow-app 开源了
java·架构
tqs_123453 小时前
MySQL RR隔离级别死锁|Gap间隙锁、临键锁,订单并发范围查询死锁根因方案
java
逆境不可逃3 小时前
Pi Agent 学习笔记:多个工具怎样并行执行
java
v_34836087623 小时前
Android native端 堆栈打印
android·算法
residual_fan3 小时前
【学术论文】航空发动机故障诊断智能体:基于持续对比强化学习的动态优化方法
人工智能·算法·数据挖掘·数据分析
Flynt4 小时前
Java 27 升级实测:默认值动得比新特性多,有个老参数会让 JVM 直接起不来
java·jvm·后端
Bs_MoneyMagnet4 小时前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
GreenTea4 小时前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
星云API技术支持4 小时前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信
niucloud-admin4 小时前
JAVA V6 多商户商城 开发文档——job 计划任务开发
java·python·github