Welcome to Subscribe On Youtube

2613. Beautiful Pairs

Description

You are given two 0-indexed integer arrays nums1 and nums2 of the same length. A pair of indices (i,j) is called beautiful if|nums1[i] - nums1[j]| + |nums2[i] - nums2[j]| is the smallest amongst all possible indices pairs where i < j.

Return the beautiful pair. In the case that there are multiple beautiful pairs, return the lexicographically smallest pair.

Note that

  • |x| denotes the absolute value of x.
  • A pair of indices (i1, j1) is lexicographically smaller than (i2, j2) if i1 < i2 or i1 == i2 and j1 < j2.

 

Example 1:

Input: nums1 = [1,2,3,2,4], nums2 = [2,3,1,2,3]
Output: [0,3]
Explanation: Consider index 0 and index 3. The value of |nums1[i]-nums1[j]| + |nums2[i]-nums2[j]| is 1, which is the smallest value we can achieve.

Example 2:

Input: nums1 = [1,2,4,3,2,5], nums2 = [1,4,2,3,5,1]
Output: [1,4]
Explanation: Consider index 1 and index 4. The value of |nums1[i]-nums1[j]| + |nums2[i]-nums2[j]| is 1, which is the smallest value we can achieve.

 

Constraints:

  • 2 <= nums1.length, nums2.length <= 105
  • nums1.length == nums2.length
  • 0 <= nums1i <= nums1.length
  • 0 <= nums2i <= nums2.length

