Skip to content

Commit 3481546

Browse files
committed
修改和完善部分内容
1 parent 6d156a7 commit 3481546

File tree

1 file changed

+44
-39
lines changed

1 file changed

+44
-39
lines changed

数据结构与算法/Leetcode-LinkList1.md

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ public class Solution {
164164
165165
### 问题分析
166166

167-
首先两个节点/指针,一个节点 node1 先开始跑,指针 node1 跑到 k-1 个节点后,另一个节点 node2 开始跑,当 node1 跑到最后时,node2 所指的节点就是倒数第k个节点。
167+
> **链表中倒数第k个节点也就是正数第(L-K+1)个节点,知道了只一点,这一题基本就没问题!**
168+
169+
首先两个节点/指针,一个节点 node1 先开始跑,指针 node1 跑到 k-1 个节点后,另一个节点 node2 开始跑,当 node1 跑到最后时,node2 所指的节点就是倒数第k个节点也就是正数第(L-K+1)个节点。
168170

169171

170172
### Solution
@@ -180,42 +182,43 @@ public class ListNode {
180182
}
181183
}*/
182184

183-
//时间复杂度O(n),一次遍历即可
184-
//https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
185+
// 时间复杂度O(n),一次遍历即可
186+
// https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
185187
public class Solution {
186-
public ListNode FindKthToTail(ListNode head,int k) {
187-
//如果链表为空或者k小于等于0
188-
if(head==null||k<=0){
189-
return null;
190-
}
188+
public ListNode FindKthToTail(ListNode head, int k) {
189+
// 如果链表为空或者k小于等于0
190+
if (head == null || k <= 0) {
191+
return null;
192+
}
191193
// 声明两个指向头结点的节点
192194
ListNode node1 = head, node2 = head;
193-
//记录节点的个数
194-
int count=0;
195-
//记录k值,后面要使用
196-
int index=k;
197-
//p指针先跑,并且记录节点数,当node1节点跑了k-1个节点后,node2节点开始跑,
198-
//当node1节点跑到最后时,node2节点所指的节点就是倒数第k个节点
199-
while(node1!=null){
200-
node1=node1.next;
201-
count++;
202-
if(k<1){
203-
node2=node2.next;
204-
}
205-
k--;
206-
}
207-
//如果节点个数小于所求的倒数第k个节点,则返回空
208-
if(count<index) return null;
209-
return node2;
210-
211-
}
212-
}
195+
// 记录节点的个数
196+
int count = 0;
197+
// 记录k值,后面要使用
198+
int index = k;
199+
// p指针先跑,并且记录节点数,当node1节点跑了k-1个节点后,node2节点开始跑,
200+
// 当node1节点跑到最后时,node2节点所指的节点就是倒数第k个节点
201+
while (node1 != null) {
202+
node1 = node1.next;
203+
count++;
204+
if (k < 1 && node1 != null) {
205+
node2 = node2.next;
206+
}
207+
k--;
208+
}
209+
// 如果节点个数小于所求的倒数第k个节点,则返回空
210+
if (count < index)
211+
return null;
212+
return node2;
213213

214+
}
215+
}
214216
```
215217

216218

217219
# 4. 删除链表的倒数第N个节点
218220

221+
219222
> Leetcode:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
220223
221224
**示例:**
@@ -239,15 +242,16 @@ public class Solution {
239242

240243
### 问题分析
241244

242-
我们注意到这个问题可以容易地简化成另一个问题:删除从列表开头数起的第 (L - n + 1)个结点,其中 LL 是列表的长度。只要我们找到列表的长度 L,这个问题就很容易解决。
245+
246+
我们注意到这个问题可以容易地简化成另一个问题:删除从列表开头数起的第 (L - n + 1)个结点,其中 L是列表的长度。只要我们找到列表的长度 L,这个问题就很容易解决。
243247

244248
![图 1. 删除列表中的第 L - n + 1 个元素](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-20/94354387.jpg)
245249

246250
### Solution
247251

248252
**两次遍历法**
249253

250-
首先我们将添加一个 **哑结点** 作为辅助,该结点位于列表头部。哑结点用来简化某些极端情况,例如列表中只含有一个结点,或需要删除列表的头部。在第一次遍历中,我们找出列表的长度 L。然后设置一个指向哑结点的指针,并移动它遍历列表,直至它到达第 (L - n) 个结点那里。我们把第 (L - n)个结点的 next 指针重新链接至第 (L - n + 2)个结点,完成这个算法。
254+
首先我们将添加一个 **哑结点** 作为辅助,该结点位于列表头部。哑结点用来简化某些极端情况,例如列表中只含有一个结点,或需要删除列表的头部。在第一次遍历中,我们找出列表的长度 L。然后设置一个指向哑结点的指针,并移动它遍历列表,直至它到达第 (L - n) 个结点那里。**我们把第 (L - n)个结点的 next 指针重新链接至第 (L - n + 2)个结点,完成这个算法。**
251255

252256
```java
253257
/**
@@ -286,16 +290,18 @@ public class Solution {
286290
}
287291
```
288292

289-
复杂度分析:
293+
**复杂度分析:**
290294

291-
- 时间复杂度 O(L) :该算法对列表进行了两次遍历,首先计算了列表的长度 LL 其次找到第 (L - n)(L−n) 个结点。 操作执行了 2L-n2L−n 步,时间复杂度为 O(L)O(L)。
292-
293-
- 空间复杂度 O(1) :我们只用了常量级的额外空间。
295+
- **时间复杂度 O(L)** :该算法对列表进行了两次遍历,首先计算了列表的长度 LL 其次找到第 (L - n)(L−n) 个结点。 操作执行了 2L-n2L−n 步,时间复杂度为 O(L)O(L)。
296+
- **空间复杂度 O(1)** :我们只用了常量级的额外空间。
294297

295298

296299

297300
**进阶——一次遍历法:**
298301

302+
303+
> **链表中倒数第N个节点也就是正数第(L-N+1)个节点。
304+
299305
其实这种方法就和我们上面第四题找“链表中倒数第k个节点”所用的思想是一样的。**基本思路就是:** 定义两个节点 node1、node2;node1 节点先跑,node1节点 跑到第 n+1 个节点的时候,node2 节点开始跑.当node1 节点跑到最后一个节点时,node2 节点所在的位置就是第 (L-n ) 个节点(L代表总链表长度,也就是倒数第 n+1 个节点)
300306

301307
```java
@@ -315,17 +321,17 @@ public class Solution {
315321
// 声明两个指向头结点的节点
316322
ListNode node1 = dummy, node2 = dummy;
317323

318-
// node1 节点先跑,node1节点 跑到第 n+1 个节点的时候,node2 节点开始跑
319-
//当node1 节点跑到最后一个节点时,node2 节点所在的位置就是第 (L-n ) 个节点(L代表总链表长度,也就是倒数第 n+1 个节点
324+
// node1 节点先跑,node1节点 跑到第 n 个节点的时候,node2 节点开始跑
325+
// 当node1 节点跑到最后一个节点时,node2 节点所在的位置就是第 (L-n ) 个节点,也就是倒数第 n+1(L代表总链表长度
320326
while (node1 != null) {
321327
node1 = node1.next;
322-
if (n < 0) {
328+
if (n < 1 && node1 != null) {
323329
node2 = node2.next;
324330
}
325331
n--;
326332
}
327333

328-
node2.next = node2.next.next;
334+
node2.next = node2.next.next;
329335

330336
return dummy.next;
331337

@@ -389,4 +395,3 @@ public ListNode Merge(ListNode list1,ListNode list2) {
389395
}
390396
```
391397

392-

0 commit comments

Comments
 (0)