LeetCode 315. Count of Smaller Numbers After Self
原题链接在这里:https://leetcode.com/problems/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]
.
题解:
从右向左扫描数组nums, try to find the position of nums[i] in BST.
For each BST node, it contains its left subtree size count, its duplicate count.
When inserting a new node, returns the sum of smaller count.
Time Complexity: O(n^2). BST不一定balance. Space: O(n).
AC Java:
1 class Solution { 2 public List<Integer> countSmaller(int[] nums) { 3 LinkedList<Integer> res = new LinkedList<>(); 4 if(nums == null || nums.length == 0){ 5 return res; 6 } 7 8 int n = nums.length; 9 res.offerFirst(0); 10 TreeNode root = new TreeNode(nums[n - 1]); 11 root.count = 1; 12 13 for(int i = n - 2; i >= 0; i--){ 14 int smallerCount = insert(root, nums[i]); 15 res.offerFirst(smallerCount); 16 } 17 18 return res; 19 } 20 21 private int insert(TreeNode root, int num){ 22 int smallerCountSum = 0; 23 while(root.val != num){ 24 if(root.val > num){ 25 root.leftCount++; 26 if(root.left == null){ 27 root.left = new TreeNode(num); 28 } 29 30 root = root.left; 31 }else{ 32 smallerCountSum += root.leftCount + root.count; 33 if(root.right == null){ 34 root.right = new TreeNode(num); 35 } 36 37 root = root.right; 38 } 39 } 40 41 root.count++; 42 return smallerCountSum + root.leftCount; 43 } 44 } 45 46 class TreeNode{ 47 int val; 48 int count; 49 int leftCount; 50 TreeNode left; 51 TreeNode right; 52 53 public TreeNode(int val){ 54 this.val = val; 55 this.count = 0; 56 this.leftCount = 0; 57 } 58 }
Above solution is TLE since tree is not balanced.
Could use Binary indexed tree.
For each tree node value, it records smaller value count.
Time Complexity: O(nlogn). n = nums.length;
Space: O(n).
AC Java:
1 class Solution { 2 public List<Integer> countSmaller(int[] nums) { 3 LinkedList<Integer> res = new LinkedList<>(); 4 if(nums == null || nums.length == 0){ 5 return res; 6 } 7 8 int offset = 10000; 9 int [] tree = new int[2 * offset + 2]; 10 11 for(int i = nums.length - 1; i >= 0; i--){ 12 res.addFirst(query(tree, nums[i] + offset)); 13 update(tree, nums[i] + offset, 1); 14 } 15 16 return res; 17 } 18 19 private void update(int [] tree, int index, int val){ 20 index++; 21 while(index < tree.length){ 22 tree[index] += val; 23 index += (index & -index); 24 } 25 } 26 27 private int query(int [] tree, int index){ 28 // sum of [0, index) 29 int res = 0; 30 while(index >= 1){ 31 res += tree[index]; 32 index -= (index & -index); 33 } 34 35 return res; 36 } 37 }