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 8e311ae

Browse files
Merge branch 'youngyangyang04:master' into master
2 parents 87a51bc + fbe1e00 commit 8e311ae

18 files changed

+471
-35
lines changed

‎problems/0024.两两交换链表中的节点.md‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,5 +337,48 @@ object Solution {
337337
}
338338
```
339339

340+
PHP:
341+
```php
342+
//虚拟头结点
343+
function swapPairs($head) {
344+
if ($head == null || $head->next == null) {
345+
return $head;
346+
}
347+
348+
$dummyNode = new ListNode(0, $head);
349+
$preNode = $dummyNode; //虚拟头结点
350+
$curNode = $head;
351+
$nextNode = $head->next;
352+
while($curNode && $nextNode) {
353+
$nextNextNode = $nextNode->next; //存下一个节点
354+
$nextNode->next = $curNode; //交换curHead 和 nextHead
355+
$curNode->next = $nextNextNode;
356+
$preNode->next = $nextNode; //上一个节点的下一个指向指向nextHead
357+
358+
//更新当前的几个指针
359+
$preNode = $preNode->next->next;
360+
$curNode = $nextNextNode;
361+
$nextNode = $nextNextNode->next;
362+
}
363+
364+
return $dummyNode->next;
365+
}
366+
367+
//递归版本
368+
function swapPairs($head)
369+
{
370+
// 终止条件
371+
if ($head === null || $head->next === null) {
372+
return $head;
373+
}
374+
375+
//结果要返回的头结点
376+
$next = $head->next;
377+
$head->next = $this->swapPairs($next->next); //当前头结点->next指向更新
378+
$next->next = $head; //当前第二个节点的->next指向更新
379+
return $next; //返回翻转后的头结点
380+
}
381+
```
382+
340383
-----------------------
341384
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>

‎problems/0027.移除元素.md‎

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,37 +146,50 @@ public:
146146
};
147147
```
148148

149-
149+
150150
## 相关题目推荐
151151

152152
* 26.删除排序数组中的重复项
153153
* 283.移动零
154154
* 844.比较含退格的字符串
155155
* 977.有序数组的平方
156156

157-
158-
159-
160-
161157
## 其他语言版本
162158

163159

164160
Java:
165161
```java
166162
class Solution {
167163
public int removeElement(int[] nums, int val) {
168-
169164
// 快慢指针
170-
int fastIndex = 0;
171-
int slowIndex;
172-
for (slowIndex = 0; fastIndex < nums.length; fastIndex++) {
165+
int slowIndex = 0;
166+
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
173167
if (nums[fastIndex] != val) {
174168
nums[slowIndex] = nums[fastIndex];
175169
slowIndex++;
176170
}
177171
}
178172
return slowIndex;
179-
173+
}
174+
}
175+
```
176+
```java
177+
//相向双指针法
178+
class Solution {
179+
public int removeElement(int[] nums, int val) {
180+
int left = 0;
181+
int right = nums.length - 1;
182+
while(right >= 0 && nums[right] == val) right--; //将right移到从右数第一个值不为val的位置
183+
while(left <= right) {
184+
if(nums[left] == val) { //left位置的元素需要移除
185+
//将right位置的元素移到left(覆盖),right位置移除
186+
nums[left] = nums[right];
187+
right--;
188+
}
189+
left++;
190+
while(right >= 0 && nums[right] == val) right--;
191+
}
192+
return left;
180193
}
181194
}
182195
```

