初学者关于Leetcode-1855(下标对的最大距离)的三种方法分析

1. 题目

给你两个 非递增 的整数数组 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) 。

2. 3种解题方法:

(1)暴力解法

        直接使用双重循环去进行最大值的寻找,但使用此方法时,要考虑时间复杂度问题,单纯的使用双从循环会超出时间限制,因此此处nums2出的判断就进行了简化。代码展示:



class Solution {
    public int maxDistance(int[] nums1, int[] nums2) {
        int max=0;
        for(int i=0;i<nums1.length;i++){
            for(int j=i+max;j<nums2.length;j++){
                if(nums1[i]<=nums2[j]){
                    int cha=j-i;
                    if(cha>max){
                        max=cha;
                    }
                }else{
                        break;
                    }
               
            }
        }
        return max;
    }
}
​

(2)双指针解法

        此题还可进行双指针处理,通过遍历nums1每一位与nums2的对应位进行比较,遍历长度更短,例如i为0时,nums1显示的是下标为0的第一位,分别与nums2的每位比较,当比到nums1大于nums2的之时,后续将不再进行比较,直接让nums1的第二位即下标为1的数字跟nums2的第二位及之后的每一位进行比较,过程你与第一位数字比较方式相似。代码展示:

class Solution {
    public int maxDistance(int[] nums1, int[] nums2) {
       int i=0,j=0,maxDistance=0;
       while(i<nums1.length){
           if(j>nums2.length-1 || nums1[i]>nums2[j]){
               i++;
               j=i+maxDistance;
           }else{
               if(maxDistance<(j-i)){
                   maxDistance=j-i;    
               }
               j++;
           }
       }
        return maxDistance;
    }
}

(3)二分查找解法

        使用二分查找将left与nums1下标数进行绑定,right与nums2的范围绑定,使用两者的中间值进行最后一位大于nums1的下标数查找,然后进行最大距离的计算。代码展示:

class Solution {
   public int maxDistance(int[] nums1, int[] nums2) {
        int maxDistance=0;
        for(int i=0;i<nums1.length;i++){
            int left=i;
            int right=nums2.length-1;
            if(nums2.length-i<maxDistance){
                break;
            }
            while(left<=right){
                int mid=(left+right)>>1;

                if(nums2[mid]>=nums1[i]){
                    left=mid+1;
                    if(maxDistance<(mid-i)){
                        maxDistance=mid-i;
                    }
                }else{
                    right=mid-1;
                }
            }
        }

        return maxDistance;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值