原题链接:
思路(又是脑子短路没想到的一天):
前缀和+hash。需要确定第i个位置之前有多少的前缀和相加为0,只需要确定前缀和中有多少个值为preSum[i] - goal。然后后半部分就是目标和了。
实现:
class Solution {public:int numSubarraysWithSum(vector<int>& nums, int goal) {int sum = 0;unordered_map<int, int> mp;int ans = 0;for(int i = 0; i < nums.size(); i++){mp[sum]++;sum += nums[i];ans += mp[sum - goal];}return ans;}};
相关练习题:
724. 寻找数组的中心下标
思路1:前缀和后缀和都算一次,然后直接比较。
实现:
class Solution {public:int preSum[10005], endSum[10005];int pivotIndex(vector<int>& nums) {int len = nums.size();preSum[0] = nums[0], endSum[len - 1] = nums[len - 1];for(int i = 1; i < len; i++){preSum[i] = preSum[i - 1] + nums[i];}for(int j = len - 2; j >= 0; j--){endSum[j] = endSum[j + 1] + nums[j];}for(int i = 0; i < len; i++){int pre, end;if(i >= 1 && i < len - 1)pre = preSum[i - 1], end = endSum[i + 1];else if(i < 1){pre = 0, end = endSum[i + 1];}else if(i >= len - 1){pre = preSum[i - 1], end = endSum[i + 1];}if(pre == end)return i;}return -1;}};
思路2:计算前缀和与总和,前缀和成2加上当前位置的数值等于总和即为答案。
实现:
class Solution {public:int pivotIndex(vector<int>& nums) {int total = accumulate(nums.begin(), nums.end(), 0);int sum = 0;for(int i = 0; i < nums.size(); i++){if(sum * 2 + nums[i] == total){return i;}sum += nums[i];}return -1;}};
1. 两数之和
思路:两个哈希表,一个存放出现的值,一个存放值对应的索引。
实现:
class Solution {public:vector<int> twoSum(vector<int>& nums, int target) {map<int, int> mp;map<int, int> mp2;vector<int> ans(2);for(int i = 0; i < nums.size(); i++){int t;if(mp[target - nums[i]] != 0){ans[0] = mp2[target - nums[i]], ans[1] = i;return ans;}mp[nums[i]] = 1;mp2[nums[i]] = i;}return ans;}};
其实不需要两个哈希表,直接一个哈希表存放数值对应的下标就可以了。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> mp;
vector<int> ans(2);
for(int i = 0; i < nums.size(); i++){
int t;
if(mp[target - nums[i]] != 0){
ans[0] = mp[target - nums[i]] - 1, ans[1] = i;
return ans;
}
mp[nums[i]] = i + 1;
}
return ans;
}
};
