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和++相互配合。