315. Count of Smaller Numbers After Self
You are given an integer array nums and you have to return a new counts array.
The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. Example: Given nums = [5, 2, 6, 1] To the right of 5 there are 2 smaller elements (2 and 1). To the right of 2 there is only 1 smaller element (1). To the right of 6 there is 1 smaller element (1). To the right of 1 there is 0 smaller element. Return the array [2, 1, 1, 0].
bst: 加count记住遍历过得点有几个点比当前的点小(作为当前节点的左子树的节点数), 返回右父节点的所有count 和, 向左遍历(想好建好树后最后的点向哪遍历, 向左遍历, 第一个点就遍历了右边的所有的节点)
Time: O(NlogN), space: O(N) better than naive solution O(N^2)
public class Solution { private class TreeNode { public int val; public int count = 1; public TreeNode left, right; public TreeNode(int val) { this.val = val; } } public List<Integer> countSmaller(int[] nums) { List<Integer> res = new ArrayList<>(); if(nums == null || nums.length == 0) { return res; } TreeNode root = new TreeNode(nums[nums.length - 1]); res.add(0); for(int i = nums.length - 2; i >= 0; i--) { int count = addNode(root, nums[i]); res.add(count); } Collections.reverse(res); return res; } private int addNode(TreeNode root, int val) { int curCount = 0; while(true) { if(val <= root.val) { root.count++; // add the inversion count if(root.left == null) { root.left = new TreeNode(val); break; } else { root = root.left; } } else { curCount += root.count; if(root.right == null) { root.right = new TreeNode(val); break; } else { root = root.right; } } } return curCount; } }
Merge sort: 老难了, 还是用bst吧
public class Solution { int[] count;// 记录坐标的count //记录排序后的坐标, 就是nums[index[i]] 为排序后的值 public List<Integer> countSmaller(int[] nums) { List<Integer> ans = new ArrayList<>(); if (nums == null || nums.length == 0) { return ans; } count = new int[nums.length]; int[] index = new int[nums.length]; for (int i = 0; i < nums.length; i++) { index[i] = i; } mergSort(nums, 0, nums.length - 1, index); for (int i = 0; i < nums.length; i++) { ans.add(count[i]); } return ans; } private void mergSort(int[] nums, int start, int end, int[] index) { if (end <= start) return; int mid = start + (end - start) / 2; mergSort(nums, start, mid, index); mergSort(nums, mid + 1, end, index); merg(nums, start, end, index); } private void merg(int[] nums, int start, int end, int[] index) { int mid = start + (end - start) / 2; int left = start, right = mid + 1, newStart = 0, sum = 0; int[] newIndex = new int[end - start + 1]; // 对坐标排序 while (left <= mid && right <= end) { if (nums[index[right]] < nums[index[left]]) { sum++; newIndex[newStart++] = index[right++]; } else { count[index[left]] += sum; newIndex[newStart++] = index[left++]; } } while (left <= mid) { count[index[left]] += sum; newIndex[newStart++] = index[left++]; } while (right <= end) { newIndex[newStart++] = index[right++]; } for (int i = start; i <= end; i++) { index[i] = newIndex[i - start]; } } }