zoukankan      html  css  js  c++  java
  • LeetCode 1995 统计特殊四元组

    给你一个 下标从 0 开始 的整数数组 nums ,返回满足下述条件的 不同 四元组 (a, b, c, d)数目

    • nums[a] + nums[b] + nums[c] == nums[d] ,且
    • a < b < c < d

    示例 1:

    输入:nums = [1,2,3,6]
    输出:1
    解释:满足要求的唯一一个四元组是 (0, 1, 2, 3) 因为 1 + 2 + 3 == 6 。
    

    示例 2:

    输入:nums = [3,3,6,4,5]
    输出:0
    解释:[3,3,6,4,5] 中不存在满足要求的四元组。
    

    示例 3:

    输入:nums = [1,1,1,3,5]
    输出:4
    解释:满足要求的 4 个四元组如下:
    - (0, 1, 2, 3): 1 + 1 + 1 == 3
    - (0, 1, 3, 4): 1 + 1 + 3 == 5
    - (0, 2, 3, 4): 1 + 1 + 3 == 5
    - (1, 2, 3, 4): 1 + 1 + 3 == 5
    

    提示:

    • 4 <= nums.length <= 50
    • 1 <= nums[i] <= 100
    暴力求解

    暴力枚举,列出所有可能性,时间复杂度为O(n^4)

    /**
     * 因为数组个数<50,可用暴力枚举,时间复杂度O(n^4)
     *
     * @param nums
     * @return
     */
    public static int countQuadruplets01(int[] nums) {
        if (nums == null || nums.length < 4) return 0;
    
        int cnt = 0;
        int n = nums.length;
        for (int i = 0; i < n - 3; i++) {
            for (int j = i + 1; j < n - 2; j++) {
                for (int k = j + 1; k < n - 1; k++) {
                    for (int l = k + 1; l < n; l++) {
                        if (nums[i] + nums[j] + nums[k] == nums[l]) {
                            cnt++;
                        }
                    }
                }
            }
        }
        return cnt;
    }
    
    哈希
    • 新建一个哈希表,用于保存nums[d]出现的次数,因为每个数字不超过100,所有num[a]..num[b],num[c]数字之和不超过300,哈希数组长度限定在301,;

    • 下标d>c, 可以利用逆序C,c逆序加1,下标d的可选范围也可以加1;

    • 时间复杂度可降低一个量级为O(n^3)

    /**
     * 哈希:下标c逆序加1,下标d的可选范围也加1
     * 利用哈希记录,时间复杂度可降低为O(n^3)
     *
     * @param nums
     * @return
     */
    public static int countQuadruplets(int[] nums) {
        int n = nums.length;
        int ans = 0;
        // 每个数字小于等于100,三者之和不超过300
        int[] sum = new int[301];
    
        for (int c = n - 2; c >= 2; c--) {
            sum[nums[c + 1]]++;
            for (int a = 0; a < n - 3; a++) {
                for (int b = a + 1; b < c; b++) {
                    ans += sum[nums[a] + nums[b] + nums[c]];
                }
            }
        }
        return ans;
    }
    
    测试用例
    public static void main(String[] args) {
        int[] nums = new int[]{1, 2, 3, 6};
        int cnt = CountQuadruplets.countQuadruplets(nums);
        System.out.println("CountQuadruplets demo01 result : " + cnt);
    
        nums = new int[]{3, 3, 6, 4, 5};
        cnt = CountQuadruplets.countQuadruplets(nums);
        System.out.println("CountQuadruplets demo02 result : " + cnt);
    
        nums = new int[]{1, 1, 1, 3, 5};
        cnt = CountQuadruplets.countQuadruplets(nums);
        System.out.println("CountQuadruplets demo03 result : " + cnt);
    }
    
    测试结果
    CountQuadruplets demo01 result : 1
    CountQuadruplets demo02 result : 0
    CountQuadruplets demo03 result : 4
    
  • 相关阅读:
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
  • 原文地址:https://www.cnblogs.com/fyusac/p/15745191.html
Copyright © 2011-2022 走看看