1. 题目来源
2. 题目说明
3. 题目解析
方法一:暴力+常规解法
这一阵子暴力习惯了,遇见题脑子都不动了,看了看数据范围就直接暴力枚举。也没多想什么。思路如下:
- 从1 开始,枚举所有可能的正数
- 若出现和小于 1 的情况,则枚举下一个正数
- 若累加结果大于等于 1,则返回当前正数即可
很直接的思路,但是手误将第一个正数起始值设为了 0,自信提交,结果 WA
了一发…
参见代码如下:
// 执行用时 :0 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :7.3 MB, 在所有 C++ 提交中击败了100.00%的用户
class Solution {
public:
int minStartValue(vector<int>& nums) {
int res = 0;
for (int j = 1; j < 10050; ++j) {
int cnt = j;
for (int i = 0; i < nums.size(); ++i) {
cnt += nums[i];
if (cnt < 1) break;
}
if (cnt >= 1) return j;
}
return 0;
}
};
方法二:前缀和+常规解法
一开始没想到,总结的时候能发现其中规律。一直累加的过程就是求前缀和的过程,那么通过这一系列前缀和的最小值就能确定这个最小正数。即:
- 若前缀和中最小值大于 0,则这个最小正数就是 1
- 若前缀和中最小值小于等于 0,即为
num
,那么这个最小正数就是该负数的绝对值再加 1,即abs(num) + 1
,在此就能写为1 - num
简单思路就在上面,那么还在题解区发现了几个大佬采用泛型算法 API
,很是优雅,做以记录。
参见代码如下:
// 执行用时 :0 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :7.5 MB, 在所有 C++ 提交中击败了100.00%的用户
class Solution {
public:
int minStartValue(vector<int>& nums) {
vector<int> a;
partial_sum(nums.begin(), nums.end(), back_inserter(a));
int ans = *min_element(a.begin(), a.end());
return ans <= 0 ? 1 - ans : 1;
}
};
参见代码如下:
// 执行用时 :0 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :7.3 MB, 在所有 C++ 提交中击败了100.00%的用户
class Solution {
public:
int minStartValue(vector<int>& nums) {
int res = 0, cnt = 10050;
for (auto& e : nums) {
res += e;
cnt = min(cnt, res);
}
return cnt <= 0 ? 1 - cnt : 1;
}
};