算法小知识-----8.09-----逐步求和得到正数的最小值

160 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情

做工不饱和的一天,周二的会议一堆

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

该题出自力扣的1413题 —— 逐步求和得到正数的最小值【简单题】,虽然是简单题,但差点翻车了

审题

给你一个整数数组 nums 。你可以选定任意的 正数 startValue 作为初始值。
你需要从左到右遍历 nums 数组,并将 startValue 依次累加上 nums 数组中的值。
请你在确保累加和始终大于等于 1 的前提下,选出一个最小的 正数 作为 startValue 。

image.png

  • 题意并不是很复杂,毕竟简单题,给出一个整型数组,并且返回一个数值,这个数值需要与数组每个元素相加后 大于等于1
  • 简单模拟:
    • 定义一个max值和一个变量值,最终返回max值变量
    • 循环遍历数组
      • 计算出当前元素与变量值的相加
      • 判断结果是否小于1,如果是则证明max变量小了,需要加上少于1的数,并且重置x 等于1
      • 否则变量等于结果
  • 除此以外,还可以有二分的做法
    • 本质上就是寻找负数,只需要找到数组内部的负数进行业务处理即可
    • 当 nums 所有下标数值都为正数时,可以直接返回1;
    • 当存在负数时,可以在某个数值满足startValue的要求时,比它大的数字肯定也都满足,比它小的数字则不一定能满足
    • 判断某个数字是否满足 startValue 的要求时,可以将nums 的数字逐步加到这个数字上,判断是否一直为正即可。

编码

class Solution {
    public int minStartValue(int[] nums) {
        int max = 1;
        int x = 1;
        for (int num:nums) {
            int sum = num +x;
            if (sum < 1){
                max += (1-sum);
                x  = 1;
            }else {
                x = sum;
            }
        }
        return max;
    }
}
public int minStartValue(int[] nums) {
        int m = Arrays.stream(nums).min().getAsInt();
        if (m >= 0) {
            return 1;
        }
        int left = 1, right = -m * nums.length + 1;
        while (left < right) {
            int medium = (left + right) / 2;
            if (valid(medium, nums)) {
                right = medium;
            } else {
                left = medium + 1;
            }
        }
        return left;
    }