- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 55 lines of Java from the credited upstream file 315-4.java.
- The implementation visibly relies on sequence storage.
- 4 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public List<Integer> countSmaller(int[] nums) {3 final int n = nums.length;4 int[] ans = new int[n];5 Item[] items = new Item[n];6 7 for (int i = 0; i < n; ++i)8 items[i] = new Item(nums[i], i);9 10 mergeSort(items, 0, n - 1, ans);11 return Arrays.stream(ans).boxed().collect(Collectors.toList());12 }13 14 private record Item(int num, int index) {}15 16 private void mergeSort(Item[] items, int l, int r, int[] ans) {17 if (l >= r)18 return;19 20 final int m = (l + r) / 2;21 mergeSort(items, l, m, ans);22 mergeSort(items, m + 1, r, ans);23 merge(items, l, m, r, ans);24 }25 26 private void merge(Item[] items, int l, int m, int r, int[] ans) {27 Item[] sorted = new Item[r - l + 1];28 int k = 0; 29 int i = l; 30 int j = m + 1; 31 int rightCount = 0; 32 33 while (i <= m && j <= r)34 if (items[i].num > items[j].num) {35 ++rightCount;36 sorted[k++] = items[j++];37 } else {38 ans[items[i].index] += rightCount;39 sorted[k++] = items[i++];40 }41 42 43 while (i <= m) {44 ans[items[i].index] += rightCount;45 sorted[k++] = items[i++];46 }47 48 49 while (j <= r)50 sorted[k++] = items[j++];51 52 System.arraycopy(sorted, 0, items, l, sorted.length);53 }54}55