Skip to content

Commit 7c1c69a

Browse files
committed
feat: add solutions to lcci problem: No.17.08
No.17.08.Circus Tower
1 parent 6014b39 commit 7c1c69a

File tree

6 files changed

+654
-2
lines changed

6 files changed

+654
-2
lines changed

lcci/17.08.Circus Tower/README.md

+224
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 题目描述
66

77
<!-- 这里写题目描述 -->
8+
89
<p>有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上。出于实际和美观的考虑,在上面的人要比下面的人矮一点且轻一点。已知马戏团每个人的身高和体重,请编写代码计算叠罗汉最多能叠几个人。</p>
910
<p><strong>示例:</strong></p>
1011
<pre><strong>输入:</strong>height = [65,70,56,75,60,68] weight = [100,150,90,190,95,110]
@@ -18,22 +19,245 @@
1819
## 解法
1920

2021
<!-- 这里可写通用的实现逻辑 -->
22+
23+
**方法一:排序 + 离散化 + 树状数组**
24+
25+
我们现将所有人按照身高从小到大排序,若身高相同,则按照体重从大到小排序。这样我们可以将问题转换为求体重数组的最长递增子序列的问题。
26+
27+
最长递增子序列的问题可以使用动态规划求解,时间复杂度 $O(n^2)$。但是我们可以使用树状数组来优化求解过程,时间复杂度 $O(n \log n)$。
28+
29+
空间复杂度 $O(n)$。其中 $n$ 为人数。
30+
2131
<!-- tabs:start -->
2232

2333
### **Python3**
2434

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

2737
```python
38+
class BinaryIndexedTree:
39+
def __init__(self, n):
40+
self.n = n
41+
self.c = [0] * (n + 1)
42+
43+
def update(self, x, delta):
44+
while x <= self.n:
45+
self.c[x] = max(self.c[x], delta)
46+
x += x & -x
2847

48+
def query(self, x):
49+
s = 0
50+
while x:
51+
s = max(s, self.c[x])
52+
x -= x & -x
53+
return s
54+
55+
56+
class Solution:
57+
def bestSeqAtIndex(self, height: List[int], weight: List[int]) -> int:
58+
arr = list(zip(height, weight))
59+
arr.sort(key=lambda x: (x[0], -x[1]))
60+
alls = sorted({w for _, w in arr})
61+
m = {w: i for i, w in enumerate(alls, 1)}
62+
tree = BinaryIndexedTree(len(m))
63+
ans = 1
64+
for _, w in arr:
65+
x = m[w]
66+
t = tree.query(x - 1) + 1
67+
ans = max(ans, t)
68+
tree.update(x, t)
69+
return ans
2970
```
3071

3172
### **Java**
3273

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

