Algorithms
  • Introduction
  • Analysis of Algorithms
  • Numbers
    • Reverse Integer
    • Palindroms
      • Valid Palindrome
    • Prime factor
    • Prime Number
    • Roman to Integer
    • Happy Number
    • p^k
  • Searching
    • Union-Find Algorithms
    • Finding Peak
    • Find Sum in Array
    • Binary Search
      • Find Index Binary Search
      • Sqrt(x)
      • Search in Rotated Sorted Array
      • Guess Number Higher or Lower
      • First Bad Version
      • Find Peak Element
      • Find Minimum in Rotated Sorted Array
      • Find Minimum in Rotated Sorted Array II
      • Search for a Range
      • Closest Binary Search Tree Value
      • Find K Closest Elements
      • Search in a Sorted Array of Unknown Size
      • Pow(x, n)
      • Valid Perfect Square
      • Find Minimum in Rotated Sorted Array II
      • Intersection of Two Arrays
      • Intersection of Two Arrays II
      • Two Sum II - Input array is sorted
      • Find the Duplicate Number
    • Longest Common Prefix
  • Sorting
    • Elementary Sorts
    • Insertion Sort
    • Bubble Sort
    • Mergesort
    • Quicksort
    • Radix Sort
    • Heap Sort
  • Data Structures
    • Array & List
      • Find Pivot Index
      • Largest Number At Least Twice of Others
      • Plus One
      • Diagonal Traverse
      • Spiral Matrix
      • Pascal's Triangle
      • Implement strStr()
      • Add Binary
      • Duplicate Counts
      • Find Duplicates
      • Reverse String
      • Array Partition I
      • Two Sum II - Input array is sorted
      • Remove Element
      • Max Consecutive Ones
      • Minimum Size Subarray Sum
      • Reverse Words in a String
      • Reverse Words in a String III
      • Remove Duplicates from Sorted Array
      • Move Zeroes
      • Rotate Array
      • Rotate Image
      • Best Time to Buy and Sell Stock
      • Best Time to Buy and Sell Stock II
      • Valid Anagram
      • 3Sum
      • String to Integer (atoi)
      • Count and Say
      • Merge Sorted Array
      • Shuffle an Array
      • Max Area of Island
    • Matrix
    • Stack
      • Valid Parentheses
      • Min Stack
    • Queue
    • Linked List
      • Design Linked List
      • Design Doubly Linked List
      • Find Middle Element
      • Doubly Linked List
      • Cyclic Linked List
      • Linked List Cycle II
      • Find Nth Element from End
      • Remove Nth Node From End of List
      • Add Two Numbers
      • Merge Two Sorted Lists
      • Remove Nth Node From End of List
      • Reverse Linked List
      • Remove Linked List Elements
      • Odd Even Linked List
      • Design Doubly Linked List
      • Flatten a Multilevel Doubly Linked List
      • Rotate List
      • Copy List with Random Pointer
      • Insert into a Cyclic Sorted List
      • Delete Node in a Linked List
      • Palindrome Linked List
    • Set
      • Intersection of Two Arrays
      • Single Number
      • Contains Duplicate
      • Contains Duplicate II
      • Jewels and Stones
      • Longest Substring Without Repeating Characters
      • Two Sum III - Data structure design
      • Valid Sudoku
      • Missing Number
    • Map
      • Two Sum
      • Isomorphic Strings
      • Minimum Index Sum of Two Lists
      • First Unique Character in a String
      • Intersection of Two Arrays II
      • Logger Rate Limiter
      • Group Anagrams
      • Group Shifted Strings
      • Find Duplicate Subtrees
      • 4Sum II
      • Top K Frequent Elements
      • Unique Word Abbreviation
      • Insert Delete GetRandom O(1)
    • Binary Tree
      • Binary Tree Preorder Traversal
      • Binary Tree Inorder Traversal
      • Binary Tree Postorder Traversal
      • Binary Tree Level Order Traversal
      • Maximum Depth of Binary Tree
      • Symmetric Tree
      • Path Sum
      • Balanced Binary Tree
      • Count Univalue Subtrees
      • Construct Binary Tree from Inorder and Postorder Traversal
      • Construct Binary Tree from Preorder and Inorder Traversal
      • Populating Next Right Pointers in Each Node
      • Lowest Common Ancestor of a Binary Tree
      • Serialize and Deserialize Binary Tree
      • Median of Two Sorted Arrays
      • Invert Binary Tree
      • Find K-th Smallest Pair Distance
      • Split Array Largest Sum
    • Heap
    • Binary Search Tree
      • Validate Binary Search Tree
      • Inorder Successor in BST
      • Binary Search Tree Iterator
      • Search in a Binary Search Tree
      • Insert into a Binary Search Tree
      • Delete Node in a BST
      • Kth Largest Element in a Stream
      • Lowest Common Ancestor of a Binary Search Tree
      • Contains Duplicate III
      • Height-Balanced BST
        • Balanced Binary Tree
        • Convert Sorted Array to Binary Search Tree
    • Map
    • N-ary Tree
      • N-ary Tree Preorder Traversal
      • N-ary Tree Postorder Traversal
      • N-ary Tree Level Order Traversal
      • Maximum Depth of N-ary Tree
      • Encode N-ary Tree to Binary Tree
      • Serialize and Deserialize N-ary Tree
    • Trie
      • Implement Trie (Prefix Tree)
      • Map Sum Pairs
      • Replace Words
      • Design Search Autocomplete System
      • Maximum XOR of Two Numbers in an Array
      • Add and Search Word - Data structure design
      • Word Search II
      • Word Squares
      • Longest Common Prefix
      • Palindrome Pairs
    • Balanced Tree
      • B-Tree
      • Red-black Tree
      • AVL Tree
    • Graph
      • A* Search
      • Breadth First Search
      • Depth First Search
      • Dijkstra Algorithm
  • Sequences
    • Fibonacci Sequence
  • Dynamic Programming
    • Knapsack problem
    • Climbing Stairs
    • Best Time to Buy and Sell Stock
    • Maximum Subarray
    • House Robber
  • Interviews
    • Google Leetcode
      • Repeated String Match
      • K Empty Slots
      • Next Closest Time
      • Longest Univalue Path
      • License Key Formatting
      • Spiral Matrix
      • Plus One
      • Trapping Rain Water
      • Longest Substring with At Most K Distinct Characters
      • Add Bold Tag in String
      • Game of Life
      • Read N Characters Given Read4
      • Read N Characters Given Read4 II - Call multiple times
      • One Edit Distance
      • Valid Palindrome
      • Valid Number
      • Valid Parentheses
      • Image Smoother
      • Intersection of Two Arrays
      • Max Consecutive Ones
      • Max Consecutive Ones II
      • Shortest Palindrome
      • First Missing Positive
      • First Unique Character in a String
      • Move Zeroes
      • Remove Duplicates from Sorted Array
      • Merge k Sorted Lists
      • Insert into a Cyclic Sorted List
      • Evaluate Division
      • Inorder Successor in BST
      • Robot Room Cleaner
      • Redundant Connection II
      • Course Schedule
      • Validate Binary Search Tree
      • Closest Binary Search Tree Value
      • Word Squares
      • Strobogrammatic Number II
      • Word Search II
      • Android Unlock Patterns
      • Minimum Window Substring
      • Kth Largest Element in an Array
      • Shortest Distance from All Buildings
      • Find K-th Smallest Pair Distance
      • Find K Pairs with Smallest Sums
      • Range Module
      • Insert Interval
      • Sort Transformed Array
      • Merge Intervals
      • Longest Palindromic Substring
      • Next Greater Element I
      • Pacific Atlantic Water Flow
      • Evaluate Reverse Polish Notation
      • Decode Ways
      • Word Break
      • Sentence Screen Fitting
      • Maximum Vacation Days
      • Edit Distance
      • Minimum Path Sum
      • House Robber II
      • Moving Average from Data Stream
      • Peeking Iterator
      • Binary Search Tree Iterator
      • Zigzag Iterator
      • Design Tic-Tac-Toe
      • Range Sum Query 2D - Mutable
      • UTF-8 Validation
      • Maximum Product of Word Lengths
  • Other
    • Game of Life
