-
Notifications
You must be signed in to change notification settings - Fork 23
/
Count of Smaller Number before itself.java
executable file
·127 lines (109 loc) · 3.79 KB
/
Count of Smaller Number before itself.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
H
与Count of Smaller Number非常类似。以实际的value来构成segment tree,leaf上存(count of smaller number)。
Trick: 先Query,再modify.
每次Query时候,A[i]都还没有加入到Segment Tree 里面,而A[i+1,...etc]自然也还没有加进去。
那么就自然是coutning smaller number before itself.
刁钻啊!
另外注意:
在modify里面:多Check了root.start <= index 和 index <= root.end。 过去都忽略了。以后可以把这个也写上。
(其实是Make sense的,就是更加严格地check了index再 root.left 或者 root.right里面的站位)
```
/*
Give you an integer array (index from 0 to n-1, where n is the size of this array, value from 0 to 10000) .
For each element Ai in the array, count the number of element before this element Ai is smaller than
it and return count number array.
Example
For array [1,2,7,8,5], return [0,1,2,3,2]
Note
We suggest you finish problem Segment Tree Build, Segment Tree Query II and
Count of Smaller Number before itself I first.
Tags Expand
LintCode Copyright Binary Tree Segment Tree
*/
/*
Thoughts:
Just like Count of Smaller Number (in all given array A):
Create segment tree on index (0 ~ 10000)
Modify it to store count of equal or smaller numbers comparing to itself.
However, do query on every A[i] before calling 'modify'!!!!This is the trick.
Every time, before adding a new count information into the tree, do a query and return result. This way, it's always checking numbers before itself.
*/
public class Solution {
public class SegmentTreeNode {
public int start,end;
public int count;
public SegmentTreeNode left, right;
public SegmentTreeNode(int start, int end) {
this.start = start;
this.end = end;
this.count = 0;
this.left = null;
this.right = null;
}
}
/* Build a empty segment tree based on index*/
public SegmentTreeNode build(int start, int end) {
if (start > end) {
return null;
}
if (start == end) {
return new SegmentTreeNode(start, end);
}
SegmentTreeNode root = new SegmentTreeNode(start, end);
int mid = start + (end - start) / 2;
root.left = build(start, mid);
root.right = build(mid + 1, end);
return root;
}
/* Update the tree with 'count': from bottom to this specific tree node, how many integers do we have.*/
public void modify(SegmentTreeNode root, int index, int count){
if (root.start == index && root.end == index) {
root.count += count;
return;
}
int mid = root.start + (root.end - root.start)/2;
if (root.start <= index && index <= mid) {
modify(root.left, index, count);
}
if (mid < index && index <= root.end) {
modify(root.right, index, count);
}
root.count = root.left.count + root.right.count;
}
/* Look for that number based on start&&end*/
public int query(SegmentTreeNode root, int start, int end) {
if (root.start == start && root.end == end) {
return root.count;
}
int sum = 0;
int mid = root.start + (root.end - root.start)/2;
if (end <= mid) {
sum += query(root.left, start, end);
} else if (start > mid) {
sum += query(root.right, start, end);
} else if (start <= mid && mid < end) {
sum += query(root.left, start, mid);
sum += query(root.right, mid + 1, end);
}
return sum;
}
/**
* @param A: An integer array
* @return: Count the number of element before this element 'ai' is
* smaller than it and return count number array
*/
public ArrayList<Integer> countOfSmallerNumberII(int[] A) {
ArrayList<Integer> rst = new ArrayList<Integer>();
SegmentTreeNode root = build(0, 10000);
for (int i = 0; i < A.length; i++) {
int count = 0;
if (A[i] > 0) {
count = query(root, 0, A[i] - 1);
}
rst.add(count);
modify(root, A[i], 1);
}
return rst;
}
}
```