3576
```java
77+
class BinaryIndexedTree {
78+
private int n;
79+
private int[] c;
80+
81+
public BinaryIndexedTree(int n) {
82+
this.n = n;
83+
c = new int[n + 1];
84+
}
85+
86+
public void update(int x, int val) {
87+
while (x <= n) {
88+
this.c[x] = Math.max(this.c[x], val);
89+
x += x & -x;
90+
}
91+
}
92+
93+
public int query(int x) {
94+
int s = 0;
95+
while (x > 0) {
96+
s = Math.max(s, this.c[x]);
97+
x -= x & -x;
98+
}
99+
return s;
100+
}
101+
}
102+
103+
class Solution {
104+
public int bestSeqAtIndex(int[] height, int[] weight) {
105+
int n = height.length;
106+
int[][] arr = new int[n][2];
107+
for (int i = 0; i < n; ++i) {
108+
arr[i] = new int[]{height[i], weight[i]};
109+
}
110+
Arrays.sort(arr, (a, b) -> a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]);
111+
Set<Integer> s = new HashSet<>();
112+
for (int[] e : arr) {
113+
s.add(e[1]);
114+
}
115+
List<Integer> alls = new ArrayList<>(s);
116+
Collections.sort(alls);
117+
Map<Integer, Integer> m = new HashMap<>(alls.size());
118+
for (int i = 0; i < alls.size(); ++i) {
119+
m.put(alls.get(i), i + 1);
120+
}
121+
BinaryIndexedTree tree = new BinaryIndexedTree(alls.size());
122+
int ans = 1;
123+
for (int[] e : arr) {
124+
int x = m.get(e[1]);
125+
int t = tree.query(x - 1) + 1;
126+
ans = Math.max(ans, t);
127+
tree.update(x, t);
128+
}
129+
return ans;
130+
}
131+
}
132+
```
133+
134+
### **C++**
135+
136+
```cpp
137+
class BinaryIndexedTree {
138+
public:
139+
BinaryIndexedTree(int _n)
140+
: n(_n)
141+
, c(_n + 1) {}
142+
143+
void update(int x, int val) {
144+
while (x <= n) {
145+
c[x] = max(c[x], val);
146+
x += x & -x;
147+
}
148+
}
149+
150+
int query(int x) {
151+
int s = 0;
152+
while (x > 0) {
153+
s = max(s, c[x]);
154+
x -= x & -x;
155+
}
156+
return s;
157+
}
158+
159+
private:
160+
int n;
161+
vector<int> c;
162+
};
163+
164+
class Solution {
165+
public:
166+
int bestSeqAtIndex(vector<int>& height, vector<int>& weight) {
167+
int n = height.size();
168+
vector<pair<int, int>> people;
169+
for (int i = 0; i < n; ++i) {
170+
people.emplace_back(height[i], weight[i]);
171+
}
172+
sort(people.begin(), people.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
173+
if (a.first == b.first) {
174+
return a.second > b.second;
175+
}
176+
return a.first < b.first;
177+
});
178+
vector<int> alls = weight;
179+
sort(alls.begin(), alls.end());
180+
alls.erase(unique(alls.begin(), alls.end()), alls.end());
181+
BinaryIndexedTree tree(alls.size());
182+
int ans = 1;
183+
for (auto& [_, w] : people) {
184+
int x = lower_bound(alls.begin(), alls.end(), w) - alls.begin() + 1;
185+
int t = tree.query(x - 1) + 1;
186+
ans = max(ans, t);
187+
tree.update(x, t);
188+
}
189+
return ans;
190+
}
191+
};
192+
```
193+
194+
### **Go**
195+
196+
```go
197+
type BinaryIndexedTree struct {
198+
n int
199+
c []int
200+
}
201+
202+
func newBinaryIndexedTree(n int) *BinaryIndexedTree {
203+
c := make([]int, n+1)
204+
return &BinaryIndexedTree{n, c}
205+
}
206+
207+
func (this *BinaryIndexedTree) update(x, val int) {
208+
for x <= this.n {
209+
if this.c[x] < val {
210+
this.c[x] = val
211+
}
212+
x += x & -x
213+
}
214+
}
215+
216+
func (this *BinaryIndexedTree) query(x int) int {
217+
s := 0
218+
for x > 0 {
219+
if s < this.c[x] {
220+
s = this.c[x]
221+
}
222+
x -= x & -x
223+
}
224+
return s
225+
}
226+
227+
func bestSeqAtIndex(height []int, weight []int) int {
228+
n := len(height)
229+
people := make([][2]int, n)
230+
s := map[int]bool{}
231+
for i := range people {
232+
people[i] = [2]int{height[i], weight[i]}
233+
s[weight[i]] = true
234+
}
235+
sort.Slice(people, func(i, j int) bool {
236+
a, b := people[i], people[j]
237+
return a[0] < b[0] || a[0] == b[0] && a[1] > b[1]
238+
})
239+
alls := make([]int, 0, len(s))
240+
for k := range s {
241+
alls = append(alls, k)
242+
}
243+
sort.Ints(alls)
244+
tree := newBinaryIndexedTree(len(alls))
245+
ans := 1
246+
for _, p := range people {
247+
x := sort.SearchInts(alls, p[1]) + 1
248+
t := tree.query(x-1) + 1
249+
ans = max(ans, t)
250+
tree.update(x, t)
251+
}
252+
return ans
253+
}
36254
255+
func max(a, b int) int {
256+
if a > b {
257+
return a
258+
}
259+
return b
260+
}
37261
```
38262

39263
### **...**

0 commit comments

Comments
 (0)