【代码随想录——贪心算法——二周目】

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]
		}
	}
}

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值