diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index 5e06490a..05ad872b 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -36,7 +36,7 @@ 贪心的思路,局部最优:当前可移动距离尽可能多走,如果还没到终点,步数再加一。整体最优:一步尽可能多走,从而达到最小步数。 -思路虽然是这样,但在写代码的时候还不能真的就能跳多远跳远,那样就不知道下一步最远能跳到哪里了。 +思路虽然是这样,但在写代码的时候还不能真的能跳多远就跳多远,那样就不知道下一步最远能跳到哪里了。 **所以真正解题的时候,要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最小步数!** @@ -234,31 +234,6 @@ class Solution: ### Go -```Go -func jump(nums []int) int { - dp := make([]int, len(nums)) - dp[0] = 0//初始第一格跳跃数一定为0 - - for i := 1; i < len(nums); i++ { - dp[i] = i - for j := 0; j < i; j++ { - if nums[j] + j >= i {//nums[j]为起点,j为往右跳的覆盖范围,这行表示从j能跳到i - dp[i] = min(dp[j] + 1, dp[i])//更新最小能到i的跳跃次数 - } - } - } - return dp[len(nums)-1] -} - -func min(a, b int) int { - if a < b { - return a - } else { - return b - } -} -``` - ```go // 贪心版本一 func jump(nums []int) int { @@ -320,8 +295,6 @@ func max(a, b int) int { } ``` - - ### Javascript ```Javascript diff --git a/problems/0134.加油站.md b/problems/0134.加油站.md index 37dddb99..ade84773 100644 --- a/problems/0134.加油站.md +++ b/problems/0134.加油站.md @@ -176,13 +176,13 @@ public: * 时间复杂度:$O(n)$ * 空间复杂度:$O(1)$ -**说这种解法为贪心算法,才是是有理有据的,因为全局最优解是根据局部最优推导出来的**。 +**说这种解法为贪心算法,才是有理有据的,因为全局最优解是根据局部最优推导出来的**。 ## 总结 对于本题首先给出了暴力解法,暴力解法模拟跑一圈的过程其实比较考验代码技巧的,要对while使用的很熟练。 -然后给出了两种贪心算法,对于第一种贪心方法,其实我认为就是一种直接从全局选取最优的模拟操作,思路还是好巧妙的,值得学习一下。 +然后给出了两种贪心算法,对于第一种贪心方法,其实我认为就是一种直接从全局选取最优的模拟操作,思路还是很巧妙的,值得学习一下。 对于第二种贪心方法,才真正体现出贪心的精髓,用局部最优可以推出全局最优,进而求得起始位置。 diff --git a/problems/0135.分发糖果.md b/problems/0135.分发糖果.md index 442deccd..f56e1839 100644 --- a/problems/0135.分发糖果.md +++ b/problems/0135.分发糖果.md @@ -65,7 +65,7 @@ for (int i = 1; i < ratings.size(); i++) { 如果 ratings[i] > ratings[i + 1],此时candyVec[i](第i个小孩的糖果数量)就有两个选择了,一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。 -那么又要贪心了,局部最优:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,保证第i个小孩的糖果数量即大于左边的也大于右边的。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。 +那么又要贪心了,局部最优:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,保证第i个小孩的糖果数量既大于左边的也大于右边的。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。 局部最优可以推出全局最优。 @@ -172,63 +172,44 @@ class Solution: ``` ### Go -```golang +```go func candy(ratings []int) int { /**先确定一边,再确定另外一边 1.先从左到右,当右边的大于左边的就加1 2.再从右到左,当左边的大于右边的就再加1 **/ - need:=make([]int,len(ratings)) - sum:=0 - //初始化(每个人至少一个糖果) - for i:=0;i0;i--{ - if ratings[i-1]>ratings[i]{ - need[i-1]=findMax(need[i-1],need[i]+1) + // 2.再从右到左,当左边的大于右边的就右边加1,但要花费糖果最少,所以需要做下判断 + for i := len(ratings)-1; i > 0; i-- { + if ratings[i-1] > ratings[i] { + need[i-1] = findMax(need[i-1], need[i]+1) } } //计算总共糖果 - for i:=0;inum2{ +func findMax(num1 int, num2 int) int { + if num1 > num2 { return num1 } return num2 } ``` -### Rust -```rust -pub fn candy(ratings: Vec) -> i32 { - let mut candies = vec![1i32; ratings.len()]; - for i in 1..ratings.len() { - if ratings[i - 1] < ratings[i] { - candies[i] = candies[i - 1] + 1; - } - } - - for i in (0..ratings.len()-1).rev() { - if ratings[i] > ratings[i + 1] { - candies[i] = candies[i].max(candies[i + 1] + 1); - } - } - candies.iter().sum() -} -``` - ### Javascript: ```Javascript var candy = function(ratings) { @@ -255,6 +236,25 @@ var candy = function(ratings) { ``` +### Rust +```rust +pub fn candy(ratings: Vec) -> i32 { + let mut candies = vec![1i32; ratings.len()]; + for i in 1..ratings.len() { + if ratings[i - 1] < ratings[i] { + candies[i] = candies[i - 1] + 1; + } + } + + for i in (0..ratings.len()-1).rev() { + if ratings[i] > ratings[i + 1] { + candies[i] = candies[i].max(candies[i + 1] + 1); + } + } + candies.iter().sum() +} +``` + ### C ```c #define max(a, b) (((a) > (b)) ? (a) : (b)) diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index 2c5c7cd3..934cc9ee 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -39,7 +39,7 @@ ## 思路 -本题有两个维度,h和k,看到这种题目一定要想如何确定一个维度,然后在按照另一个维度重新排列。 +本题有两个维度,h和k,看到这种题目一定要想如何确定一个维度,然后再按照另一个维度重新排列。 其实如果大家认真做了[135. 分发糖果](https://programmercarl.com/0135.分发糖果.html),就会发现和此题有点点的像。 @@ -47,7 +47,7 @@ **如果两个维度一起考虑一定会顾此失彼**。 -对于本题相信大家困惑的点是先确定k还是先确定h呢,也就是究竟先按h排序呢,还先按照k排序呢? +对于本题相信大家困惑的点是先确定k还是先确定h呢,也就是究竟先按h排序呢,还是先按照k排序呢? 如果按照k来从小到大排序,排完之后,会发现k的排列并不符合条件,身高也不符合条件,两个维度哪一个都没确定下来。 @@ -222,48 +222,46 @@ class Solution: ### Go ```go func reconstructQueue(people [][]int) [][]int { - //先将身高从大到小排序,确定最大个子的相对位置 - sort.Slice(people,func(i,j int)bool{ - if people[i][0]==people[j][0]{ - return people[i][1]people[j][0]//这个只是确保身高按照由大到小的顺序来排,并不确定K是按照从小到大排序的 + return people[i][0] > people[j][0] // 身高按照由大到小的顺序来排 }) - //再按照K进行插入排序,优先插入K小的 - result := make([][]int, 0) - for _, info := range people { - result = append(result, info) - copy(result[info[1] +1:], result[info[1]:])//将插入位置之后的元素后移动一位(意思是腾出空间) - result[info[1]] = info//将插入元素位置插入元素 + + // 再按照K进行插入排序,优先插入K小的 + for i, p := range people { + copy(people[p[1]+1 : i+1], people[p[1] : i+1]) // 空出一个位置 + people[p[1]] = p } - return result + return people } ``` ```go -//链表法 +// 链表实现 func reconstructQueue(people [][]int) [][]int { sort.Slice(people,func (i,j int) bool { - if people[i][0]==people[j][0]{ - return people[i][1]people[j][0] + return people[i][0] > people[j][0] }) - l:=list.New()//创建链表 - for i:=0;ib{ +func min(a, b int) int { + if a > b { return b } return a diff --git a/problems/0860.柠檬水找零.md b/problems/0860.柠檬水找零.md index bc006f45..fc336eba 100644 --- a/problems/0860.柠檬水找零.md +++ b/problems/0860.柠檬水找零.md @@ -54,7 +54,7 @@ 这是前几天的leetcode每日一题,感觉不错,给大家讲一下。 -这道题目刚一看,可能会有点懵,这要怎么找零才能保证完整全部账单的找零呢? +这道题目刚一看,可能会有点懵,这要怎么找零才能保证完成全部账单的找零呢? **但仔细一琢磨就会发现,可供我们做判断的空间非常少!** @@ -179,38 +179,23 @@ class Solution: ### Go -```golang +```go func lemonadeChange(bills []int) bool { - //left表示还剩多少 下标0位5元的个数 ,下标1为10元的个数 - left:=[2]int{0,0} - //第一个元素不为5,直接退出 - if bills[0]!=5{ - return false - } - for i:=0;i0{ - left[0]-=1 - }else { + ten, five := 0, 0 + for i := 0; i < len(bills); i++ { + if bills[i] == 5 { + five++ + } else if bills[i] == 10 { + if five == 0 { return false } - } - if tmp==15{ - if left[1]>0&&left[0]>0{ - left[0]-=1 - left[1]-=1 - }else if left[1]==0&&left[0]>2{ - left[0]-=3 - }else{ + ten++; five-- + } else { + if ten >= 1 && five >= 1 { + ten--; five-- + } else if five >= 3 { + five -= 3 + } else { return false } }