Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4d8e387

Browse files
feat: add solutions to lcp problems: No.77,78 (doocs#1218)
* No.77.符文储备 * No.78.城墙防线
1 parent 0a6a47a commit 4d8e387

File tree

12 files changed

+454
-2
lines changed

12 files changed

+454
-2
lines changed

‎lcp/LCP 77. 符文储备/README.md‎

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,105 @@
3838

3939
<!-- 这里可写通用的实现逻辑 -->
4040

41+
**方法一:排序**
42+
43+
我们可以将符文按照魔力值从小到大排序,然后使用双指针维护一个滑动窗口,使得滑动窗口中的任意相邻的两块符文之间的魔力值相差不超过,找出满足条件的最大窗口长度即可。
44+
45+
时间复杂度 $O(n \times \log n),ドル空间复杂度 $O(\log n)$。其中 $n$ 是数组 $runes$ 的长度。
46+
4147
<!-- tabs:start -->
4248

4349
### **Python3**
4450

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

4753
```python
48-
54+
class Solution:
55+
def runeReserve(self, runes: List[int]) -> int:
56+
runes.sort()
57+
ans = i = 0
58+
for j, x in enumerate(runes):
59+
if j and runes[j] - runes[j - 1] > 1:
60+
i = j
61+
else:
62+
ans = max(ans, j - i + 1)
63+
return ans
4964
```
5065

5166
### **Java**
5267

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

5570
```java
71+
class Solution {
72+
public int runeReserve(int[] runes) {
73+
Arrays.sort(runes);
74+
int ans = 0;
75+
for (int i = 0, j = 0; j < runes.length; ++j) {
76+
if (j > 0 && runes[j] - runes[j - 1] > 1) {
77+
i = j;
78+
} else {
79+
ans = Math.max(ans, j - i + 1);
80+
}
81+
}
82+
return ans;
83+
}
84+
}
85+
```
86+
87+
### **C++**
88+
89+
```cpp
90+
class Solution {
91+
public:
92+
int runeReserve(vector<int>& runes) {
93+
sort(runes.begin(), runes.end());
94+
int ans = 0;
95+
for (int i = 0, j = 0; j < runes.size(); ++j) {
96+
if (j && runes[j] - runes[j - 1] > 1) {
97+
i = j;
98+
} else {
99+
ans = max(ans, j - i + 1);
100+
}
101+
}
102+
return ans;
103+
}
104+
};
105+
```
106+
107+
### **Go**
108+
109+
```go
110+
func runeReserve(runes []int) (ans int) {
111+
sort.Ints(runes)
112+
i := 0
113+
for j, x := range runes {
114+
if j > 0 && x-runes[j-1] > 1 {
115+
i = j
116+
} else if t := j - i + 1; ans < t {
117+
ans = t
118+
}
119+
}
120+
return
121+
}
122+
```
56123

124+
### **TypeScript**
125+
126+
```ts
127+
function runeReserve(runes: number[]): number {
128+
runes.sort((a, b) => a - b);
129+
let ans = 0;
130+
let i = 0;
131+
for (let j = 0; j < runes.length; ++j) {
132+
if (j > 0 && runes[j] - runes[j - 1] > 1) {
133+
i = j;
134+
} else {
135+
ans = Math.max(ans, j - i + 1);
136+
}
137+
}
138+
return ans;
139+
}
57140
```
58141

59142
### **...**
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Solution {
2+
public:
3+
int runeReserve(vector<int>& runes) {
4+
sort(runes.begin(), runes.end());
5+
int ans = 0;
6+
for (int i = 0, j = 0; j < runes.size(); ++j) {
7+
if (j && runes[j] - runes[j - 1] > 1) {
8+
i = j;
9+
} else {
10+
ans = max(ans, j - i + 1);
11+
}
12+
}
13+
return ans;
14+
}
15+
};

‎lcp/LCP 77. 符文储备/Solution.go‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
func runeReserve(runes []int) (ans int) {
2+
sort.Ints(runes)
3+
i := 0
4+
for j, x := range runes {
5+
if j > 0 && x-runes[j-1] > 1 {
6+
i = j
7+
} else if t := j - i + 1; ans < t {
8+
ans = t
9+
}
10+
}
11+
return
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution {
2+
public int runeReserve(int[] runes) {
3+
Arrays.sort(runes);
4+
int ans = 0;
5+
for (int i = 0, j = 0; j < runes.length; ++j) {
6+
if (j > 0 && runes[j] - runes[j - 1] > 1) {
7+
i = j;
8+
} else {
9+
ans = Math.max(ans, j - i + 1);
10+
}
11+
}
12+
return ans;
13+
}
14+
}

‎lcp/LCP 77. 符文储备/Solution.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Solution:
2+
def runeReserve(self, runes: List[int]) -> int:
3+
runes.sort()
4+
ans = i = 0
5+
for j, x in enumerate(runes):
6+
if j and runes[j] - runes[j - 1] > 1:
7+
i = j
8+
else:
9+
ans = max(ans, j - i + 1)
10+
return ans

‎lcp/LCP 77. 符文储备/Solution.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function runeReserve(runes: number[]): number {
2+
runes.sort((a, b) => a - b);
3+
let ans = 0;
4+
let i = 0;
5+
for (let j = 0; j < runes.length; ++j) {
6+
if (j > 0 && runes[j] - runes[j - 1] > 1) {
7+
i = j;
8+
} else {
9+
ans = Math.max(ans, j - i + 1);
10+
}
11+
}
12+
return ans;
13+
}

‎lcp/LCP 78. 城墙防线/README.md‎

Lines changed: 166 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,187 @@
4646

4747
<!-- 这里可写通用的实现逻辑 -->
4848

49+
**方法一:二分查找**
50+
51+
我们注意到,如果一个膨胀值 $x$ 满足条件,那么所有小于 $x$ 的值也都满足条件,这存在着单调性。因此我们可以使用二分查找的方法,找到最大的满足条件的膨胀值。
52+
53+
我们定义二分查找的左边界 $left=0,ドル $right=rampart[1][0]-rampart[0][1]+rampart[2][0]-rampart[1][1],ドル其中 $rampart[i][0]$ 表示第 $i$ 段城墙的左端点,$rampart[i][1]$ 表示第 $i$ 段城墙的右端点。
54+
55+
接下来,我们开始进行二分查找。每一次,我们求出当前的中间值 $mid,ドル并判断其是否满足条件。如果满足条件,那么我们就将左边界 $left$ 更新为 $mid,ドル否则将右边界 $right$ 更新为 $mid-1$。在二分查找结束后,我们返回左边界 $left$ 即可。
56+
57+
那么问题的关键在于如何判断一个值 $w$ 是否满足条件。显然,我们可以用贪心的策略,每次先尽可能往左膨胀,如果还有剩余的膨胀值,再往右膨胀,如果在向右膨胀的过程中,发生了重叠,那么说明当前的膨胀值 $w$ 不满足条件,直接返回 `false` 即可。否则,遍历结束,返回 `true`
58+
59+
时间复杂度 $O(n \times \log M),ドル其中 $n$ 和 $M$ 分别是数组 $rampart$ 的长度和二分查找的右边界,本题中右边界最大为 $range=rampart[1][0]-rampart[0][1]+rampart[2][0]-rampart[1][1]$。空间复杂度 $O(1)$。
60+
4961
<!-- tabs:start -->
5062

5163
### **Python3**
5264

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

5567
```python
56-
68+
class Solution:
69+
def rampartDefensiveLine(self, rampart: List[List[int]]) -> int:
70+
def check(w: int) -> bool:
71+
last = rampart[0][1]
72+
for i in range(1, len(rampart) - 1):
73+
x, y = rampart[i]
74+
a = x - last
75+
b = max(w - a, 0)
76+
if y + b > rampart[i + 1][0]:
77+
return False
78+
last = y + b
79+
return True
80+
81+
left, right = 0, rampart[1][0] - rampart[0][1] + rampart[2][0] - rampart[1][1]
82+
while left < right:
83+
mid = (left + right + 1) >> 1
84+
if check(mid):
85+
left = mid
86+
else:
87+
right = mid - 1
88+
return left
5789
```
5890

5991
### **Java**
6092

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

6395
```java
96+
class Solution {
97+
private int[][] rampart;
98+
99+
public int rampartDefensiveLine(int[][] rampart) {
100+
this.rampart = rampart;
101+
int left = 0, right = rampart[1][0] - rampart[0][1] + rampart[2][0] - rampart[1][1];
102+
while (left < right) {
103+
int mid = (left + right + 1) >> 1;
104+
if (check(mid)) {
105+
left = mid;
106+
} else {
107+
right = mid - 1;
108+
}
109+
}
110+
return left;
111+
}
112+
113+
private boolean check(int w) {
114+
int last = rampart[0][1];
115+
for (int i = 1; i < rampart.length - 1; ++i) {
116+
int x = rampart[i][0], y = rampart[i][1];
117+
int a = x - last;
118+
int b = Math.max(w - a, 0);
119+
if (y + b > rampart[i + 1][0]) {
120+
return false;
121+
}
122+
last = y + b;
123+
}
124+
return true;
125+
}
126+
}
127+
```
128+
129+
### **C++**
130+
131+
```cpp
132+
class Solution {
133+
public:
134+
int rampartDefensiveLine(vector<vector<int>>& rampart) {
135+
int left = 0, right = rampart[1][0] - rampart[0][1] + rampart[2][0] - rampart[1][1];
136+
auto check = [&](int w) {
137+
int last = rampart[0][1];
138+
for (int i = 1; i < rampart.size() - 1; ++i) {
139+
int x = rampart[i][0], y = rampart[i][1];
140+
int a = x - last;
141+
int b = max(w - a, 0);
142+
if (y + b > rampart[i + 1][0]) {
143+
return false;
144+
}
145+
last = y + b;
146+
}
147+
return true;
148+
};
149+
150+
while (left < right) {
151+
int mid = (left + right + 1) >> 1;
152+
if (check(mid)) {
153+
left = mid;
154+
} else {
155+
right = mid - 1;
156+
}
157+
}
158+
return left;
159+
}
160+
};
161+
```
162+
163+
### **Go**
164+
165+
```go
166+
func rampartDefensiveLine(rampart [][]int) int {
167+
check := func(w int) bool {
168+
last := rampart[0][1]
169+
for i := 1; i < len(rampart)-1; i++ {
170+
x, y := rampart[i][0], rampart[i][1]
171+
a := x - last
172+
b := max(w-a, 0)
173+
if y+b > rampart[i+1][0] {
174+
return false
175+
}
176+
last = y + b
177+
}
178+
return true
179+
}
180+
181+
left, right := 0, rampart[1][0]-rampart[0][1]+rampart[2][0]-rampart[1][1]
182+
for left < right {
183+
mid := (left + right + 1) >> 1
184+
if check(mid) {
185+
left = mid
186+
} else {
187+
right = mid - 1
188+
}
189+
}
190+
return left
191+
}
192+
193+
func max(a, b int) int {
194+
if a > b {
195+
return a
196+
}
197+
return b
198+
}
199+
```
64200

201+
### **TypeScript**
202+
203+
```ts
204+
function rampartDefensiveLine(rampart: number[][]): number {
205+
const check = (w: number): boolean => {
206+
let last = rampart[0][1];
207+
for (let i = 1; i < rampart.length - 1; ++i) {
208+
const [x, y] = rampart[i];
209+
const a = x - last;
210+
const b = Math.max(w - a, 0);
211+
if (y + b > rampart[i + 1][0]) {
212+
return false;
213+
}
214+
last = y + b;
215+
}
216+
return true;
217+
};
218+
let left = 0;
219+
let right = rampart[1][0] - rampart[0][1] + rampart[2][0] - rampart[1][1];
220+
while (left < right) {
221+
const mid = (left + right + 1) >> 1;
222+
if (check(mid)) {
223+
left = mid;
224+
} else {
225+
right = mid - 1;
226+
}
227+
}
228+
return left;
229+
}
65230
```
66231

67232
### **...**
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution {
2+
public:
3+
int rampartDefensiveLine(vector<vector<int>>& rampart) {
4+
int left = 0, right = rampart[1][0] - rampart[0][1] + rampart[2][0] - rampart[1][1];
5+
auto check = [&](int w) {
6+
int last = rampart[0][1];
7+
for (int i = 1; i < rampart.size() - 1; ++i) {
8+
int x = rampart[i][0], y = rampart[i][1];
9+
int a = x - last;
10+
int b = max(w - a, 0);
11+
if (y + b > rampart[i + 1][0]) {
12+
return false;
13+
}
14+
last = y + b;
15+
}
16+
return true;
17+
};
18+
19+
while (left < right) {
20+
int mid = (left + right + 1) >> 1;
21+
if (check(mid)) {
22+
left = mid;
23+
} else {
24+
right = mid - 1;
25+
}
26+
}
27+
return left;
28+
}
29+
};

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /