1.最大连续子数组和问题
输入一个 非空 整型数组,数组里的数可能为正,也可能为负。数组中一个或连续的多个整数组成一个子数组。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
样例
输入:[1, -2, 3, 10, -4, 7, 2, -5]
输出:18
class Solution {
public:
int maxSubArray(vector<int>& nums) {
// from linyan
// 遍历至nums[i]时 若此次加上nums[i]后curSum变为负数
// 就没必要带着这个负数继续加了 curSum重新至0
// 用res记录中途出现的最大值
int res = nums[0];
int curSum = 0;
for (int i = 0; i < nums.size(); ++i) {
curSum += nums[i];
res = max(res, curSum);
curSum = (curSum<0) ? 0 : curSum; // vital idea
}
return res;
}
};
2.数组中出现次数超过一半的元素
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
假设数组非空,并且一定存在满足条件的数字。
样例
输入:[1,2,1,1,3]
输出:1
class Solution {
public:
int moreThanHalfNum_Solution(vector<int>& nums) {
// 当cnt累加 累减至0时 tar若真的符合要求 则在剩余的数组里同样符合要求
int cnt = 1;
int tar = nums[0];
for (int i = 1; i < nums.size(); ++i) {
if (nums[i] == tar) cnt++;
else cnt--;
if (cnt++ == 0) tar = nums[i];
}
cnt = 0;
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] == tar) cnt++;
}
if (cnt > nums.size()/2) return tar;
}
};
3.数组中出现次数刚好一半的元素
数组中有一个数字出现的次数刚好是数组长度的一半,请找出这个数字。
假设数组非空,并且一定存在满足条件的数字。
样例
输入:[1,2,1,3]
输出:1
class Solution {
public:
int moreThanHalf(vector<int> &nums) {
int cnt = 1;
int tar = nums[0];
for (int i = 1; i < nums.size(); ++i) {
if (nums[i] == tar) cnt++;
else cnt--;
if (cnt++ == 0) tar = nums[i];
}
cnt = 0;
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] == tar) cnt++;
}
if (cnt > nums.size()/2) return tar;
}
int HalfNum_Solution(vector<int>& nums) {
// 沿用2.超过一半的逻辑
int tar = moreThanHalf(nums);
int cnt = 0;
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] == tar) cnt++;
}
if (cnt == nums.size()/2) return tar;
else {
vector<int> v = nums;
v.pop_back();
return moreThanHalf(v);
}
}
};