455. 分发饼干
解题步骤
- 排序:给两个数组排序
- 举例判断:看第一个情况不满足,要换孩子还是换物品?
a. 换孩子→遍历孩子
b. 换物品→遍历物品
实战:
- 选择从小到大排序
- 第一个不满足,我要换物品。因为换了孩子还是不满足。
- 确定了遍历顺序:换物品→遍历物品
go实现
/*** @date: 2024 Jan 06* @time: 10:50* @author: Chris* @title: 455. Assign Cookies* @link: https://leetcode.cn/problems/assign-cookies/description/
**/
package day31import ("sort"
)// 优先满足胃口小的孩子,
// 如果不可以换下一个物品;如果换孩子的的话也不能满足
func findContentChildren(g []int, s []int) int {// sort by ascendingsort.Ints(g)sort.Ints(s)child := 0// 遍历物品,如果不行换下个物品for sIndex := 0; child < len(g) && sIndex < len(s); sIndex++ {// 物品sIndex在不断递增// child只有满足的当前孩子时候才递增,才会尝试分配给下一个孩子if s[sIndex] >= g[child] {child++}}return child
}// 优先满足胃口大的孩子,
// 如果不行,换下个孩子; 如果换下一个物品的话也不能满足。
func findContentChildren2(g []int, s []int) int {// sortsort.Ints(g)sort.Ints(s)sIndex := len(s) - 1// 遍历孩子,如果不行换孩子for i := len(g) - 1; sIndex >= 0 && i >= 0; i-- {// 孩子可能大于饼干数,注意sIndex别越界if s[sIndex] >= g[i] {sIndex--}}return (len(s) - 1) - sIndex
}
55. 跳跃游戏
/*** @date: 2024 Jan 06* @time: 13:32* @author: Chris* @title: 55. Jump Game* @link: https://leetcode.cn/problems/jump-game/description/
**/
package day32// 跳跃覆盖范围究竟可不可以覆盖到终点!
func canJump(nums []int) bool {if len(nums) == 1 {return true}// 记录 能到达的最大的位置cover := 0// 注意这里i的范围是cover,是能到达的距离!超过这个距离不能到达for i := 0; i <= cover; i++ {// 更新cover = (当前位置+跳跃距离, 旧cover)cover = max(i+nums[i], cover)if cover >= len(nums)-1 {return true}}return false
}
45. 跳跃游戏 II
思路:
记录步骤的规则: 每超过上一次可达最大范围,需要跳跃一次。
所以 在i==上一次可达范围+1的位置进行记录,次数+1
即if (i == lastDistance + 1) minSetp++;
从题目中可知:一开始到达了nums[0]位置,从nums[1]记录一次!
然后题目确保了可到达尾巴nums[n-1]。
/*** @date: 2024 Jan 06* @time: 13:44* @author: Chris* @title: 45. Jump Game II* @link: https://leetcode.cn/problems/jump-game-ii/description/
**/
package day32// 记录步骤规则:每超过上一次可达最大范围,需要跳跃一次,次数+1
// 记录位置:i == lastDistance + 1
func jump(nums []int) int {// 根据题目规则,初始位置为nums[0]lastDistance := 0 // 上一次覆盖范围curDistance := 0 // 当前覆盖范围(可达最大范围)minStep := 0 // 记录最少跳跃次数for i := 0; i < len(nums); i++ {if i == lastDistance+1 { // 在上一次可达范围+1的位置,记录步骤minStep++ // 跳跃次数+1lastDistance = curDistance // 记录时才可以更新}curDistance = max(nums[i]+i, curDistance) // 更新当前可达的最大范围}return minStep
}
135. 分发糖果
1. 初始化每人一个糖果
2. 确保每个比左邻居评分高的孩子,比左邻居多一颗糖果。
a. 从左向右遍历–>,和右邻居比较
💡 因为判断是基于左邻居,应先确定左边,所以从左到右遍历
3. 确保每个比右邻居评分高的孩子,比右邻居多一颗糖果。
a. 从右向左遍历<–,和右邻居比较
💡 判断基于右邻居,右边的状态先确定,所以从右向左遍历
/*** @date: 2024 Jan 06* @time: 17:16* @author: Chris* @title: 135. Candy* @link: https://leetcode.cn/problems/candy/
**/
package day34func candy(ratings []int) int {n := len(ratings)if n == 0 {return 0}// 初始化,每人一个糖candies := make([]int, n)for i := range candies {candies[i] = 1}// 确保每个比左邻居评分高的孩子,比左邻居多一颗糖果。// 从左到右 --->for i := 1; i < n; i++ {//评分比左侧高!if ratings[i] > ratings[i-1] {// 比左侧多一个candies[i] = candies[i-1] + 1}}// 确保每个比右邻居评分高的孩子,比右邻居多一颗糖果。// 从右到左 <---for i := n - 2; i >= 0; i-- {//评分比右侧高! 如果糖果少的话再操作,糖果多不要操作,可能会减少糖果!// 比如 [1,2,3,1] 糖果数[1,2,3,1],不加这个条件3就变成2了!if ratings[i] > ratings[i+1] && candies[i] <= candies[i+1] {candies[i] = candies[i+1] + 1}}total := 0for _, c := range candies {total += c}return total
}
细节:
左到右→: i =1
右到左←: i = n-2
为什么是评分比较不包含=符号?
题目要求比邻居高,糖果比邻居糖果多,
如果相等(即不比邻居高),那么可以不比邻居多。
比如: ratings[1, 2, 2] 糖果为:[1, 2, 1]
为什么第二次循环多加了一个candies[i] <= candies[i+1]
判断,如果不判断有什么后果?
如果当前孩子比右邻居糖果还进行操作,可能会减少糖果!从而导致违背第一次遍历要求!
比如ratings [1,2,3,1] 第一次遍历糖果数[1,2,3,1]
不加这个条件,遍历[1,2,3
,1],3就会变成2了!不满足糖果数大于左邻居!