Easy
题目描述
给定一个下标从 0 开始的整数数组 nums,判断是否存在两个长度为 2 的子数组具有相等的和。注意,这两个子数组必须开始于不同的下标。
如果存在这样的子数组,返回 true;否则,返回 false。
子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [4,2,4]
输出:true
解释:元素为 [4,2] 和 [2,4] 的子数组的和都是 6。
示例 2:
输入:nums = [1,2,3,4,5]
输出:false
解释:没有两个长度为 2 的子数组有相同的和。
示例 3:
输入:nums = [0,0,0]
输出:true
解释:子数组 [nums[0],nums[1]] 和 [nums[1],nums[2]] 的和都是 0。
注意,即使子数组的内容相同,但它们在原数组中的位置不同,因此被视为不同的子数组。
约束条件:
2 <= nums.length <= 1000-10^9 <= nums[i] <= 10^9
解题思路
这道题要求判断是否存在两个长度为 2 的子数组具有相等的和。
思路分析:
由于子数组长度固定为 2,我们可以遍历数组,计算每个长度为 2 的子数组的和。具体来说,对于位置 i,子数组的和就是 nums[i] + nums[i+1]。
解法一:哈希集合(推荐)
- 使用哈希集合存储已经遇到的子数组和
- 遍历数组,计算当前位置开始的长度为 2 的子数组和
- 如果这个和已经在集合中,说明找到了两个相等的子数组和,返回 true
- 否则将当前和加入集合,继续遍历
- 如果遍历完都没找到,返回false
解法二:暴力枚举
- 双重循环,枚举所有可能的子数组对
- 比较它们的和是否相等
- 时间复杂度较高,不推荐
第一种解法时间复杂度为 O(n),空间复杂度为 O(n),是最优解法。由于数组长度最大为 1000,哈希集合的空间开销也很小。
代码实现
class Solution {
public:
bool findSubarrays(vector<int>& nums) {
unordered_set<int> sums;
for (int i = 0; i < nums.size() - 1; i++) {
int sum = nums[i] + nums[i + 1];
if (sums.count(sum)) {
return true;
}
sums.insert(sum);
}
return false;
}
};
class Solution:
def findSubarrays(self, nums: List[int]) -> bool:
sums = set()
for i in range(len(nums) - 1):
subarray_sum = nums[i] + nums[i + 1]
if subarray_sum in sums:
return True
sums.add(subarray_sum)
return False
public class Solution {
public bool FindSubarrays(int[] nums) {
HashSet<int> sums = new HashSet<int>();
for (int i = 0; i < nums.Length - 1; i++) {
int sum = nums[i] + nums[i + 1];
if (sums.Contains(sum)) {
return true;
}
sums.Add(sum);
}
return false;
}
}
var findSubarrays = function(nums) {
const sums = new Set();
for (let i = 0; i < nums.length - 1; i++) {
const sum = nums[i] + nums[i + 1];
if (sums.has(sum)) {
return true;
}
sums.add(sum);
}
return false;
};
复杂度分析
| 复杂度类型 | 大小 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(n) |
其中 n 是数组的长度。我们需要遍历数组一次,每次操作的时间复杂度为 O(1)。空间复杂度取决于哈希集合中存储的元素个数,最坏情况下为 O(n)。
相关题目
. Two Sum (Easy)
. Partition Equal Subset Sum (Medium)
. Find Two Non-overlapping Sub-arrays Each With Target Sum (Medium)