LeetCode第2552题-统计上升四元组-java实现-图解思路与手撕代码

LeetCode第2552题-统计上升四元组-java实现-图解思路与手撕代码


一、题目描述

在这里插入图片描述

二、解题思路与代码实现

1.解题思路

这道题需要从数组中找到满足条件的四个下标,返回所有满足条件的数量。

直接遍历i,j,k,l会超时,可以遍历中间两个下标j和k。

对于每个固定的j和k,
统计下标小于j且值小于nums[k]的i的数量,
统计下标大于k且值大于nums[j]的l的数量,
该组满足条件的下标的数量就是两个数量相乘的结果。

2.代码实现

代码如下(示例):

class Solution {
    public long countQuadruplets(int[] nums) {
        int len = nums.length;
        // 1 <= nums[i] <= nums.length
        // large[k][x]表示nums[idx>k]大于x的个数,其中x的范围是1到len+1
        int[][] large = new int[len][len+1];
        for(int k=len-2;k>=2;k--){
            // 逆序遍历,对于遍历到的第k+1个数nums[k+1],小于这个数的所有数都应该加一。
            // 比如遍历到数5,那么前面如果有1234,都需要加一,表示1234的右边有一个大数。
            large[k]=large[k+1].clone();
            for(int x=nums[k+1]-1;x>0;x--){
                large[k][x]++;
            }
        }
        long res = 0;
        // 这里就不需要二维数组,每遍历一个j,就直接计算,这样甚至省去clone这一步。
        int[] small = new int[len+1];
        for(int j=1;j<len-2;j++){
            // 对于每一个数nums[j-1],对于所有大于这个数的数来说,左边都有一个小数。
            // 所以从nums[j-1]+1到len都要加一。
            for(int x=nums[j-1]+1;x<=len;x++){
                small[x]++;
            }
            // 这里计算结果,对于每一个j,遍历k。
            // 对于满足nums[j]>nums[k]固定的j,k,对结果的贡献是large[k][nums[j]]*small[nums[k]]
            for(int k=j+1;k<len-1;k++){
                if(nums[j]>nums[k]){
                    res+=large[k][nums[j]]*small[nums[k]];
                }
            }
        }
        return res;
    }
}

总结

这道题的难点在于对数据的处理,只用遍历中间两个下标,以及计算满足条件的数量时clone和++相互配合。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值