【二分查找】leetcode 1855. 下标对中的最大距离

1855. 下标对中的最大距离

题目描述

给你两个 非递增 的整数数组 nums1​​​​​​ 和 nums2​​​​​​ ,数组下标均 从 0 开始 计数

下标对 (i, j) 中 0 <= i < nums1.length 且 0 <= j < nums2.length 。如果该下标对同时满足 i <= j 且 nums1[i] <= nums2[j] ,则称之为 有效 下标对,该下标对的 距离 为 j - i​​ 。​​

返回所有 有效 下标对 (i, j) 中的 最大距离 。如果不存在有效下标对,返回 0 。
一个数组 arr ,如果每个 1 <= i < arr.length 均有 arr[i-1] >= arr[i] 成立,那么该数组是一个 非递增 数组。

示例1:

输入: nums1 = [55,30,5,4,2], nums2 = [100,20,10,10,5]
输出: 2
解释: 有效下标对是 (0,0), (2,2), (2,3), (2,4), (3,3), (3,4) 和 (4,4) 。
最大距离是 2 ,对应下标对 (2,4) 。

示例2:

输入: nums1 = [2,2,2], nums2 = [10,10,1]
输出: 1
解释: 有效下标对是 (0,0), (0,1) 和 (1,1) 。
最大距离是 1 ,对应下标对 (0,1) 。

示例3:

输入: nums1 = [30,29,19,5], nums2 = [25,25,25,25,25]
输出: 2
解释: 有效下标对是 (2,2), (2,3), (2,4), (3,3) 和 (3,4) 。
最大距离是 2 ,对应下标对 (2,4) 。

提示

  • 1 < = n u m s 1. l e n g t h < = 1 0 5 1 <= nums1.length <= 10^5 1<=nums1.length<=105
  • 1 < = n u m s 2. l e n g t h < = 1 0 5 1 <= nums2.length <= 10^5 1<=nums2.length<=105
  • 1 < = n u m s 1 [ i ] , n u m s 2 [ j ] < = 1 0 5 1 <= nums1[i], nums2[j] <= 10^5 1<=nums1[i],nums2[j]<=105
  • n u m s 1 和 n u m s 2 都是非递增数组 nums1 和 nums2 都是 非递增 数组 nums1nums2都是非递增数组

方法一:双指针

解题思路

使用指针 i 遍历 n u m s 1 nums_1 nums1 中每一个元素,同时使用 j 来遍历 n u m s 2 nums_2 nums2,找出在 n u m s 2 nums_2 nums2 < = n u m s 1 [ i ] <= nums_1[i] <=nums1[i] 的第一个位置,求出此时 j - i 的值,并更新最大值。

代码

class Solution {
public:
    int maxDistance(vector<int>& nums1, vector<int>& nums2) {
        int n1 = nums1.size(), n2 = nums2.size();
        int i = 0;
        int res = 0;
        for(int j = 0; j < n2; j++)
        {
            while(i < n1 && nums1[i] > nums2[j])
                i++;
            if(i < n1)
                res = max(res, j - i);
        }
        return res;
    }
};

复杂度分析

  • 时间复杂度: O ( n 1 + n 2 ) O(n1+n2) O(n1+n2),其中 n 1 n_1 n1, n 2 n_2 n2 分别为 nums 1 \textit{nums}_1 nums1 nums 2 \textit{nums}_2 nums2 的长度。在双指针寻找最大值的过程中,我们最多会遍历两个数组各一次。
  • 空间复杂度: O ( 1 ) O(1) O(1)

方法二:二分查找

解题思路

遍历 n u m s 1 nums_1 nums1 中每一个元素,同时在 n u m s 2 nums_2 nums2 中利用二分查找的方法找出 > = n u m s 1 [ i ] >= nums_1[i] >=nums1[i] 的第一个位置,求出此时 j - i 的值,并更新最大值。

代码

class Solution {
public:
    int maxDistance(vector<int>& nums1, vector<int>& nums2) {
        int ans = 0;
        for(int i = 0; i < nums1.size(); i++)
        {
            if(i >= nums2.size())   break;
            int l = i, r = nums2.size() - 1, mid;
            while(l < r)
            {
                mid = (l + r + 1) >> 1;
                if(nums2[mid] >= nums1[i]) l = mid;
                else    r = mid - 1;
            }
            if(nums2[l] >= nums1[i])
                ans = max(ans, l - i);
        }
        return ans;
    }
};

复杂度分析

  • 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度: O ( 1 ) O(1) O(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值