Make Lexicographically Smallest Array by Swapping Elements - Complete Solution Guide
Make Lexicographically Smallest Array by Swapping Elements is LeetCode problem 2948, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
You are given a 0-indexed array of positive integers nums and a positive integer limit . In one operation, you can choose any two indices i and j and swap nums[i] and nums[j] if |nums[i] - nums[j]| <= limit . Return the lexicographically smallest array that can be obtained by performing the operation any number of times . An array a is lexicographically smaller than an array b if in the first position where a and b differ, array a has an element that is less than the corresponding element in b .
Detailed Explanation
The problem asks us to find the lexicographically smallest array that can be obtained from a given array `nums` by swapping elements. The constraint is that we can only swap two elements `nums[i]` and `nums[j]` if their absolute difference `|nums[i] - nums[j]|` is less than or equal to a given `limit`. The goal is to perform these swaps as many times as needed to achieve the smallest possible array in lexicographical order.
Solution Approach
The provided solution identifies connected components within the array. Two indices `i` and `j` are in the same component if `|nums[i] - nums[j]| <= limit`. Once identified, the elements within each component are sorted. Then, the sorted elements are placed back into their original positions within their respective components, resulting in the lexicographically smallest array.
Step-by-Step Algorithm
- Step 1: Create pairs of (value, index) from the input array `nums` and store them in a list/vector. This preserves the original indices of the elements.
- Step 2: Sort the pairs based on their values (the first element of the pair). This allows us to easily identify elements that are close enough to be swapped.
- Step 3: Iterate through the sorted pairs to identify connected components. A new component starts at the current index `i`. While subsequent elements `j` are within the `limit` difference from the previous element, they belong to the same component.
- Step 4: For each identified component, extract the original indices of the elements belonging to the component.
- Step 5: Sort these indices to maintain the original order within each component. This will enable placement of the sorted values to the correct location in the result array
- Step 6: Assign the sorted values from the sorted pairs to their corresponding positions (original indices) in the result array.
- Step 7: Advance the main loop counter `i` to the end of the current component and repeat steps 3-6 until all elements are processed.
- Step 8: Return the result array, which now contains the lexicographically smallest arrangement.
Key Insights
- Insight 1: Elements within the same connected component (where elements can be swapped amongst each other) can be rearranged freely to achieve the lexicographically smallest order within that component.
- Insight 2: Sorting the elements within each connected component and then placing them back into their original positions within the component results in the lexicographically smallest arrangement for that component.
- Insight 3: Identifying the connected components is key. Two elements belong to the same component if there exists a path of swappable elements between them (i.e., their absolute difference, or the absolute difference of elements they are connected to, is within the limit).
Complexity Analysis
Time Complexity: O(n log n)
Space Complexity: O(n)
Topics
This problem involves: Array, Union Find, Sorting.
Companies
Asked at: Atlassian, PhonePe.