Skip to content

Commit e71f5df

Browse files
authored
Update longest-increasing-subsequence.cpp
1 parent edf426c commit e71f5df

File tree

1 file changed

+66
-9
lines changed

1 file changed

+66
-9
lines changed

C++/longest-increasing-subsequence.cpp

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,78 @@ class Solution2 {
6767

6868
// Time: O(nlogn)
6969
// Space: O(n)
70-
// optimized from Solution4
70+
// bit, fenwick tree
7171
class Solution3 {
7272
public:
7373
int lengthOfLIS(vector<int>& nums) {
7474
set<int> sorted_nums(cbegin(nums), cend(nums));
75-
unordered_map<int, int> lookup;
75+
unordered_map<int, int> val_to_idx;
7676
for (const auto& num : sorted_nums) {
77-
lookup[num] = size(lookup);
77+
val_to_idx[num] = size(val_to_idx);
7878
}
79-
SegmentTree segment_tree(size(lookup));
80-
for (const auto& num : nums) {
81-
segment_tree.update(lookup[num], lookup[num],
82-
(lookup[num] >= 1) ? segment_tree.query(0, lookup[num] - 1) + 1 : 1);
79+
const auto& fn = [](const auto& a, const auto& b) {
80+
return max(a, b);
81+
};
82+
83+
BIT<int> bit(size(val_to_idx), 0, fn);
84+
for (const auto& x : nums) {
85+
bit.update(val_to_idx[x], bit.query(val_to_idx[x] - 1) + 1);
86+
}
87+
return bit.query(size(val_to_idx) - 1);
88+
}
89+
90+
private:
91+
template<typename T>
92+
class BIT {
93+
public:
94+
BIT(int n, T val, const function<T (T, T)> fn)
95+
: bit_(n + 1, val),
96+
fn_(fn) { // 0-indexed
97+
}
98+
99+
void update(int i, T val) {
100+
++i;
101+
for (; i < size(bit_); i += lower_bit(i)) {
102+
bit_[i] = fn_(bit_[i], val);
103+
}
104+
}
105+
106+
T query(int i) const {
107+
++i;
108+
auto total = bit_[0];
109+
for (; i > 0; i -= lower_bit(i)) {
110+
total = fn_(total, bit_[i]);
111+
}
112+
return total;
113+
}
114+
115+
private:
116+
int lower_bit(int i) const {
117+
return i & -i;
83118
}
84-
return (size(lookup) >= 1) ? segment_tree.query(0, size(lookup) - 1) : 0;
119+
120+
vector<T> bit_;
121+
const function<T (T, T)> fn_;
122+
};
123+
};
124+
125+
// Time: O(nlogn)
126+
// Space: O(n)
127+
// optimized from Solution5
128+
class Solution4 {
129+
public:
130+
int lengthOfLIS(vector<int>& nums) {
131+
set<int> sorted_nums(cbegin(nums), cend(nums));
132+
unordered_map<int, int> val_to_idx;
133+
for (const auto& x : sorted_nums) {
134+
val_to_idx[x] = size(val_to_idx);
135+
}
136+
SegmentTree st(size(val_to_idx));
137+
for (const auto& x : nums) {
138+
st.update(val_to_idx[x], val_to_idx[x],
139+
(val_to_idx[x] >= 1) ? st.query(0, val_to_idx[x] - 1) + 1 : 1);
140+
}
141+
return (size(val_to_idx) >= 1) ? st.query(0, size(val_to_idx) - 1) : 0;
85142
}
86143

87144
private:
@@ -164,7 +221,7 @@ class Solution3 {
164221
// Time: O(n^2)
165222
// Space: O(n)
166223
// Traditional DP solution.
167-
class Solution4 {
224+
class Solution5 {
168225
public:
169226
int lengthOfLIS(vector<int>& nums) {
170227
const int n = nums.size();

0 commit comments

Comments
 (0)