22年48周

最近两周刷了刷贪心和动态规划的题目,可以说这两类题目还是比较难想的。

目录

1.买卖股票的最佳时机II

2.跳跃游戏

3.跳跃游戏II

4.K次取反后最大化的数组和

5.加油站

6.柠檬水找零


1.买卖股票的最佳时机II

题目:买卖股票的最佳时机II

思路:局部最优:收集每天的正利润,全局最优:求得最大利润

原因就是有这个递推公式:

假如第0天买入,第3天卖出,那么利润为:prices[3] - prices[0]。

相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。

此时就是把利润分解为每天为单位的维度,而不是从0天到第3天整体去考虑!

所以只要第二天能获利,就当天买入,第二天卖出

func maxProfit(prices []int) int {
    result := 0 

    for i:=1;i 0 {
            result += prices[i] - prices[i-1]
        }
    }
    return result
}

2.跳跃游戏

题目:跳跃游戏

思路:每跳一次都去选择,如果跳到这一个节点i,nums[i] + i 和假如没跳到这个节点来讲,哪个覆盖率更大一点,就选择是否跳到该节点。

贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点

55.跳跃游戏

 

func canJump(nums []int) bool {
    if len(nums) <= 1 {
        return true
    }
    n := len(nums)
    cover := 0
    //[4,2,0,0,1,1,4,4,4,0,4,0]
    for i:=0;i<=cover;i++ {
        //i代表当前的位置
        //nums[i]表示,加上当前的这个能挑到最远的位置
        cover = max(i+nums[i],cover)
        if cover >= n-1 {
            return true
        }
    }
    return false
}

func max(a, b int ) int {
    if a > b {
        return a
    }
    return b
}

3.跳跃游戏II

题目:跳跃游戏II

思路:

func jump(nums []int) int {
    n := len(nums)
    if n == 1 {
        return 0
    }
    cur, next := 0, 0
    step := 0
    for i := 0; i < n-1; i++ {
        next = max(nums[i]+i, next)
        if i == cur {
            cur = next
            step++
        }
    }
    return step
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

4.K次取反后最大化的数组和

题目:K次取反后最大化的数组和

思路:这道题其实还是比较好想的,先排序,之后把小于零的全都取反,

之后再排序,看取反次数还剩多少,偶数个的话,就是数组和

奇数个的话,就是首元素取反之后的数组和。

func largestSumAfterKNegations(nums []int, k int) int {

    sort.Ints(nums)
    index := 0
    i:=0
    //有小于0的直接逆反
    for ;i

5.加油站

题目:加油站

思路:

首先如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。

每个加油站的剩余量rest[i]为gas[i] - cost[i]。

i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,起始位置从i+1算起,再从0计算curSum。

func canCompleteCircuit(gas []int, cost []int) int {
    total := 0
    partTotal := 0
    start := 0

    for i:=0;i

6.柠檬水找零

题目:柠檬水找零

思路:这道题用简单的模拟就能完成。优先使用5元的来找零

func lemonadeChange(bills []int) bool {
    if bills[0] != 5 {
        return false
    }

    billsMap := make(map[int]int)

    for _,v := range bills {
        if v == 5 {
            billsMap[v]++
        }
        if v == 10 {
            billsMap[5]--
            if billsMap[5] < 0 {
                return false
            }
            billsMap[10]++
        }
        if v == 20 {
            if billsMap[10] > 0 {
                billsMap[10]--
                billsMap[5]--
                if billsMap[5] < 0 {
                    return false
                }
            }else {
                billsMap[5] -= 3
                if billsMap[5] < 0 {
                    return false
                }
            }
        }
    }
    return true
}

你可能感兴趣的:(leetcode刷题总结,算法)