1.买卖股票的最佳时间②
思路:构建每两天之间的利润之差,如果是正数则一直累加即可。
体现出来场景是,如果理论一直为正,则说明我们需要一直持有股票。当出现负数时,代表我们应该在前一天卖出。当出现正数时我们应该在前一天买入。
func maxProfit(prices []int) int {
profits := make([]int,len(prices)-1)
//生成profits数组
for i:=1;i<len(prices);i++{
profits[i-1] = prices[i]-prices[i-1]
}
sum := 0
for i:=0;i<len(profits);i++{
if profits[i]>0{
sum += profits[i]
}
}
return sum
}
2.跳跃游戏
2.1 反向遍历(自己写)
特殊条件:
- 数组只有一个元素,永远为true
- 数组第一个元素为0且长度不为1,永远为false
- 数组最后一个元素为0
我是思路是从后往前遍历,当有零时向前查看有能够跳过该0的数。
func canJump(nums []int) bool {
if len(nums)==1{
return true
}
if nums[0]==0{
return false
}
flag := true
for i:= len(nums)-1;i>0;{
if nums[i]==0{
flag = false
temp := 1
if i==len(nums)-1{
temp = 0
}
i--
for i>=0{
if nums[i]>temp{
flag = true
break
}else{
temp++
i--
}
}
}else{
i--
continue
}
if !flag{
return false
}
}
return true
}
2.2 正向遍历(官方)
// 贪心
func canJump(nums []int) bool {
cover := 0//目前所能覆盖到的最远地方
n := len(nums)-1
for i:=0;i<=cover;i++{//每次与覆盖值相比较
cover = max(i+nums[i],cover//每走一步都将 cover 更新为最大值)
if cover >= n{
return true
}
}
return false
}
func max(a, b int ) int {
if a > b {
return a
}
return b
}
3.跳跃游戏②
使用jumpCount来记录到达每个位置的最小步数。
3.1 方法1(自己写的)
感觉用了动态规划
func jump(nums []int) int {
n := len(nums)
jumpCount := make([]int, n)
for i := 0; i < n; i++ {
for j := 1; j <= nums[i] && i+j < n; j++ {
if jumpCount[i+j] == 0 {
jumpCount[i+j] = jumpCount[i] + 1
} else {
jumpCount[i+j] = min(jumpCount[i+j], jumpCount[i]+1)
}
if i+j == n-1 {
return jumpCount[n-1]
}
}
}
return jumpCount[n-1]
}
2.2 官方方法
// 贪心版本一
func jump(nums []int) int {
n := len(nums)
if n==1{
return 0
}
cur,next := 0,0
step := 0
for i := 0;i<n;i++{
next = max(nums[i]+i, next)
if i == cur{//只有当走到目前能走的最远处才考虑进行走下一步
if cur != n-1{//还没到达终点
step++
cur= next
if cur>=n-1{//已经可以到达终点
return step
}
}else{
return step
}
}
}
return step
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
4.K次取反后最大化的数组和
解题思路:尽可能的先将最小负数进行反转,若全部翻转后还有次数剩余。若为偶数,则无所谓。若为奇数,则将一个最小数进行反转
func largestSumAfterKNegations(nums []int, k int) int {
sort.Slice(nums, func(i, j int) bool {
return math.Abs(float64(nums[i])) > math.Abs(float64(nums[j]))
})
sum := 0
for i := 0; i < len(nums); i++ {
if nums[i] < 0 && k > 0 {
sum += -nums[i]
k--
} else {
sum += nums[i]
}
}
if k%2 == 0 {
return sum
} else {
if nums[len(nums)-1] > 0 {
return sum + 2*nums[len(nums)-1]*-1
} else {
return sum + 2*nums[len(nums)-1]
}
}
}