Maximum Distance Between a Pair of Values

Med
#1694Time: O(N * log M), where N is the length of `nums1` and M is the length of `nums2`. The outer loop runs N times, and each binary search takes O(log M) time.Space: O(1), as we only use a few variables for the loops and binary search.
Patterns
Algorithms
Data structures

Prompt

You are given two non-increasing 0-indexed integer arrays nums1​​​​​​ and nums2​​​​​​.

A pair of indices (i, j), where 0 <= i < nums1.length and 0 <= j < nums2.length, is valid if both i <= j and nums1[i] <= nums2[j]. The distance of the pair is j - i​​​​.

Return the maximum distance of any valid pair (i, j). If there are no valid pairs, return 0.

An array arr is non-increasing if arr[i-1] >= arr[i] for every 1 <= i < arr.length.

 

Example 1:

Input: nums1 = [55,30,5,4,2], nums2 = [100,20,10,10,5]
Output: 2
Explanation: The valid pairs are (0,0), (2,2), (2,3), (2,4), (3,3), (3,4), and (4,4).
The maximum distance is 2 with pair (2,4).

Example 2:

Input: nums1 = [2,2,2], nums2 = [10,10,1]
Output: 1
Explanation: The valid pairs are (0,0), (0,1), and (1,1).
The maximum distance is 1 with pair (0,1).

Example 3:

Input: nums1 = [30,29,19,5], nums2 = [25,25,25,25,25]
Output: 2
Explanation: The valid pairs are (2,2), (2,3), (2,4), (3,3), and (3,4).
The maximum distance is 2 with pair (2,4).

 

Constraints:

  • 1 <= nums1.length, nums2.length <= 105
  • 1 <= nums1[i], nums2[j] <= 105
  • Both nums1 and nums2 are non-increasing.

Approaches

3 approaches with complexity analysis and trade-offs.

This approach improves upon the brute-force method by optimizing the search for the index j. For each index i in nums1, instead of linearly scanning nums2, we use binary search to find the largest valid index j. This is possible because nums2 is a non-increasing (sorted) array.

Algorithm

  • Initialize maxDistance = 0.
  • Iterate i from 0 to nums1.length - 1.
  • For each i, perform a binary search on nums2 in the range [i, nums2.length - 1] for the value nums1[i].
  • The goal of the binary search is to find the largest index j such that nums2[j] >= nums1[i].
  • Let this index be found_j.
  • If a valid found_j exists (i.e., it's not -1), update maxDistance = max(maxDistance, found_j - i).
  • Return maxDistance.

Walkthrough

We can optimize the inner loop of the brute-force approach. For a fixed i, we want to find the largest j such that j >= i and nums2[j] >= nums1[i]. Since nums2 is non-increasing, the values nums2[j] that are greater than or equal to nums1[i] will appear at the beginning of the array. We can use binary search to efficiently find the rightmost index j that satisfies this condition.

For each i from 0 to nums1.length - 1, we perform a binary search on the subarray nums2 starting from index i. The search aims to find the largest j where nums2[j] >= nums1[i]. If such a j is found, we calculate j - i and update our maxDistance.

class Solution {    public int maxDistance(int[] nums1, int[] nums2) {        int maxDistance = 0;        int n = nums1.length;        int m = nums2.length;        for (int i = 0; i < n; i++) {            // Binary search for the largest j >= i with nums2[j] >= nums1[i]            int low = i;            int high = m - 1;            int best_j = -1;                        while (low <= high) {                int mid = low + (high - low) / 2;                if (nums2[mid] >= nums1[i]) {                    // This is a potential answer, try to find a larger j                    best_j = mid;                    low = mid + 1;                } else {                    // nums2[mid] is too small, need to search in the left part                    high = mid - 1;                }            }                        if (best_j != -1) {                maxDistance = Math.max(maxDistance, best_j - i);            }        }        return maxDistance;    }}

Complexity

Time

O(N * log M), where N is the length of `nums1` and M is the length of `nums2`. The outer loop runs N times, and each binary search takes O(log M) time.

Space

O(1), as we only use a few variables for the loops and binary search.

Trade-offs

Pros

  • Significantly faster than the brute-force approach.

  • Passes the time limits for the given constraints.

Cons

  • More complex to implement correctly than the brute-force approach.

  • Not as efficient as the optimal two-pointer solution.

Solutions

/** * @param {number[]} nums1 * @param {number[]} nums2 * @return {number} */ var maxDistance =  function (nums1, nums2) {    let ans = 0;    let m = nums1.length;    let n = nums2.length;    for (let i = 0; i < m; ++i) {      let left = i;      let right = n - 1;      while (left < right) {        const mid = (left + right + 1) >> 1;        if (nums2[mid] >= nums1[i]) {          left = mid;        } else {          right = mid - 1;        }      }      ans = Math.max(ans, left - i);    }    return ans;  };

Video walkthrough

Newsletter

One sharp idea, every week

System design and interview prep — short enough to finish.

No spam. Unsubscribe anytime.

Practice

Same difficulty — related problems to reinforce the pattern.