题目描述
给你两个 非递增 的整数数组 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 都是 非递增 数组 nums1和nums2都是非递增数组
方法一:双指针
解题思路
使用指针 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)。