leetcode算法923. 三数之和的多种可能

99 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情

一、题目描述:

923. 三数之和的多种可能 - 力扣(LeetCode)

给定一个整数数组 arr ,以及一个整数 target 作为目标值,返回满足 i < j < k 且 arr[i] + arr[j] + arr[k] == target 的元组 i, j, k 的数量。

由于结果会非常大,请返回 10^9 + 7 的模。

示例 1:

输入:arr = [1,1,2,2,3,3,4,4,5,5], target = 8
输出:20
解释:
按值枚举(arr[i], arr[j], arr[k]):
(1, 2, 5) 出现 8 次;
(1, 3, 4) 出现 8 次;
(2, 2, 4) 出现 2 次;
(2, 3, 3) 出现 2 次。

示例 2:

输入:arr = [1,1,2,2,2,2], target = 5
输出:12
解释:
arr[i] = 1, arr[j] = arr[k] = 2 出现 12 次:
我们从 [1,1] 中选择一个 1,有 2 种情况,
从 [2,2,2,2] 中选出两个 2,有 6 种情况。

提示:

  • 3 <= arr.length <= 3000
  • 0 <= arr[i] <= 100
  • 0 <= target <= 300

二、思路分析:

巧妙利用双指针,达到固定一个数,寻找剩下两个数。 特殊情况需要注意: 当找到一组组合时,需要判断两数是否相等。 若不相等,看看两数周围有没有和两数一样的数,统计它们,然后相乘。 由于我们先行排序了数组,若两数相等,说明中间已经没有其他不同于两数的数字存在了,我们需要统计一列相同数字的排列组合,然后将之加上就好了。 思路来自于官方~

三、AC 代码:

class Solution {
public:
    int threeSumMulti(vector<int>& A, int target) {
        //升序排序数组
        sort(A.begin(),A.end());
        long res = 0;
        for(int i = 0;i<A.size();i++){
            //确定双指针的目标组合数
            int T = target-A[i];
            int j = i+1;
            int k = A.size()-1;
            while(j<k){
                if(A[j]+A[k]<T){
                    j++;
                }else if(A[j]+A[k]>T){
                    k--;
                }else{
                    //两数加起来的等于目标数T的情况有三种
                    //第一、二种合并处理
                    if(A[j]!=A[k]){
                        int left = 1;
                        int right = 1;
                        while(A[j]==A[j+1]){
                            left++;
                            j++;
                        }
                        while(A[k]==A[k-1]){
                            right++;
                            k--;
                        }
                        res += left*right;
                        j++;
                        k--;
                    }else{
                    //第三种
                        res+= (k-j)*(k-j+1)/2;
                        break;
                    }
                }
            }
        }
        res %= 1000000007;
        return res;
    }
};

范文参考:

双指针 - 三数之和的多种可能 - 力扣(LeetCode) (leetcode-cn.com)