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)

相关推荐
☆cwlulu3 小时前
Linux系统调用与C库I/O的底层奥秘
java·spring boot·spring
008爬虫实战录4 小时前
【数据结构】 树、二叉树、完全二叉树,先序遍历、中序遍历、后序遍历
数据结构·算法
小O的算法实验室4 小时前
2024年AST,基于费马点分组粒子群算法的复合型无人机统一路径规划
算法·无人机
于先生吖4 小时前
前后端分离人事招聘项目,校招宣讲预约+社招双向撮合功能架构设计教程
java·开发语言·uni-app
user_admin_god4 小时前
Claude Code 安装与配置指南:兼容国产模型,禁止自动更新
java·人工智能
AllData公司负责人4 小时前
大模型赋能AllData数据中台,系列升级|通过联合智谱大模型与BiSheng开源项目,建设企业大模型应用开发平台,支持知识库向量检索!
大数据·数据结构·数据库·算法·大模型·向量数据库·智谱ai
一个王同学4 小时前
从零到一 | CV转多模态大模型 | week12 | 整理 MiniLLaVA 工程与文档
人工智能·深度学习·算法·机器学习·计算机视觉
一只鹿鹿鹿4 小时前
网络安全评估方案
java·大数据·运维·物联网·web安全
码界索隆4 小时前
Python转Java系列:作者有话说
java·开发语言·python