‎problems/0035.搜索插入位置.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,32 @@ class Solution {
226226
}
227227
}
228228
```
229+
```java
230+
//第二种二分法:左闭右开
231+
public int searchInsert(int[] nums, int target) {
232+
int left = 0;
233+
int right = nums.length;
234+
while (left < right) { //左闭右开 [left, right)
235+
int middle = left + ((right - left) >> 1);
236+
if (nums[middle] > target) {
237+
right = middle; // target 在左区间,在[left, middle)中
238+
} else if (nums[middle] < target) {
239+
left = middle + 1; // target 在右区间,在 [middle+1, right)中
240+
} else { // nums[middle] == target
241+
return middle; // 数组中找到目标值的情况,直接返回下标
242+
}
243+
}
244+
// 目标值在数组所有元素之前 [0,0)
245+
// 目标值插入数组中的位置 [left, right) ,return right 即可
246+
// 目标值在数组所有元素之后的情况 [left, right),因为是右开区间,所以 return right
247+
return right;
248+
}
249+
```
250+
251+
252+
229253
Golang:
254+
230255
```golang
231256
// 第一种二分法
232257
func searchInsert(nums []int, target int) int {

‎problems/0077.组合.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ vector<vector<int>> result; // 存放符合条件结果的集合
114114
vector<int> path; // 用来存放符合条件结果
115115
```
116116

117-
其实不定义这两个全局遍历也是可以的,把这两个变量放进递归函数的参数里,但函数里参数太多影响可读性,所以我定义全局变量了。
117+
其实不定义这两个全局变量也是可以的,把这两个变量放进递归函数的参数里,但函数里参数太多影响可读性,所以我定义全局变量了。
118118

119119
函数里一定有两个参数,既然是集合n里面取k的数,那么n和k是两个int型的参数。
120120

‎problems/0096.不同的二叉搜索树.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,24 @@ function numTrees(n: number): number {
252252
};
253253
```
254254

255+
### Rust
256+
257+
```Rust
258+
impl Solution {
259+
pub fn num_trees(n: i32) -> i32 {
260+
let n = n as usize;
261+
let mut dp = vec![0; n + 1];
262+
dp[0] = 1;
263+
for i in 1..=n {
264+
for j in 1..=i {
265+
dp[i] += dp[j - 1] * dp[i - j];
266+
}
267+
}
268+
dp[n]
269+
}
270+
}
271+
```
272+
255273
### C
256274

257275
```c

‎problems/0131.分割回文串.md‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,65 @@ public:
206206
return result;
207207
}
208208
};
209+
```
210+
# 优化
211+
212+
上面的代码还存在一定的优化空间, 在于如何更高效的计算一个子字符串是否是回文字串。上述代码```isPalindrome```函数运用双指针的方法来判定对于一个字符串```s```, 给定起始下标和终止下标, 截取出的子字符串是否是回文字串。但是其中有一定的重复计算存在:
213+
214+
例如给定字符串```"abcde"```, 在已知```"bcd"```不是回文字串时, 不再需要去双指针操作```"abcde"```而可以直接判定它一定不是回文字串。
215+
216+
具体来说, 给定一个字符串`s`, 长度为```n```, 它成为回文字串的充分必要条件是```s[0] == s[n-1]```且```s[1:n-1]```是回文字串。
217+
218+
大家如果熟悉动态规划这种算法的话, 我们可以高效地事先一次性计算出, 针对一个字符串```s```, 它的任何子串是否是回文字串, 然后在我们的回溯函数中直接查询即可, 省去了双指针移动判定这一步骤.
219+
220+
具体参考代码如下:
221+
222+
```CPP
223+
class Solution {
224+
private:
225+
vector<vector<string>> result;
226+
vector<string> path; // 放已经回文的子串
227+
vector<vector<bool>> isPalindrome; // 放事先计算好的是否回文子串的结果
228+
void backtracking (const string& s, int startIndex) {
229+
// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了
230+
if (startIndex >= s.size()) {
231+
result.push_back(path);
232+
return;
233+
}
234+
for (int i = startIndex; i < s.size(); i++) {
235+
if (isPalindrome[startIndex][i]) { // 是回文子串
236+
// 获取[startIndex,i]在s中的子串
237+
string str = s.substr(startIndex, i - startIndex + 1);
238+
path.push_back(str);
239+
} else { // 不是回文,跳过
240+
continue;
241+
}
242+
backtracking(s, i + 1); // 寻找i+1为起始位置的子串
243+
path.pop_back(); // 回溯过程,弹出本次已经填在的子串
244+
}
245+
}
246+
void computePalindrome(const string& s) {
247+
// isPalindrome[i][j] 代表 s[i:j](双边包括)是否是回文字串
248+
isPalindrome.resize(s.size(), vector<bool>(s.size(), false)); // 根据字符串s, 刷新布尔矩阵的大小
249+
for (int i = s.size() - 1; i >= 0; i--) {
250+
// 需要倒序计算, 保证在i行时, i+1行已经计算好了
251+
for (int j = i; j < s.size(); j++) {
252+
if (j == i) {isPalindrome[i][j] = true;}
253+
else if (j - i == 1) {isPalindrome[i][j] = (s[i] == s[j]);}
254+
else {isPalindrome[i][j] = (s[i] == s[j] && isPalindrome[i+1][j-1]);}
255+
}
256+
}
257+
}
258+
public:
259+
vector<vector<string>> partition(string s) {
260+
result.clear();
261+
path.clear();
262+
computePalindrome(s);
263+
backtracking(s, 0);
264+
return result;
265+
}
266+
};
267+
209268
```
210269

211270
# 总结

‎problems/0150.逆波兰表达式求值.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565

6666
# 思路
6767

68+
《代码随想录》算法视频公开课:[栈的最后表演! | LeetCode:150. 逆波兰表达式求值](https://www.bilibili.com/video/BV1kd4y1o7on),相信结合视频在看本篇题解,更有助于大家对本题的理解。
69+
6870
在上一篇文章中[1047.删除字符串中的所有相邻重复项](https://programmercarl.com/1047.删除字符串中的所有相邻重复项.html)提到了 递归就是用栈来实现的。
6971

7072
所以**栈与递归之间在某种程度上是可以转换的!** 这一点我们在后续讲解二叉树的时候,会更详细的讲解到。

‎problems/0239.滑动窗口最大值.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
# 思路
3434

35+
《代码随想录》算法视频公开课:[单调队列正式登场!| LeetCode:239. 滑动窗口最大值](https://www.bilibili.com/video/BV1XS4y1p7qj),相信结合视频在看本篇题解,更有助于大家对本题的理解。
36+
3537
这是使用单调队列的经典题目。
3638

3739
难点是如何求一个区间里的最大值呢? (这好像是废话),暴力一下不就得了。

‎problems/0343.整数拆分.md‎

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public:
192192
## 其他语言版本
193193
194194
195-
### Java
195+
### Java
196196
```Java
197197
class Solution {
198198
public int integerBreak(int n) {
@@ -259,6 +259,21 @@ func max(a,b int) int{
259259
}
260260
```
261261

262+
### Rust
263+
```rust
264+
pub fn integer_break(n: i32) -> i32 {
265+
let n = n as usize;
266+
let mut dp = vec![0; n + 1];
267+
dp[2] = 1;
268+
for i in 3..=n {
269+
for j in 1..i-1 {
270+
dp[i] = dp[i].max((i - j) * j).max(dp[i - j] * j);
271+
}
272+
}
273+
dp[n] as i32
274+
}
275+
```
276+
262277
### Javascript
263278
```Javascript
264279
var integerBreak = function(n) {
@@ -299,6 +314,27 @@ function integerBreak(n: number): number {
299314
};
300315
```
301316

317+
### Rust
318+
319+
```Rust
320+
impl Solution {
321+
fn max(a: i32, b: i32) -> i32{
322+
if a > b { a } else { b }
323+
}
324+
pub fn integer_break(n: i32) -> i32 {
325+
let n = n as usize;
326+
let mut dp = vec![0; n + 1];
327+
dp[2] = 1;
328+
for i in 3..=n {
329+
for j in 1..i - 1 {
330+
dp[i] = Self::max(dp[i], Self::max(((i - j) * j) as i32, dp[i - j] * j as i32));
331+
}
332+
}
333+
dp[n]
334+
}
335+
}
336+
```
337+
302338
### C
303339

304340
```c

‎problems/0347.前K个高频元素.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@
3131

3232
# 思路
3333

34+
《代码随想录》算法视频公开课:[优先级队列正式登场!大顶堆、小顶堆该怎么用?| LeetCode:347.前 K 个高频元素](https://www.bilibili.com/video/BV1Xg41167Lz),相信结合视频在看本篇题解,更有助于大家对本题的理解。
35+
36+
<p align="center">
37+
<iframe src="//player.bilibili.com/player.html?aid=514643371&bvid=BV1Xg41167Lz&cid=808260290&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width=750 height=500></iframe>
38+
</p>
39+
40+
41+
3442
这道题目主要涉及到如下三块内容:
3543
1. 要统计元素出现频率
3644
2. 对频率排序

0 commit comments

Comments
(0)

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