问题
剑指 Offer 42. 连续子数组的最大和
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。
题意分析: 查找数组中连续数之间最大的和(可能是一个也可能十多个)
- 声明两个变量,一个用来存储累计当前的最大和 maxAns,一个用来存储计算到当前的和pre
- 遍历数组,当前值加上pre>pre时,pre = pre + 当前值
- 当maxAns < pre 时,maxAns = pre
- 返回maxAns
测试用例 nums = [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
var maxSubArray = function(nums) {
if(!nums.length) return;
let pre = 0, maxAns = nums[0];
nums.forEach((x) => {
pre = Math.max(pre + x, x);
maxAns = Math.max(maxAns, pre);
});
return maxAns;
};
剑指 Offer 47. 礼物的最大价值
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
题意理解 二位数组从左上到右下,只能向右或向下走,返回累计最大的和
- 定义个变量用来存储走到每个点的左大值
- 从左上到右上只能从左到右走,可以计算出第一行走到每个位置的值
- 从左上到左下只能从上往下走,可以计算出福一列走到每个位置的值
- 然后开始计算第二行、第二列开始一次到每个点比较出的最大值
- 返回右下角数据
测试用例 输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 12 解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
if(!grid.length){
return 0
}
// 设置res 储存每个节点最大值的数组
let res = []
for(let i=0;i<grid.length;i++){
res[i] = []
for(let j =0;j<grid[0].length;j++){
res[i][j] = 0
}
}
// 算出向下走第一行的取值
let m = 0
for(let i =0;i<res.length;i++){
m += grid[i][0]
res[i][0] = m
}
let n = 0
for(let i =0;i<res[0].length;i++){
n += grid[0][i]
res[0][i] = n
}
for(let i=1;i<grid.length;i++){
for(let j =1;j<grid[0].length;j++){
res[i][j] = Math.max(res[i][j-1],res[i-1][j])+grid[i][j]
}
}
return res[grid.length-1][grid[0].length-1]