yankewei / LeetCode

LeetCode 问题的解决方法
MIT License
6 stars 0 forks source link

逐步求和得到正数的最小值 #140

Open yankewei opened 3 years ago

yankewei commented 3 years ago

给你一个整数数组 nums 。你可以选定任意的 正数 startValue 作为初始值。

你需要从左到右遍历 nums 数组,并将 startValue 依次累加上 nums 数组中的值。

请你在确保累加和始终大于等于 1 的前提下,选出一个最小的 正数 作为 startValue 。

示例 1:

输入:nums = [-3,2,-3,4,2]
输出:5
解释:如果你选择 startValue = 4,在第三次累加时,和小于 1 。
                累加求和
                startValue = 4 | startValue = 5 | nums
                  (4 -3 ) = 1  | (5 -3 ) = 2    |  -3
                  (1 +2 ) = 3  | (2 +2 ) = 4    |   2
                  (3 -3 ) = 0  | (4 -3 ) = 1    |  -3
                  (0 +4 ) = 4  | (1 +4 ) = 5    |   4
                  (4 +2 ) = 6  | (5 +2 ) = 7    |   2

示例 2:

输入:nums = [1,2]
输出:1
解释:最小的 startValue 需要是正数。

示例 3:

输入:nums = [1,-2,-3]
输出:5

提示:

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/minimum-value-to-get-positive-step-by-step-sum 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

yankewei commented 3 years ago

模拟

按照题意模拟即可,因为我们知道数组的最大长度和最小值,直接两层循环久可以,有一点要注意我们的初始值不能小于1

func minStartValue(nums []int) int {
    r := 0-nums[0]+1
    if r < 1 {
        r = 1
    }

    for startValue := r; startValue < 10000; startValue++ {
        ret := startValue
        isBreak := false
        for i := 0; i < len(nums); i++ {
            ret += nums[i]
            if ret < 1 {
                isBreak = true
                break
            }
        }
        if !isBreak {
            r = startValue
            break
        }
    }
    return r
}

前缀和

我们可以先假设初始值为0,那么其时整个过程就是一个求前缀和,遍历一遍找到前缀和的最小值min,这样我们的结果只要让初始值+min = 1即可。 要注意一点,就是可能最小值min都大于1,直接返回1即可。

func minStartValue(nums []int) int {
    preSum, min := 0, 10000
    for i := 0; i < len(nums); i++ {
        preSum += nums[i]
        if preSum < min {
            min = preSum
        }
    }
    if min >= 1{
        return 1
    }
    return 1-min
}