Skip to content

Commit 5392e8c

Browse files
committed
feat: add solutions to lc problem: No.1964
No.1964.Find the Longest Valid Obstacle Course at Each Position
1 parent 10b43c6 commit 5392e8c

File tree

6 files changed

+630
-1
lines changed

6 files changed

+630
-1
lines changed

solution/1900-1999/1964.Find the Longest Valid Obstacle Course at Each Position/README.md

+230-1
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,251 @@
7272

7373
<!-- 这里可写通用的实现逻辑 -->
7474

75+
树状数组。
76+
77+
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
78+
79+
1. **单点更新** `update(x, delta)`: 把序列 x 位置的数加上一个值 delta;
80+
1. **前缀和查询** `query(x)`:查询序列 `[1,...x]` 区间的区间和,即位置 x 的前缀和。
81+
82+
这两个操作的时间复杂度均为 `O(log n)`。当数的范围比较大时,需要进行离散化,即先进行去重并排序,然后对每个数字进行编号。
83+
84+
本题我们使用树状数组来维护以 `tree[x]` 来维护以 x 结尾的最长上升子序列的长度。
85+
86+
```python
87+
def update(x, val):
88+
while x <= n:
89+
c[x] = max(c[x], val)
90+
x += lowbit(x)
91+
92+
93+
def query(x):
94+
s = 0
95+
while x > 0:
96+
s = max(s, c[x])
97+
x -= lowbit(x)
98+
return s
99+
```
100+
75101
<!-- tabs:start -->
76102

77103
### **Python3**
78104

79105
<!-- 这里可写当前语言的特殊实现逻辑 -->
80106

81107
```python
82-
108+
class BinaryIndexedTree:
109+
def __init__(self, n):
110+
self.n = n
111+
self.c = [0] * (n + 1)
112+
113+
@staticmethod
114+
def lowbit(x):
115+
return x & -x
116+
117+
def update(self, x, val):
118+
while x <= self.n:
119+
self.c[x] = max(self.c[x], val)
120+
x += BinaryIndexedTree.lowbit(x)
121+
122+
def query(self, x):
123+
s = 0
124+
while x > 0:
125+
s = max(s, self.c[x])
126+
x -= BinaryIndexedTree.lowbit(x)
127+
return s
128+
129+
130+
class Solution:
131+
def longestObstacleCourseAtEachPosition(self, obstacles: List[int]) -> List[int]:
132+
s = sorted(set(obstacles))
133+
m = {v: i for i, v in enumerate(s, 1)}
134+
tree = BinaryIndexedTree(len(m))
135+
ans = []
136+
for v in obstacles:
137+
x = m[v]
138+
ans.append(1 + tree.query(x))
139+
tree.update(x, ans[-1])
140+
return ans
83141
```
84142

85143
### **Java**
86144

87145
<!-- 这里可写当前语言的特殊实现逻辑 -->
88146

