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) 。
示例 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 <= nums1.length <= 105 1 <= nums2.length <= 105 1 <= nums1[i], nums2[j] <= 105 nums1 和 nums2 都是 非递增 数组
2. 分析
这类计算最大距离和最小距离的题目特别多,感觉还是有很多相似之处。
本题有个条件非递增 的整数数组 nums1 和 nums2 ,我一开始没有注意到 arr[i-1] >= arr[i]这句话,以为就是两个乱序的数组,但其实,这里说的是递减数组。非递增和递减肯定不是一个意思,物理吐槽。
有了这个条件,其实就可以使用滑动窗口的思路来解题。同样采用两层循环,外层循环为第一个数组的顺序遍历,内层循环为第二个数组的顺序遍历,但只需要找到第一个不满足nums1[i] <= nums2[j]就行了,想到与就找到了数组1中第i个数值对应的有效最大距离。更重要的,当遍历到数组1的i+1个下标时,内层循环只需要接着上次的遍历位置继续遍历和比较即可,因为是有序的,不需要从头开始,不然就超时了。
3. 代码实现
class Solution {
public int maxDistance(int[] nums1, int[] nums2) {
int maxDistance = 0;
int fromIndex = 0;
for (int i = 0; i < nums1.length; i++) {
// 判断是否继续循环
if (maxDistance != 0 && maxDistance >= nums2.length - 1 - i) {
return maxDistance;
}
// 从上个位置开始往后找,直到找到第一个不匹配的数据
for (int j = fromIndex; j <= nums2.length - 1; j++) {
if (nums1[i] > nums2[j]) {
fromIndex = j;
break;
}
maxDistance = Math.max(maxDistance, j - i);
}
}
return maxDistance;
}
}