Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 349849f

Browse files
committed
add leetcode 203 and fix some error.
1 parent 4228d33 commit 349849f

File tree

5 files changed

+112
-5
lines changed

5 files changed

+112
-5
lines changed

linkedlist/Leetcode876MiddleOftheLinkedList.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,3 @@ public ListNode middleNode(ListNode head) {
7070
- 空间复杂度:_O(1)_
7171

7272

73-
74-
冠状病毒

linkedlist/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,6 @@ gcc Quack.c revarg.c
245245
246246
[Leetcode147 链表插入排序题解](linkedlist/leetcode147.md)
247247
248-
[Leetcode86 分割链表题解](linkedlist/leetcode86.md)
248+
[Leetcode86 分割链表题解](linkedlist/leetcode86.md)
249+
250+
[Leetcode 203 移除链表元素题解](linkedlist/leetcode203.md)

linkedlist/leetcode147.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@ public ListNode insertionSortList(ListNode head) {
4646

4747
大致上就是这样,代码也比较简单,不懂的自己可以画个图来理解,感觉这几天的刷题还是对自己有点帮助的。多刷题就有进步。
4848

49-
> > 愿在追梦路上的人都有收货
49+
> > 愿在追梦路上的人都有收获
5050

linkedlist/leetcode203.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
### 描述
2+
删除单链表中等于给定值val的所有节点。
3+
例如:
4+
`1->2->3->4`, val = 2
5+
输出:
6+
1->3->4
7+
8+
[点击此处看原题](https://leetcode-cn.com/problems/remove-linked-list-elements/)
9+
10+
### 思路
11+
这题的思路很直观,但是这题是经典的dummy Node使用的一个典型例子。同时也是理解递归的好题目。
12+
13+
思路非常简单,就是典型的删除节点的代码。
14+
下面直接给出代码,供参考。
15+
这是迭代版本,使用了dummy Node。
16+
```java
17+
class Solution {
18+
public ListNode removeElements(ListNode head, int val) {
19+
ListNode sentinel = new ListNode(0); // 构造哑节点
20+
sentinel.next = head;
21+
22+
ListNode prev = sentinel, curr = head;
23+
while (curr != null) {
24+
if (curr.val == val) prev.next = curr.next; // 如果符合要求,就删除
25+
else prev = curr; // 否则就下一个。
26+
curr = curr.next;
27+
}
28+
return sentinel.next;
29+
}
30+
}
31+
32+
```
33+
上述代码非常直观。下面我们可以研究一下递归。
34+
35+
```java
36+
class Solution {
37+
public ListNode removeElements(ListNode head, int val) {
38+
// recursive
39+
if (head == null) return head; // 递归出口
40+
head.next = removeElements(head.next, val);
41+
return head.val == val? head.next:head;
42+
}
43+
}
44+
```
45+
46+
>>> 愿追梦路上的人都有收获!

linkedlist/leetcode206.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,62 @@
1-
leetcode206.md
1+
### 描述
2+
反转一个单链表。
3+
4+
示例:
5+
6+
输入: 1->2->3->4->5->NULL
7+
输出: 5->4->3->2->1->NULL
8+
9+
[点击此处查看题解](https://leetcode-cn.com/problems/reverse-linked-list/)
10+
11+
### 思路
12+
这题也是属于简单题。如何反转呢?
13+
我们在遍历列表的时候,我们就把当前节点的next指针改成指向上一个元素。但是由于是单链表,节点没有引用上一个节点,因此我们需要额外的空间来存储上一个元素,当然,在更改引用之前,还需要另一个指针来存储下一个节点。想想看,要返回的是什么?
14+
15+
下面给出迭代版本的题解:
16+
```java
17+
public ListNode reverseList(ListNode head) {
18+
ListNode prev = null;
19+
ListNode curr = head;
20+
while (curr != null) {
21+
ListNode nextTemp = curr.next;
22+
curr.next = prev;
23+
prev = curr;
24+
curr = nextTemp;
25+
}
26+
return prev;
27+
}
28+
29+
```
30+
31+
#### 复杂度分析
32+
- 时间复杂度:__O(n)__, n是列表长度。
33+
- 空间复杂度:__O(1)__,只跟踪了常数个变量。
34+
35+
### 递归思路
36+
这题的递归略微难想。我们回想一下,写递归我们一般是怎么做的?
37+
1. 递归出口
38+
2. 递归条件
39+
40+
那么我们显而易见,递归出口是当给定的链表是空的,或者只有当前一个节点。
41+
那么递归条件呢?
42+
假设我们已经有了一个列表:
43+
44+
1 -> 2 -> 3 -> 4 <- 5
45+
46+
我们可以看到, 5 -> 4 这个子list被反转了,此时,我们在3 这个节点上,我们希望的事情是, 4的下一个节点指向 3。 所以,
47+
`
48+
3.next.next = 3
49+
`
50+
这就反转了。不理解的同学可以拿出纸笔画一下,相信很快就能理解这个过程。
51+
这里要注意的是,1 的下一个节点必须指向 NULL, 如果你没有注意这个问题,你的链表会产生循环。你可以试一试长度为2的链表来试试看,模拟这个过程, 就可以很明显的看到这个错误。下面给出代码。
52+
53+
```java
54+
public ListNode reverseList(ListNode head) {
55+
if (head == null || head.next == null) return head;
56+
ListNode p = reverseList(head.next);
57+
head.next.next = head;
58+
head.next = null;
59+
return p;
60+
}
61+
```
62+
走到这里,相信对递归有了更深刻的理解。

0 commit comments

Comments
 (0)