AI刷题之三数之和问题 | 豆包MarsCode AI刷题

111 阅读4分钟

“三数之和问题”题目要求

一、问题描述

小U有一个整数数组 arr,他希望找到其中三个元素 i, j, k 满足条件 i < j < k 且 arr[i] + arr[j] + arr[k] == target。由于可能存在大量的元组,结果需要对 10^9 + 7 取模。

例如:当 arr = [1,1,2,2,3,3,4,4,5,5] 且 t = 8 时,有多个元组满足条件,你需要返回这些元组的数量。

二、测试样例

输入:arr = [1,1,2,2,3,3,4,4,5,5], t = 8
输出:20

样例2:

输入:arr = [2,2,2,2], t = 6
输出:4

样例3:

输入:arr = [1,2,3,4,5], t = 9
输出:2

样例4:

输入:arr =[1,1,1,1], t = 3
输出:4


三、题目解析

3.1代码思路

1.定义常量与变量

  • 初始化模值:定义常量 MOD = 1000000007,用于后续结果取模。
  • 初始化计数器:定义变量 count,记录满足条件的三数组合数量。

2.遍历所有可能的三元组

使用三重嵌套循环,分别枚举三个数组下标 i, j, 和 k,确保:

  • i < j < k,避免重复组合。

具体过程:

(1)外层循环 (i)** :从数组起始位置开始,枚举第一个数的下标 i

(2) 从 i+1 开始,枚举第二个数的下标 j

(3)从 j+1 开始,枚举第三个数的下标 k

3.判断三数之和是否等于目标值

在内层循环中,检查三元组是否满足 arr[i] + arr[j] + arr[k] == t 的条件:

  • 若条件成立,将计数器 count 加 1。

  • 每次累加后,对计数器取模,避免溢出:

    count = (count + 1) % MOD;
    

4.返回结果

当所有三元组都遍历完毕后,返回计数器 count 的最终值,即满足条件的三元组数量。

3.2详细代码

public class Main {
    public static int solution(int[] arr, int t) {
        int MOD = 1000000007;
        int count = 0;
        
        // 使用三重循环来遍历数组,找到满足条件的 i, j, k 组合
        for (int i = 0; i < arr.length; i++) {
            for (int j = i + 1; j < arr.length; j++) {
                for (int k = j + 1; k < arr.length; k++) {
                    // 检查是否满足条件 arr[i] + arr[j] + arr[k] == t
                    if (arr[i] + arr[j] + arr[k] == t) {
                        count = (count + 1) % MOD;
                    }
                }
            }
        }
        
        return count;
    }

    public static void main(String[] args) {
        System.out.println(solution(new int[]{1, 1, 2, 2, 3, 3, 4, 4, 5, 5}, 8) == 20);
        System.out.println(solution(new int[]{2, 2, 2, 2}, 6) == 4);
        System.out.println(solution(new int[]{1, 2, 3, 4, 5}, 9) == 2);
        System.out.println(solution(new int[]{1, 1, 1, 1}, 3) == 4);
    }
}

四、知识总结

技术点 1:组合遍历的简单性与直接性

代码采用三重循环来枚举所有可能的三元组组合 (i, j, k),并通过判断 arr[i] + arr[j] + arr[k] == t 来确定是否满足条件。优点包括:

  • 清晰直观:逻辑直接以数组下标为中心,明确指出了组合的生成方式。
  • 固定次序:利用 i < j < k 的约束,减少了无效排列,提高了效率。
技术点 2:大数取模的处理

由于可能的组合数量较大,结果对 109+710^9+7109+7 取模:

count = (count + 1) % MOD;

这一设计的优点是:

  • 避免整数溢出:对于可能的高频组合,确保结果始终可控。
  • 符合实际需求:取模操作常见于需要限制结果范围的问题场景,尤其在竞赛中被广泛使用。

代码设计的核心思想是穷举法结合约束条件的逐步缩减。这种方法利用以下思路:

  1. 穷举所有可能性
    通过三重循环,枚举数组中所有三数组合。这种方式保证了不会遗漏任何可能的组合。
  2. 约束条件的逐步筛选
    使用 i < j < k 约束以及 arr[i] + arr[j] + arr[k] == t 条件,逐步剔除无效组合,最终仅保留符合要求的结果。
  3. 结果优化与规约
    通过取模操作,使代码在应对大规模输入时依然能够高效计算并返回正确结果。

五、性能分析

1. 时间复杂度

代码使用了三重嵌套循环,分别遍历数组的三个元素 i, j, k,每层循环的复杂度为 O(n)
因此,总时间复杂度为:O(n3) 这意味着,当数组长度 n 较大时,运行时间会显著增加,适合小规模输入的情况。

2. 空间复杂度

代码只使用了常量级别的变量:

  • 整数变量 countMOD

没有额外的数据结构或递归调用,空间复杂度为:O(1) 即,代码的空间开销非常小,适用于内存受限的场景。