Advertisement
exmkg

Untitled

Dec 16th, 2024
37
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.09 KB | None | 0 0
  1. class Solution {
  2.     public List<Integer> countSmaller(int[] nums) {
  3.         int n = nums.length;
  4.  
  5.         // arr[0..n-1] = pairs (nums[i], i)
  6.         int[][] arr = new int[n][2];
  7.         for (int i = 0; i < n; i++) {
  8.             arr[i][0] = nums[i];
  9.             arr[i][1] = i; // original index
  10.         }
  11.  
  12.         // results[i] = count of smaller numbers a[j] after a[i] (j > i)
  13.         List<Integer> results = new ArrayList<>();
  14.         for (int i = 0; i < n; i++) results.add(0);
  15.  
  16.         mergeSort(arr, 0, nums.length - 1, results);
  17.         return results;
  18.     }
  19.  
  20.     public static void mergeSort(int[][] arr, int left, int right, List<Integer> results) {
  21.         // If the subarray has only one element,
  22.         // it doesn't have any inversions within it.
  23.         if (left == right) return;
  24.        
  25.         int mid = (left + right) / 2;
  26.  
  27.         // Count all inversions such that the first element
  28.         // is in the left half [left; mid] and the second is, too.
  29.         mergeSort(arr, left, mid, results);
  30.  
  31.         // Count all inversions such that the first element
  32.         // is in the right half [mid + 1; right] and the second is, too.
  33.         mergeSort(arr, mid + 1, right, results);
  34.  
  35.         // Count all inversions such that the first element
  36.         // is in the left half [left; mid] and the second
  37.         // is in the right half [mid + 1; right].
  38.         mergeSortedArrays(arr, left, right, results);
  39.     }
  40.  
  41.     public static void mergeSortedArrays(int[][] arr, int left, int right, List<Integer> results) {
  42.         int len = right - left + 1;
  43.  
  44.         int[][] tmp = new int[len][2];  
  45.         int[] updates = new int[len];
  46.  
  47.         int mid = (left + right) / 2;
  48.         for (int k = 0, i = left, j = mid + 1; k < len; k++) {
  49.             if (i > mid) tmp[k] = arr[j++];
  50.             else if (j > right) tmp[k] = arr[i++];
  51.             else if (arr[i][0] <= arr[j][0]) tmp[k] = arr[i++];
  52.             else {
  53.                 tmp[k] = arr[j++];
  54.                 // Elements at indices [i; mid] from the left half
  55.                 // are forming inversions with the element at index j
  56.                 // in the right half, e.g. (arr[i][0], arr[j][0]) is an inversion,
  57.                 // (arr[i + 1][0], arr[j][0]) is an inversion, ...,
  58.                 // (arr[mid][0], arr[j][0]) is an inversion.
  59.                 // Hence, +1 needs to be added to results[arr[i][1]],
  60.                 // results[arr[i + 1][1]], ..., results[arr[mid][1]].
  61.                 // We put this +1 update for further computation into 'updates'.
  62.                 updates[i - left] += 1;
  63.             }
  64.         }
  65.  
  66.         int cumulative_updates = 0;
  67.         for (int k = 0, i = left; i <= mid; k++, i++) { // iterate over the left half
  68.             // compute cumulative update for each index arr[i][1]
  69.             cumulative_updates += updates[k];
  70.  
  71.             // add the cumulative update to results[arr[i][1]]
  72.             results.set(arr[i][1], results.get(arr[i][1]) + cumulative_updates);
  73.         }
  74.  
  75.         for (int k = 0, i = left; k < len; k++, i++) {
  76.             arr[i] = tmp[k];
  77.         }
  78.     }
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement