• [LeetCode] 923. 3Sum With Multiplicity


    Given an integer array arr, and an integer target, return the number of tuples i, j, k such that i < j < k and arr[i] + arr[j] + arr[k] == target.

    As the answer can be very large, return it modulo 109 + 7.

    Example 1:

    Input: arr = [1,1,2,2,3,3,4,4,5,5], target = 8
    Output: 20
    Explanation: 
    Enumerating by the values (arr[i], arr[j], arr[k]):
    (1, 2, 5) occurs 8 times;
    (1, 3, 4) occurs 8 times;
    (2, 2, 4) occurs 2 times;
    (2, 3, 3) occurs 2 times.
    

    Example 2:

    Input: arr = [1,1,2,2,2,2], target = 5
    Output: 12
    Explanation: 
    arr[i] = 1, arr[j] = arr[k] = 2 occurs 12 times:
    We choose one 1 from [1,1] in 2 ways,
    and two 2s from [2,2,2,2] in 6 ways.

    Constraints:

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

    三数之和的多种可能。

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

    由于结果会非常大,请返回 结果除以 10^9 + 7 的余数。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/3sum-with-multiplicity
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    题目其实就对思路有了一些提示。既然是求三数之和,那么思路就可以往15题上靠。这道题我们找的是一个满足题意的三元组,但是注意因为input里面给的数字是有重复的,所以计算的时候要小心一些。

    首先我们记录一下input里面每个数字都分别出现的次数,用一个count数组记录好。接着我们还是按15题的思路开始遍历,首先确定前两个数字 i, j,那么第三个数字 k = target - i - j。当k的范围不在 0 - 100的时候则说明是一个无效的组合,直接跳过即可;当k是一个有效的数字的时候,也需要额外判断如下几种case

    如果i == j && j == k,说明三个数字相同。对于三个数字相同的组合,他们可以产生的组合数量是 c[i] * (c[i] - 1) * (c[i] - 2) / 6

    如果i == j && j != k, 说明其中两个数字相同,组合数量是 c[i] * (c[i] - 1) / 2 * c[k]

    如果三个数字都互不相同,组合数量是 c[i] * c[j] * c[k]

    时间O(n^2)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int threeSumMulti(int[] arr, int target) {
     3         long[] c = new long[101];
     4         for (int num : arr) {
     5             c[num]++;
     6         }
     7 
     8         int MOD = 1_000_000_007;
     9         // 注意res的类型,极容易错
    10         long res = 0;
    11         for (int i = 0; i <= 100; i++) {
    12             for (int j = i; j <= 100; j++) {
    13                 int k = target - i - j;
    14                 if (k > 100 || k < 0) {
    15                     continue;
    16                 }
    17                 if (i == j && j == k) {
    18                     res += c[i] * (c[i] - 1) * (c[i] - 2) / 6;
    19                 } else if (i == j && j != k) {
    20                     res += c[i] * (c[i] - 1) / 2 * c[k];
    21                 } else if (j < k) {
    22                     res += c[i] * c[j] * c[k];
    23                 }
    24             }
    25         }
    26         return (int) (res % MOD);
    27     }
    28 }

    two sum题目总结

    LeetCode 题目总结

  • 相关阅读:
    打造自己的性能测试类
    网站配置之最佳实践
    C#控制台窗口居中显示(转)
    将PDM文件导出成CHM帮助文件
    分享使用NPOI导出Excel树状结构的数据,如部门用户菜单权限
    Oracle 给已创建的表增加自增长列
    托管调试助手“NonComVisibleBaseClass”检测到问题
    翻页效果
    Excel表格转Json数据结构
    关于2D渲染的一些小想法
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14375779.html
Copyright © 2020-2023  润新知