分发糖果——算法

68 阅读1分钟

image.png

代码两次遍历:

image.png

  1. 所以我们第一次遍历只记录满足左规则的各个学生的糖果数
  2. 在第二次遍历时,将满足右规则的答案得出,取两者的最大值即可,
func candy(ratings []int) (ans int) {
    n := len(ratings)
    left := make([]int, n)
    for i, r := range ratings {
        if i > 0 && r > ratings[i-1] {
            left[i] = left[i-1] + 1
        } else {
            left[i] = 1
        }
    }
    right := 0
    for i := n - 1; i >= 0; i-- {
        if i < n-1 && ratings[i] > ratings[i+1] {
            right++
        } else {
            right = 1
        }
        ans += max(left[i], right)
    }
    return
}

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

代码常数空间遍历:

记录当前递减序列的长度 dec,最近的递增序列的长度inc 和前一个同学分得的糖果数量 pre 最终答案ans

func candy(ratings []int) int {
    n := len(ratings)
    ans, inc, dec, pre := 1, 1, 0, 1
    for i := 1; i < n; i++ {
        if ratings[i] >= ratings[i-1] {
            dec = 0
            if ratings[i] == ratings[i-1] {
                pre = 1
            } else {
                pre++
            }
            ans += pre
            inc = pre
        } else {
            dec++
            if dec == inc {
                dec++
            }
            ans += dec
            pre = 1
        }
    }
    return ans
}