6198. 满足不等式的数对数目

155 阅读1分钟

难度:困难

题目描述

给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,两个数组的大小都为 n ,同时给你一个整数 diff ,统计满足以下条件的 数对 (i, j) :

  • 0 <= i < j <= n - 1 且
  • nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff.

请你返回满足条件的 数对数目 。

示例

输入: nums1 = [3,2,5], nums2 = [2,2,1], diff = 1
输出: 3

条件限制

  • n==nums1.length==nums2.lengthn == nums1.length == nums2.length
  • 2<=n<=1052 <= n <= 10^5
  • 104<=nums1[i],nums2[i]<=104-10^4 <= nums1[i], nums2[i] <= 10^4
  • 104<=diff<=104-10^4 <= diff <= 10^4

解题思路

  • 转化题目表达式
nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff
nums1[i] - nums2[i] <= nums1[j] - nums2[j] + diff
设num[i]=nums1[i] - nums2[i]
num[i] < = num[j] + diff
  • 采用值的大小来构建树状数组的大小,其中要注意的是num[i]>=2104num[i]>=-2*10^4,diff>=104diff>=-10^4,此时我们值最小值能取到3104-3*10^4,所以我们将最小值定位到1,故每个值+30001+30001
  • 要需要注意的是update要更新update(num[i]+30001),querty(num[i]+diff+30001),因为[1.....num[i]+diff+30001]才是满足要求的个数和。

相关代码

class Solution {
public:
    int n,N=1e5;
    vector<int>tree;
    int lowbit(int x){return x&(-x);}
    void update(int x){
        while(x<=N){
            tree[x]++;
            x+=lowbit(x);
        }
    }
    int querty(int x){
        int res=0;
        while(x){res+=tree[x];x-=lowbit(x);}
        return res;
    }
    long long numberOfPairs(vector<int>& nums1, vector<int>& nums2, int diff) {
        int n=nums1.size();
        for(int i=0;i<n;i++)nums1[i]-=nums2[i];
        tree.resize(N,0);
        long long res=0;
        for(int i=0;i<n;i++){
            res+=querty(nums1[i]+diff+30001);
            update(nums1[i]+30001);
        }
        return res;
    }
};