[杨小白]_leetcode_力扣第 88 场双周赛-第四题

127 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

前言

小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!

力扣第 88 场双周赛

力扣第 88 场双周赛-力扣

a了三题,2000以内,小上10几分。第一题太离谱了,写O(n)的算法wa了太多次,应该直接暴力的,,,,

image.png

这里放一下312的排名,也是wa了8次 image.png

这个第四题,其实也是可以暴力做出来的。

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

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

  • 0 <= i < j <= n - 1 且

  • nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff.

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

示例 1

  • 输入:nums1 = [3,2,5], nums2 = [2,2,1], diff = 1
  • 输出:3
  • 解释:
  • 总共有 3 个满足条件的数对:
    1. i = 0, j = 1:3 - 2 <= 2 - 2 + 1 。因为 i < j 且 1 <= 1 ,这个数对满足条件。
    1. i = 0, j = 2:3 - 5 <= 2 - 1 + 1 。因为 i < j 且 -2 <= 2 ,这个数对满足条件。
    1. i = 1, j = 2:2 - 5 <= 2 - 1 + 1 。因为 i < j 且 -3 <= 2 ,这个数对满足条件。
  • 所以,我们返回 3 。

示例 2

  • 输入: nums1 = [3,-1], nums2 = [-2,2], diff = -1
  • 输出: 0
  • 解释:
  • 没有满足条件的任何数对,所以我们返回 0 。

提示

  • n == nums1.length == nums2.length
  • 2 <= n <= 105
  • -104 <= nums1[i], nums2[i] <= 104
  • -104 <= diff <= 104

代码

  • 首先我们将表达式化简nums1[i] - nums2[i] <= nums1[j] - nums2[j] + diff
  • 然后用一个arr数组表示nums1[i] - nums2[i]
  • 此时就在归并排序中计算,此处看灵茶山艾府的解析视频得到的思路。
  • 这里附上链接,大家可以去看看解析 【力扣双周赛 88】逆序对:树状数组&归并排序
class Solution {
    public long numberOfPairs(int[] nums1, int[] nums2, int diff) {
        //nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff
        //nums1[i] - nums2[i] <= nums1[j] - nums2[j] + diff
        //arr[i] <= arr2[j] + diff
        int[] arr = new int[nums1.length];
        for(int i = 0; i < nums1.length; i++) {
            arr[i] = nums1[i] - nums2[i];
        }
        long res = 0;
        res = fun(arr,0, arr.length - 1, diff);
        return res;
    }

    private long fun(int[] arr, int l, int r, int diff) {
        if (l == r) {
            return 0;
        }
        int mid = l + r >> 1;
        long res = fun(arr,l,mid,diff) + fun(arr,mid + 1, r,diff);
        for (int i = l; i <= mid; i++) {
            // for (int j = mid + 1; j <= r; j++) {  //从前往后(超时)
            //     if (arr[j] >= arr[i] - diff) {
            //         res = res + r - j + 1;
            //         // res++;
            //         break;
            //     }
            // }
            // for (int j = r; j >= mid + 1; j--) { //从后往前(超时)
            //     if (arr[j] >= arr[i] - diff) {
            //         res++;
            //         // break;
            //     }else{
            //         break;
            //     }
            // }
            for (int j = mid + 1; j <= r; j++) { //两边一起
                if (arr[j] >= arr[i] - diff) {
                    res = res + r - j + 1;
                    break;
                }
                if (arr[r - j + mid + 1] < arr[i] - diff) {
                    res = res + j - mid - 1;
                    break;
                }
            }
        }
        int cur = 0;
        int[] ints = new int[r - l + 1];
        int left = l;
        int right = mid + 1;
        while (left <= mid && right <= r) {
            if (arr[left] < arr[right]) {
                ints[cur++] = arr[left++];
            }else {
                ints[cur++] = arr[right++];
            }
        }
        for (int i = left; i <= mid; i++) {
            ints[cur++] = arr[i];
        }
        for (int i = right; i <= r; i++) {
            ints[cur++] = arr[i];
        }
        for (int i = 0; i < ints.length; i++) {
            arr[l + i] = ints[i];
        }
        return res;
    }
}

第一、二题连接如下-力扣第 88 场双周赛-第一、二题

力扣第 88 场双周赛-第一、二题

第三题连接如下-力扣第 88 场双周赛-第三题

力扣第 88 场双周赛-第三题

3.结束

第四题还是无从下手,我什么时候能成为四题选手啊!!!!gogogo,刷题刷题,每天一道,三年1000道!!!!