【算法刷题】Day22

文章目录

1. 按摩师


原题链接


题干:

按摩师每次预约服务之间要休息

不能接受相邻的预约

给一个请求序列,摘到最优的预约集合,返回总分钟数

算法原理:(dp)

1. 状态表示:

dpi 表示:选择到 i 位置的时候,此时的最长预约时长

继续细化:

fi 表示:选择到 i 位置时, numsi 必选,此时的最⻓预约时长

gi 表示:选择到 i 位置时, numsi 不选,此时的最长预约时长

2. 状态转移方程

fi

如果 numsi 必选,那么我们仅需知道 i - 1 位置在不选的情况下的最⻓预约时长

然后加上 numsi 即可

因此 fi = gi - 1 + numsi

gi

如果 numsi 不选,那么 i - 1 位置上选或者不选都可以

因此,我们需要知道 i- 1 位置上选或者不选两种情况下的最长时长

因此 gi = max(fi - 1, gi- 1)

3. 初始化

f0 = nums0

g0 = 0

4. 填表顺序

从左往右,两个表⼀起填

5. 返回值

max(fn - 1, gn - 1)


代码:

java 复制代码
class Solution {
    public int massage(int[] nums) {
        int n = nums.length;
        if(n == 0) {
            return 0;
        }
        int[] f = new int[n];
        int[] g = new int[n];
        f[0] = nums[0];

        for(int i = 1; i < n; i++) {
            f[i] = g[i-1] + nums[i];
            g[i] = Math.max(g[i-1],f[i-1]);
        }
        return Math.max(f[n - 1],g[n - 1]);
    }
}

2. 寻找数组的中心下标


原题链接


题干:

中心下标:左侧元素和 = 右侧元素和

如果这个值在最左 或者 最右 和为0

有多个下标,返回最左边

不存在这个值,返回 -1


算法原理:(前缀和)

(1)预处理前缀和

f:前缀和数组

fi 表示:0,i-1 区间,所有元素的和

fi = fi-1 + numsi-1

g:后缀和数组

gi 表示:i+1,n-1 区间,所有元素的和

gi = gi+1 + numsi+1

(2)使用前缀和

在 0~n - 1 枚举下标 i

判断 fi = gi

(3)细节问题

f(0),g(0) 可能越界访问,需要初始化

f(0) = 0

g(n-1) = 0

(4)填表顺序

f:从左往右

g:从右往左


代码:

java 复制代码
class Solution {
    public int pivotIndex(int[] nums) {
        int n = nums.length;
        int[] f = new int[n];
        int[] g = new int[n];

        for(int i = 1; i < n; i++) {
            f[i] = f[i - 1] + nums[i - 1];
        }
        for(int i = n - 2; i >= 0; i--) {
            g[i] = g[i + 1] + nums[i + 1];
        }

        for(int i = 0; i < n; i++) {
            if(f[i] == g[i]) {
                return i;
            }
        }
        return -1;
    }
}

3. 除自身以外数组的乘积


原题链接


题干:

nsweri等于nums中 numsi 之外其余各元素的乘积

前缀元素和后缀的乘积都在 32位 整数范围


算法原理:(前缀和)

(1)预处理前缀积

f:前缀积数组

fi 表示:0,i-1 区间,所有元素的乘积

fi = fi-1 * numsi-1

g:后缀积数组

gi 表示:i+1,n-1 区间,所有元素的乘积

gi = gi+1 * numsi+1

(2)使用前缀和

reti\[i = fi * gi

(3)细节问题

f(0) = 1

g(n-1) = 1

(4)填表顺序

f:从左往右

g:从右往左


代码:

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] f = new int[n];
        int[] g = new int[n];

        f[0] = g[n-1] = 1;
        for(int i = 1; i < n; i++) {
            f[i] = f[i-1] * nums[i-1];
        }
        for(int i = n - 2 ; i >= 0; i--) {
            g[i] = g[i+1] * nums[i+1];
        }
        int[] ret = new int[n];
        for(int i = 0; i < n; i++) {
            ret[i] = f[i] * g[i];
        }
        return ret;
    }
}
相关推荐
折哥的程序人生 · 物流技术专研7 小时前
第4篇:Lambda 简化策略模式(Java 8+)
java·设计模式·策略模式·函数式编程·lambda·代码简化·扩充系列
researcher-Jiang7 小时前
高性能计算之OpenMP——超算习堂学习1
android·java·学习
CS创新实验室8 小时前
算法、齿轮与硅基大脑:数值计算发展简史
人工智能·算法·数值计算
西门吹-禅9 小时前
java springboot N+1问题
java·开发语言·spring boot
DLYSB_9 小时前
生命通道:如何用 HIS 医疗系统直连网络声光终端,打造“零延误”的危急值响应网关?
java·网络·数据库·报警灯
weixin_BYSJ19879 小时前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
海石9 小时前
1563分的简单题,可能就简单在能被暴力AC
算法·leetcode
AI小码9 小时前
LLM 应用的缓存工程:当每次 API 调用都在燃烧成本
java·人工智能·spring·计算机·llm·编程·api
海石10 小时前
1400分的dp汗流浃背之【交替子数组计数】
算法·leetcode
奋发向前wcx10 小时前
P2590 树的统计 题目解析
数据结构·算法·深度优先