forked from kamyu104/LintCode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcount-of-smaller-number.cpp
143 lines (121 loc) · 3.85 KB
/
count-of-smaller-number.cpp
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Time: O(logn), per query
// Space: O(h), per query
/**
* Definition of SegmentTreeNode:
* class SegmentTreeNode {
* public:
* int start, end, count;
* SegmentTreeNode *left, *right;
* SegmentTreeNode(int start, int end, int count) {
* this->start = start;
* this->end = end;
* this->count = count;
* this->left = this->right = NULL;
* }
* }
*/
// Segment tree solution.
class Solution {
public:
/**
* @param A: An integer array
* @return: The number of element in the array that
* are smaller that the given integer
*/
vector<int> countOfSmallerNumber(vector<int> &A, vector<int> &queries) {
vector<int> res;
// Sort array before building segment tree.
sort(A.begin(), A.end());
// Build segment tree.
SegmentTreeNode *root = build(A, 0, A.size() - 1);
// Do each query.
for (const auto& q : queries) {
res.emplace_back(query(root, 0, A.size() - 1, A, q));
}
return res;
}
// Build segment tree.
SegmentTreeNode *build(vector<int> &A, int start, int end) {
if (start > end) {
return nullptr;
}
// The root's start and end is given by build method.
SegmentTreeNode *root = new SegmentTreeNode(start, end, 0);
// If start equals to end, there will be no children for this node.
if (start == end) {
root->count = 1;
return root;
}
// Left child: start=A.left, end=(A.left + A.right) / 2.
root->left = build(A, start, (start + end) / 2);
// Right child: start=(A.left + A.right) / 2 + 1, end=A.right.
root->right = build(A, (start + end) / 2 + 1, end);
int left_count = root->left != nullptr? root->left->count : 0;
int right_count = root->right != nullptr? root->right->count : 0;
// Update count.
root->count = left_count + right_count;
return root;
}
// Query count in given range.
int query(SegmentTreeNode *root, int start, int end,
vector<int> &A, int q) {
// Out of range.
if (root == nullptr || root->start > end || root->end < start) {
return 0;
}
// Skip the segment where q is smaller than its start.
if (q <= A[root->start]) {
return 0;
}
// Current segment is totally smaller than q.
if (q > A[root->end]) {
return root->count;
}
int left = query(root->left, start, end, A, q);
int right = query(root->right, start, end, A, q);
// Find count in the children.
return left + right;
}
};
// Time: O(logn)
// Space: O(1)
// Binary search solution.
class Solution2 {
public:
/**
* @param A: An integer array
* @return: The number of element in the array that
* are smaller that the given integer
*/
vector<int> countOfSmallerNumber(vector<int> &A, vector<int> &queries) {
vector<int> result;
sort(A.begin(), A.end());
for (int i = 0; i < queries.size(); ++i) {
const auto it = lower_bound(A.cbegin(), A.cend(), queries[i]);
result.emplace_back(it - A.cbegin());
}
return result;
}
};
// Time: O(n)
// Space: O(1)
// Loop solution.
class Solution_TLE {
public:
/**
* @param A: An integer array
* @return: The number of element in the array that
* are smaller that the given integer
*/
vector<int> countOfSmallerNumber(vector<int> &A, vector<int> &queries) {
vector<int> result(queries.size(), 0);
for (auto& x : A) {
for (int i = 0; i < queries.size(); ++i) {
if (queries[i] > x) {
++result[i];
}
}
}
return result;
}
};