Solutions

  • class Solution {
        private List<int[]> points = new ArrayList<>();
    
        public int[] beautifulPair(int[] nums1, int[] nums2) {
            int n = nums1.length;
            Map<Long, List<Integer>> pl = new HashMap<>();
            for (int i = 0; i < n; ++i) {
                long z = f(nums1[i], nums2[i]);
                pl.computeIfAbsent(z, k -> new ArrayList<>()).add(i);
            }
            for (int i = 0; i < n; ++i) {
                long z = f(nums1[i], nums2[i]);
                if (pl.get(z).size() > 1) {
                    return new int[] {i, pl.get(z).get(1)};
                }
                points.add(new int[] {nums1[i], nums2[i], i});
            }
            points.sort((a, b) -> a[0] - b[0]);
            int[] ans = dfs(0, points.size() - 1);
            return new int[] {ans[1], ans[2]};
        }
    
        private long f(int x, int y) {
            return x * 100000L + y;
        }
    
        private int dist(int x1, int y1, int x2, int y2) {
            return Math.abs(x1 - x2) + Math.abs(y1 - y2);
        }
    
        private int[] dfs(int l, int r) {
            if (l >= r) {
                return new int[] {1 << 30, -1, -1};
            }
            int m = (l + r) >> 1;
            int x = points.get(m)[0];
            int[] t1 = dfs(l, m);
            int[] t2 = dfs(m + 1, r);
            if (t1[0] > t2[0]
                || (t1[0] == t2[0] && (t1[1] > t2[1] || (t1[1] == t2[1] && t1[2] > t2[2])))) {
                t1 = t2;
            }
            List<int[]> t = new ArrayList<>();
            for (int i = l; i <= r; ++i) {
                if (Math.abs(points.get(i)[0] - x) <= t1[0]) {
                    t.add(points.get(i));
                }
            }
            t.sort((a, b) -> a[1] - b[1]);
            for (int i = 0; i < t.size(); ++i) {
                for (int j = i + 1; j < t.size(); ++j) {
                    if (t.get(j)[1] - t.get(i)[1] > t1[0]) {
                        break;
                    }
                    int pi = Math.min(t.get(i)[2], t.get(j)[2]);
                    int pj = Math.max(t.get(i)[2], t.get(j)[2]);
                    int d = dist(t.get(i)[0], t.get(i)[1], t.get(j)[0], t.get(j)[1]);
                    if (d < t1[0] || (d == t1[0] && (pi < t1[1] || (pi == t1[1] && pj < t1[2])))) {
                        t1 = new int[] {d, pi, pj};
                    }
                }
            }
            return t1;
        }
    }
    
  • class Solution {
    public:
        vector<int> beautifulPair(vector<int>& nums1, vector<int>& nums2) {
            int n = nums1.size();
            unordered_map<long long, vector<int>> pl;
            for (int i = 0; i < n; ++i) {
                pl[f(nums1[i], nums2[i])].push_back(i);
            }
            vector<tuple<int, int, int>> points;
            for (int i = 0; i < n; ++i) {
                long long z = f(nums1[i], nums2[i]);
                if (pl[z].size() > 1) {
                    return {i, pl[z][1]};
                }
                points.emplace_back(nums1[i], nums2[i], i);
            }
    
            function<tuple<int, int, int>(int, int)> dfs = [&](int l, int r) -> tuple<int, int, int> {
                if (l >= r) {
                    return {1 << 30, -1, -1};
                }
                int m = (l + r) >> 1;
                int x = get<0>(points[m]);
                auto t1 = dfs(l, m);
                auto t2 = dfs(m + 1, r);
                if (get<0>(t1) > get<0>(t2) || (get<0>(t1) == get<0>(t2) && (get<1>(t1) > get<1>(t2) || (get<1>(t1) == get<1>(t2) && get<2>(t1) > get<2>(t2))))) {
                    swap(t1, t2);
                }
                vector<tuple<int, int, int>> t;
                for (int i = l; i <= r; ++i) {
                    if (abs(get<0>(points[i]) - x) <= get<0>(t1)) {
                        t.emplace_back(points[i]);
                    }
                }
                sort(t.begin(), t.end(), [](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {
                    return get<1>(a) < get<1>(b);
                });
                for (int i = 0; i < t.size(); ++i) {
                    for (int j = i + 1; j < t.size(); ++j) {
                        if (get<1>(t[j]) - get<1>(t[i]) > get<0>(t1)) {
                            break;
                        }
                        int pi = min(get<2>(t[i]), get<2>(t[j]));
                        int pj = max(get<2>(t[i]), get<2>(t[j]));
                        int d = dist(get<0>(t[i]), get<1>(t[i]), get<0>(t[j]), get<1>(t[j]));
                        if (d < get<0>(t1) || (d == get<0>(t1) && (pi < get<1>(t1) || (pi == get<1>(t1) && pj < get<2>(t1))))) {
                            t1 = {d, pi, pj};
                        }
                    }
                }
                return t1;
            };
    
            sort(points.begin(), points.end());
            auto [_, pi, pj] = dfs(0, points.size() - 1);
            return {pi, pj};
        }
    
        long long f(int x, int y) {
            return x * 100000LL + y;
        }
    
        int dist(int x1, int y1, int x2, int y2) {
            return abs(x1 - x2) + abs(y1 - y2);
        }
    };
    
  • class Solution:
        def beautifulPair(self, nums1: List[int], nums2: List[int]) -> List[int]:
            def dist(x1: int, y1: int, x2: int, y2: int) -> int:
                return abs(x1 - x2) + abs(y1 - y2)
    
            def dfs(l: int, r: int):
                if l >= r:
                    return inf, -1, -1
                m = (l + r) >> 1
                x = points[m][0]
                d1, pi1, pj1 = dfs(l, m)
                d2, pi2, pj2 = dfs(m + 1, r)
                if d1 > d2 or (d1 == d2 and (pi1 > pi2 or (pi1 == pi2 and pj1 > pj2))):
                    d1, pi1, pj1 = d2, pi2, pj2
                t = [p for p in points[l : r + 1] if abs(p[0] - x) <= d1]
                t.sort(key=lambda x: x[1])
                for i in range(len(t)):
                    for j in range(i + 1, len(t)):
                        if t[j][1] - t[i][1] > d1:
                            break
                        pi, pj = sorted([t[i][2], t[j][2]])
                        d = dist(t[i][0], t[i][1], t[j][0], t[j][1])
                        if d < d1 or (d == d1 and (pi < pi1 or (pi == pi1 and pj < pj1))):
                            d1, pi1, pj1 = d, pi, pj
                return d1, pi1, pj1
    
            pl = defaultdict(list)
            for i, (x, y) in enumerate(zip(nums1, nums2)):
                pl[(x, y)].append(i)
            points = []
            for i, (x, y) in enumerate(zip(nums1, nums2)):
                if len(pl[(x, y)]) > 1:
                    return [i, pl[(x, y)][1]]
                points.append((x, y, i))
            points.sort()
            _, pi, pj = dfs(0, len(points) - 1)
            return [pi, pj]
    
    
  • func beautifulPair(nums1 []int, nums2 []int) []int {
    	n := len(nums1)
    	pl := map[[2]int][]int{}
    	for i := 0; i < n; i++ {
    		k := [2]int{nums1[i], nums2[i]}
    		pl[k] = append(pl[k], i)
    	}
    	points := [][3]int{}
    	for i := 0; i < n; i++ {
    		k := [2]int{nums2[i], nums1[i]}
    		if len(pl[k]) > 1 {
    			return []int{pl[k][0], pl[k][1]}
    		}
    		points = append(points, [3]int{nums1[i], nums2[i], i})
    	}
    	sort.Slice(points, func(i, j int) bool { return points[i][0] < points[j][0] })
    
    	var dfs func(l, r int) [3]int
    	dfs = func(l, r int) [3]int {
    		if l >= r {
    			return [3]int{1 << 30, -1, -1}
    		}
    		m := (l + r) >> 1
    		x := points[m][0]
    		t1 := dfs(l, m)
    		t2 := dfs(m+1, r)
    		if t1[0] > t2[0] || (t1[0] == t2[0] && (t1[1] > t2[1] || (t1[1] == t2[1] && t1[2] > t2[2]))) {
    			t1 = t2
    		}
    		t := [][3]int{}
    		for i := l; i <= r; i++ {
    			if abs(points[i][0]-x) <= t1[0] {
    				t = append(t, points[i])
    			}
    		}
    		sort.Slice(t, func(i, j int) bool { return t[i][1] < t[j][1] })
    		for i := 0; i < len(t); i++ {
    			for j := i + 1; j < len(t); j++ {
    				if t[j][1]-t[i][1] > t1[0] {
    					break
    				}
    				pi := min(t[i][2], t[j][2])
    				pj := max(t[i][2], t[j][2])
    				d := dist(t[i][0], t[i][1], t[j][0], t[j][1])
    				if d < t1[0] || (d == t1[0] && (pi < t1[1] || (pi == t1[1] && pj < t1[2]))) {
    					t1 = [3]int{d, pi, pj}
    				}
    			}
    		}
    		return t1
    	}
    	ans := dfs(0, n-1)
    	return []int{ans[1], ans[2]}
    }
    
    func dist(x1, y1, x2, y2 int) int {
    	return abs(x1-x2) + abs(y1-y2)
    }
    
    func min(a, b int) int {
    	if a < b {
    		return a
    	}
    	return b
    }
    
    func max(a, b int) int {
    	if a > b {
    		return a
    	}
    	return b
    }
    
    func abs(x int) int {
    	if x < 0 {
    		return -x
    	}
    	return x
    }
    
  • function beautifulPair(nums1: number[], nums2: number[]): number[] {
        const pl: Map<number, number[]> = new Map();
        const n = nums1.length;
        for (let i = 0; i < n; ++i) {
            const z = f(nums1[i], nums2[i]);
            if (!pl.has(z)) {
                pl.set(z, []);
            }
            pl.get(z)!.push(i);
        }
        const points: number[][] = [];
        for (let i = 0; i < n; ++i) {
            const z = f(nums1[i], nums2[i]);
            if (pl.get(z)!.length > 1) {
                return [i, pl.get(z)![1]];
            }
            points.push([nums1[i], nums2[i], i]);
        }
        points.sort((a, b) => a[0] - b[0]);
    
        const dfs = (l: number, r: number): number[] => {
            if (l >= r) {
                return [1 << 30, -1, -1];
            }
            const m = (l + r) >> 1;
            const x = points[m][0];
            let t1 = dfs(l, m);
            let t2 = dfs(m + 1, r);
            if (
                t1[0] > t2[0] ||
                (t1[0] == t2[0] &&
                    (t1[1] > t2[1] || (t1[1] == t2[1] && t1[2] > t2[2])))
            ) {
                t1 = t2;
            }
            const t: number[][] = [];
            for (let i = l; i <= r; ++i) {
                if (Math.abs(points[i][0] - x) <= t1[0]) {
                    t.push(points[i]);
                }
            }
            t.sort((a, b) => a[1] - b[1]);
            for (let i = 0; i < t.length; ++i) {
                for (let j = i + 1; j < t.length; ++j) {
                    if (t[j][1] - t[i][1] > t1[0]) {
                        break;
                    }
                    const pi = Math.min(t[i][2], t[j][2]);
                    const pj = Math.max(t[i][2], t[j][2]);
                    const d = dist(t[i][0], t[i][1], t[j][0], t[j][1]);
                    if (
                        d < t1[0] ||
                        (d == t1[0] && (pi < t1[1] || (pi == t1[1] && pj < t1[2])))
                    ) {
                        t1 = [d, pi, pj];
                    }
                }
            }
            return t1;
        };
        return dfs(0, n - 1).slice(1);
    }
    
    function dist(x1: number, y1: number, x2: number, y2: number): number {
        return Math.abs(x1 - x2) + Math.abs(y1 - y2);
    }
    
    function f(x: number, y: number): number {
        return x * 100000 + y;
    }
    
    

All Problems

All Solutions