青训营X豆包MarsCode技术训练营|豆包MarsCode AI刷题

49 阅读4分钟

今天再来道中等题 等和子数组问题

问题描述

小F最近在研究数组中子数组的总和问题。现在给定一个长度为N的数组A,数组按非递减顺序排序。你需要判断是否存在两个不同的长度相同的子数组,它们的元素总和相等。如果存在这样的子数组,返回1;否则,返回0

请注意,只要两个子数组的起始和结束索引不同,即便它们包含相同的元素,也被认为是不同的子数组。


测试样例

样例1:

输入:N = 5, A = [2, 5, 5, 5, 9]
输出:True

样例2:

输入:N = 4, A = [1, 2, 3, 4]
输出:False

样例3:

输入:N = 6, A = [1, 1, 2, 3, 3, 6]
输出:True

还是那句话 简单分析一哈

我们需要判断给定数组中是否存在两个不同的长度相同的子数组,它们的元素总和相等。数组是按非递减顺序排序的,即数组中的元素是从小到大排列的。若存在这样的子数组,返回1,否则返回0

2. 关键知识点

  • 子数组:子数组是数组中的一个连续部分。(这个不用多说了应该)
  • 非递减顺序:数组已经排好序,我们可以利用这个特性加速某些操作(如排序相关的算法)。

3. 思考过程

要判断是否有两个子数组和相等,可以采用以下方法:

  • 对每个可能的子数组长度,遍历所有可能的子数组,计算它们的总和。
  • 利用哈希表来存储每个子数组的和。对于每个子数组,如果该和已经在哈希表中出现过,则说明存在另一个子数组,其和与当前子数组相同,满足条件。

4. 细化方案

  • 遍历所有可能的子数组的长度,从1N//2(因为至少需要两个子数组才能对比)。
  • 对于每一个子数组长度,遍历所有可能的子数组,计算它们的和,并将和存入哈希表。
  • 如果某个子数组的和已经在哈希表中存在,说明找到了两个和相同的子数组,返回1
  • 如果遍历完成没有找到任何符合条件的子数组,返回0

5. 时间复杂度分析

  • 对于每个子数组长度L,我们要遍历N-L+1个可能的子数组(起始索引从0N-L)。
  • 计算每个子数组的和,时间复杂度为O(L)
  • 因此,总的时间复杂度为O(N^2),其中N是数组的长度。因为我们要计算所有可能的子数组和并存储在哈希表中。

6. 示例分析

示例 1:

输入: N = 5, A = [2, 5, 5, 5, 9]

  • 子数组总和计算:
    • 长度为2的子数组:[2, 5][5, 5][5, 5][5, 9]
    • 长度为3的子数组:[2, 5, 5][5, 5, 5][5, 5, 9]
    • 长度为4的子数组:[2, 5, 5, 5][5, 5, 5, 9]
    • 长度为5的子数组:[2, 5, 5, 5, 9]
  • 在计算长度为3的子数组时,[5, 5, 5][5, 5, 5]的总和相同。因此返回True

示例 2:

输入: N = 4, A = [1, 2, 3, 4]

  • 子数组总和计算:
    • 长度为2的子数组:[1, 2][2, 3][3, 4]
    • 长度为3的子数组:[1, 2, 3][2, 3, 4]
    • 长度为4的子数组:[1, 2, 3, 4]
  • 所有子数组的和都不同,因此返回False

示例 3:

输入: N = 6, A = [1, 1, 2, 3, 3, 6]

  • 子数组总和计算:
    • 长度为2的子数组:[1, 1][1, 2][2, 3][3, 3][3, 6]
    • 长度为3的子数组:[1, 1, 2][1, 2, 3][2, 3, 3][3, 3, 6]
    • 长度为4的子数组:[1, 1, 2, 3][1, 2, 3, 3][2, 3, 3, 6]
    • 长度为5的子数组:[1, 1, 2, 3, 3][1, 2, 3, 3, 6]
    • 长度为6的子数组:[1, 1, 2, 3, 3, 6]
  • 1 + 1 = 23 + 3 = 6的和相同,因此返回True

7. 代码实现

def solution(N, A):
    # 遍历所有子数组长度
    for length in range(1, N // 2 + 1):
        # 用一个字典存储每个子数组的和
        sum_dict = {}
        
        # 遍历所有长度为length的子数组
        for i in range(N - length + 1):
            subarray_sum = sum(A[i:i+length])
            
            # 如果这个子数组的和已经出现过,说明有两个子数组和相等
            if subarray_sum in sum_dict:
                return 1
            sum_dict[subarray_sum] = True
            
    return 0

8. 感慨一下

这段时间也用了不少云端编辑器的AI功能,感觉它的优势体现在它可以有针对性而且便捷的学习,主要在哪里都可以打开。AI通过实时分析我的代码情况,而且有什么不明白的点直接问AI就完事(感觉也会让我养成不勤于思考的坏习惯hh,不过这个也要看个人,如果善用效率还是很高的)通过长期使用AI刷题,尤其是对于中等难度题目刷题效率明显提升,主要是因为界面中直接可以问各种问题,一体式学习工具还能让我随时随地debugger。边debugger边问,岂不快哉!