Powered by GitBook
On this page
  • Solution
  • Approach #1: Heap
  • Approach #2: Binary Search + Prefix Sum
  • Approach #3: Binary Search + Sliding Window

Was this helpful?

  1. Data Structures
  2. Binary Tree

Find K-th Smallest Pair Distance

Given an integer array, return the k-th smallestdistanceamong all the pairs. The distance of a pair (A, B) is defined as the absolute difference between A and B.

Example 1:

Input:
nums = [1,3,1]
k = 1
Output: 0 
Explanation:
Here are all the pairs:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
Then the 1st smallest distance pair is (1,1), and its distance is 0.

Solution

Approach #1: Heap

Intuition and Algorithm

Sort the points. For every point with indexi, the pairs with indexes(i, j)[by order of distance] are(i, i+1), (i, i+2), ..., (i, N-1).

Let's keep a heap of pairs, initiallyheap = [(i, i+1) for all i], and ordered by distance (the distance of(i, j)isnums[j] - nums[i].) Whenever we use a pair(i, x)from our heap, we will add(i, x+1)to our heap when appropriate.

Complexity Analysis

  • Time Complexity:O((k+N)logN)O((k+N)logN), whereNNis the length ofnums. Ask=O(N2)k=O(N​2​​), this isO(N2logN)O(N​2​​logN)in the worst case. The complexity added by our heap operations is eitherO((k+N)logN)O((k+N)logN)in the Java solution, orO(klogN+N)O(klogN+N)in the Python solution because theheapq.heapifyoperation is linear time. Additionally, we addO(NlogN)O(NlogN)complexity due to sorting.

  • Space Complexity:O(N)O(N), the space used to store ourheapof at mostN-1elements.