89147
```java
148+
class Solution {
149+
public int[] longestObstacleCourseAtEachPosition(int[] obstacles) {
150+
TreeSet<Integer> ts = new TreeSet();
151+
for (int v : obstacles) {
152+
ts.add(v);
153+
}
154+
int idx = 1;
155+
Map<Integer, Integer> m = new HashMap<>();
156+
for (int v : ts) {
157+
m.put(v, idx++);
158+
}
159+
BinaryIndexedTree tree = new BinaryIndexedTree(m.size());
160+
int n = obstacles.length;
161+
int[] ans = new int[n];
162+
for (int i = 0; i < n; ++i) {
163+
int v = obstacles[i];
164+
int x = m.get(v);
165+
ans[i] = tree.query(x) + 1;
166+
tree.update(x, ans[i]);
167+
}
168+
return ans;
169+
}
170+
}
171+
172+
class BinaryIndexedTree {
173+
private int n;
174+
private int[] c;
175+
176+
public BinaryIndexedTree(int n) {
177+
this.n = n;
178+
c = new int[n + 1];
179+
}
180+
181+
public void update(int x, int val) {
182+
while (x <= n) {
183+
c[x] = Math.max(c[x], val);
184+
x += lowbit(x);
185+
}
186+
}
187+
188+
public int query(int x) {
189+
int s = 0;
190+
while (x > 0) {
191+
s = Math.max(s, c[x]);
192+
x -= lowbit(x);
193+
}
194+
return s;
195+
}
196+
197+
public static int lowbit(int x) {
198+
return x & -x;
199+
}
200+
}
201+
```
202+
203+
### **C++**
204+
205+
```cpp
206+
class BinaryIndexedTree {
207+
public:
208+
int n;
209+
vector<int> c;
210+
211+
BinaryIndexedTree(int _n): n(_n), c(_n + 1){}
212+
213+
void update(int x, int val) {
214+
while (x <= n)
215+
{
216+
c[x] = max(c[x], val);
217+
x += lowbit(x);
218+
}
219+
}
220+
221+
int query(int x) {
222+
int s = 0;
223+
while (x > 0)
224+
{
225+
s = max(s, c[x]);
226+
x -= lowbit(x);
227+
}
228+
return s;
229+
}
230+
231+
int lowbit(int x) {
232+
return x & -x;
233+
}
234+
};
235+
236+
237+
class Solution {
238+
public:
239+
vector<int> longestObstacleCourseAtEachPosition(vector<int>& obstacles) {
240+
set<int> s(obstacles.begin(), obstacles.end());
241+
int idx = 1;
242+
unordered_map<int, int> m;
243+
for (int v : s) m[v] = idx++;
244+
BinaryIndexedTree* tree = new BinaryIndexedTree(m.size());
245+
int n = obstacles.size();
246+
vector<int> ans(n);
247+
for (int i = 0; i < n; ++i)
248+
{
249+
int v = obstacles[i];
250+
int x = m[v];
251+
ans[i] = 1 + tree->query(x);
252+
tree->update(x, ans[i]);
253+
}
254+
return ans;
255+
}
256+
};
257+
```
90258
259+
### **Go**
260+
261+
```go
262+
type BinaryIndexedTree struct {
263+
n int
264+
c []int
265+
}
266+
267+
func newBinaryIndexedTree(n int) *BinaryIndexedTree {
268+
c := make([]int, n+1)
269+
return &BinaryIndexedTree{n, c}
270+
}
271+
272+
func (this *BinaryIndexedTree) lowbit(x int) int {
273+
return x & -x
274+
}
275+
276+
func (this *BinaryIndexedTree) update(x, val int) {
277+
for x <= this.n {
278+
if this.c[x] < val {
279+
this.c[x] = val
280+
}
281+
x += this.lowbit(x)
282+
}
283+
}
284+
285+
func (this *BinaryIndexedTree) query(x int) int {
286+
s := 0
287+
for x > 0 {
288+
if s < this.c[x] {
289+
s = this.c[x]
290+
}
291+
x -= this.lowbit(x)
292+
}
293+
return s
294+
}
295+
296+
func longestObstacleCourseAtEachPosition(obstacles []int) []int {
297+
s := make(map[int]bool)
298+
for _, v := range obstacles {
299+
s[v] = true
300+
}
301+
var t []int
302+
for v, _ := range s {
303+
t = append(t, v)
304+
}
305+
sort.Ints(t)
306+
m := make(map[int]int)
307+
for i, v := range t {
308+
m[v] = i + 1
309+
}
310+
n := len(obstacles)
311+
ans := make([]int, n)
312+
tree := newBinaryIndexedTree(len(m))
313+
for i, v := range obstacles {
314+
x := m[v]
315+
ans[i] = 1 + tree.query(x)
316+
tree.update(x, ans[i])
317+
}
318+
return ans
319+
}
91320
```
92321

93322
### **...**

0 commit comments

Comments
 (0)