UBER Coding Question – Solved

10 Live
Count Swaps During Custom Sorting Analyze the efficiency of the following sorting algorithm by counting the number of swaps it performs: For an array arr of size n: 1. Find the smallest pair of indices 0 ≤ i < j ≤ n-1 such that arr[i] > arr[j], where "smallest" means lexicographical ordering of pairs (i1, j1) < (i2, j2) if i1 < i2 or (i1 = i2 and j1 < j2). 2. If no such pair exists, the algorithm stops. 3. Otherwise, swap arr[i] and arr[j] and search for the next pair. Your task is to determine how many swaps this algorithm performs to sort a given array. Example n = 4, the size of arr arr = [5, 1, 4, 2] The algorithm performs these swaps: [5, 1, 4, 2] → [1, 5, 4, 2] (swap indices 0 and 1) [1, 5, 4, 2] → [1, 4, 5, 2] (swap indices 1 and 2) [1, 4, 5, 2] → [1, 4, 2, 5] (swap indices 2 and 3) [1, 4, 2, 5] → [1, 2, 4, 5] (swap indices 1 and 2) The total number of swaps is 4. Function Description Complete the function howManySwaps in the editor with the following parameter(s): int arr[]: the array to sort Returns int: the number of swaps Constraints 1 ≤ n ≤ 10^5 1 ≤ arr[i] ≤ 10^9 All elements of arr are distinct. Input Format for Custom Testing Sample Case 0 Sample Input arr[] size n = 3 arr = [7, 1, 2] Sample Output 2 Explanation [7, 1, 2] → [1, 7, 2] → [1, 2, 7]

Asked in: UBER

Image of the Question

Question Image Question Image Question Image Question Image

All Testcases Passed ✔



Passcode Image

Solution


#include <vector>
using namespace std;

long countAndMerge(const vector<int>& leftPart, const vector<int>& rightPart, vector<int>& combined) {
// ... rest of solution available after purchase

🔒 Please login to view the solution

Explanation


```
To approach this problem, start by carefully understanding what the sorting algorithm does and how it differs from standard sorting algorithms. The algorithm repeatedly looks for the smallest pair of indices (i, j) with i < j such that arr[i] > arr[j] and swaps these elements. The "smallest pair" means the lexicographically earliest such pair, i.e., the first i for which such a j exists, and then the smallest such j for that i. This process continues until no such pair exists, meaning the array is sorted.

1. **Understanding the Core Mechanism**
The key is that the algorithm finds the first "inversion" in the array from left to right and fixes it by swapping those two elements. An inversion here means a pair (i, j) where i < j and arr[i] > arr[j]. But the algorithm does not just swap adjacent elements like bubble sort; it swaps the first found out-of-order pair anywhere in the array, even if i and j are far apart.

2. **Characterizing the Swaps**
Each swap resolves one inversion, but because it swaps non-adjacent elements, it can affect multiple inversions simultaneously. After the swap, the array is closer to sorted, but not necessarily sorted, so the process repeats.

3. **What is Being Asked?**
The problem asks to count how many swaps this algorithm performs to completely sort the array. It is important to note that all elements are distinct, which simplifies reasoning about inversions.

4. **Relating the Problem to Inversions**
An inversion is a pair of indices where the order is wrong. The total number of inversions in the array is a known measure of how unsorted the array is. A well-known fact is that sorting algorithms like bubble sort or insertion sort perform a number of swaps proportional to the number of inversions. However, this algorithm swaps the "first" inversion found each time and might do fewer or more swaps depending on the strategy.

5. **Key Insight: The Algorithm Fixes the Leftmost Inversion**
Because it always chooses the smallest i such that arr[i] > arr[j], it means the algorithm first addresses inversions starting at the earliest position possible. This suggests a sequential "fixing" of the array from left to right.

6. **How to Model or Simulate the Process?**
Direct simulation by scanning for the smallest inversion repeatedly would be too slow for large n (up to 10^5). You must find a mathematical or algorithmic shortcut.

7. **Think About the Final Sorted Array and Original Positions**
Since all elements are distinct, sorting the array is straightforward. If you record the sorted order, you can relate each element's original position to its position in the sorted array.

8. **Connecting to Inversion Counting Techniques**
The total number of inversions can be counted efficiently using data structures like Fenwick Trees (Binary Indexed Trees) or Balanced Binary Search Trees. However, the number of swaps performed by this algorithm is not necessarily the total number of inversions because the algorithm swaps non-adjacent elements.

9. **Analyzing the Effect of Each Swap**
Each swap exchanges elements at positions i and j, with i < j and arr[i] > arr[j]. After this swap:
- The element previously at arr[i] moves right to position j.
- The element previously at arr[j] moves left to position i.
This swap corrects at least one inversion but can also create or remove other inversions.

10. **Is There a Known Sorting Algorithm Equivalent?**
The described algorithm is reminiscent of selection sort or a variant where the first out-of-order pair is fixed, but instead of selecting the minimal element for each position, it swaps the first inversion found.

11. **Thinking About Minimal Number of Swaps to Sort an Array**
Another perspective is to find the minimal number of swaps needed to sort the array. This minimal number corresponds to decomposing the permutation represented by arr into cycles and counting their lengths.

12. **Key Observation**
The number of swaps performed by the algorithm matches the minimal number of swaps required to sort the array because:
- The algorithm always fixes the earliest inversion, effectively moving the smallest misplaced element towards its correct position.
- Eventually, this corresponds to breaking cycles in the permutation.

13. **How to Count Minimal Swaps to Sort**
The minimal number of swaps needed to sort the array equals n minus the number of cycles in the permutation represented by the original array relative to the sorted array.

14. **Approach to Solution Without Direct Simulation**
- Sort a copy of the array to know the target order.
- Create a mapping from the original array elements to their indices in the sorted array.
- Represent the array as a permutation of indices relative to sorted order.
- Find cycles in this permutation.
- The answer is sum over all cycles of (cycle length - 1), which simplifies to n - number of cycles.

15. **Why This Works**
Each cycle corresponds to a group of elements that need to be rotated among themselves to reach the sorted position. Each cycle of length k requires k-1 swaps. This method yields the minimal number of swaps needed to sort, which matches the count of swaps performed by the algorithm described.

16. **Summary of Thought Process**
Instead of simulating the algorithm directly, which is inefficient for large inputs, understand that the number of swaps performed corresponds exactly to the minimal number of swaps needed to transform the permutation into sorted order. This is a classical problem solvable via cycle detection in permutations.

17. **Final Steps for Implementation**
- Sort the array and map each original element to its sorted position.
- Use a visited array to mark elements already accounted for in cycles.
- For each unvisited element, follow the cycle it forms and count its length.
- Sum up the cycle lengths minus one.
- Return the total sum as the number of swaps.

By focusing on the permutation cycle decomposition and relating it to the minimal number of swaps, you solve the problem efficiently and correctly for large arrays.
```


Related Questions