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 }

类似Reverse Pairs.

posted @ 2016-03-23 05:36  Dylan_Java_NYC  阅读(556)  评论(0编辑  收藏  举报