class Solution {
    public int smallestDistancePair(int[] nums, int k) {
        Arrays.sort(nums);
        PriorityQueue<Node> heap = new PriorityQueue<Node>(nums.length,
            Comparator.<Node> comparingInt(node -> nums[node.nei] - nums[node.root]));
        for (int i = 0; i + 1 < nums.length; ++i) {
            heap.offer(new Node(i, i+1));
        }

        Node node = null;
        for (; k > 0; --k) {
            node = heap.poll();
            if (node.nei + 1 < nums.length) {
                heap.offer(new Node(node.root, node.nei + 1));
            }
        }
        return nums[node.nei] - nums[node.root];
    }
}
class Node {
    int root;
    int nei;
    Node(int r, int n) {
        root = r;
        nei = n;
    }
}

Approach #2: Binary Search + Prefix Sum

Intuition

Let's binary search for the answer. It's definitely in the range[0, W], whereW = max(nums) - min(nums)].

Letpossible(guess)be true if and only if there arekor more pairs with distance less than or equal toguess. We will focus on evaluating ourpossiblefunction quickly.

Algorithm

Letprefix[v]be the number of points innumsless than or equal tov. Also, letmultiplicity[j]be the number of pointsiwithi < j and nums[i] == nums[j]. We can record both of these with a simple linear scan.

Now, for every pointi, the number of pointsjwithi < jandnums[j] - nums[i] <= guessisprefix[x+guess] - prefix[x] + (count[i] - multiplicity[i]), wherecount[i]is the number of ocurrences ofnums[i]innums. The sum of this over alliis the number of pairs with distance<= guess.

Finally, because the sum ofcount[i] - multiplicity[i]is the same as the sum ofmultiplicity[i], we could just replace that term withmultiplicity[i]without affecting the answer. (Actually, the sum of multiplicities in total will be a constant used in the answer, so we could precalculate it if we wanted.)

In our Java solution, we computedpossible = count >= kdirectly in the binary search instead of using a helper function.

Complexity Analysis

  • Time Complexity:O(W+NlogW+NlogN)O(W+NlogW+NlogN), whereNNis the length ofnums, andWWis equal tonums[nums.length - 1] - nums[0]. We doO(W)O(W)work to calculateprefixinitially. ThelogWlogWfactor comes from our binary search, and we doO(N)O(N)work inside our call topossible(or to calculatecountin Java). The finalO(NlogN)O(NlogN)factor comes from sorting.

  • Space Complexity:O(N+W)O(N+W), the space used to storemultiplicityandprefix.

class Solution {
    public int smallestDistancePair(int[] nums, int k) {
        Arrays.sort(nums);
        int WIDTH = 2 * nums[nums.length - 1];

        //multiplicity[i] = number of nums[j] == nums[i] (j < i)
        int[] multiplicity = new int[nums.length];
        for (int i = 1; i < nums.length; ++i) {
            if (nums[i] == nums[i-1]) {
                multiplicity[i] = 1 + multiplicity[i - 1];
            }
        }

        //prefix[v] = number of values <= v
        int[] prefix = new int[WIDTH];
        int left = 0;
        for (int i = 0; i < WIDTH; ++i) {
            while (left < nums.length && nums[left] == i) left++;
            prefix[i] = left;
        }

        int lo = 0;
        int hi = nums[nums.length - 1] - nums[0];
        while (lo < hi) {
            int mi = (lo + hi) / 2;
            int count = 0;
            for (int i = 0; i < nums.length; ++i) {
                count += prefix[nums[i] + mi] - prefix[nums[i]] + multiplicity[i];
            }
            //count = number of pairs with distance <= mi
            if (count >= k) hi = mi;
            else lo = mi + 1;
        }
        return lo;
    }
}

Approach #3: Binary Search + Sliding Window

Intuition

As inApproach #2, let's binary search for the answer, and we will focus on evaluating ourpossiblefunction quickly.

Algorithm

We will use a sliding window approach to count the number of pairs with distance<=guess.

For every possibleright, we maintain the loop invariant:leftis the smallest value such thatnums[right] - nums[left] <= guess. Then, the number of pairs withrightas it's right-most endpoint isright - left, and we add all of these up.

Complexity Analysis

  • Time Complexity:O(NlogW+NlogN)O(NlogW+NlogN), whereNNis the length ofnums, andWWis equal tonums[nums.length - 1] - nums[0]. ThelogWlogWfactor comes from our binary search, and we doO(N)O(N)work inside our call topossible(or to calculatecountin Java). The finalO(NlogN)O(NlogN)factor comes from sorting.

  • Space Complexity:O(1)O(1). No additional space is used except for integer variables.

class Solution {
    public int smallestDistancePair(int[] nums, int k) {
        Arrays.sort(nums);

        int lo = 0;
        int hi = nums[nums.length - 1] - nums[0];
        while (lo < hi) {
            int mi = (lo + hi) / 2;
            int count = 0, left = 0;
            for (int right = 0; right < nums.length; ++right) {
                while (nums[right] - nums[left] > mi)  {
                    left++;
                }
                count += right - left;
            }
            //count = number of pairs with distance <= mi
            if (count >= k) {
                hi = mi;
            } else {
                lo = mi + 1;
            }
        }
        return lo;
    }
}
PreviousInvert Binary TreeNextSplit Array Largest Sum

Last updated 5 years ago

Was this helpful?