链表中删除倒数第K个节点

Posted Viktor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表中删除倒数第K个节点相关的知识,希望对你有一定的参考价值。

问题描述

  分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点。

问题分析与解决

  从问题当中,我们只能得到一个链表和要删除的第K个节点的信息,于是就有以下思路:如果链表为空或者K<0时,直接返回;如若不然,遍历链表的每个节点,每经过一个节点K减1。比如对于1 --> 2 --> 3 --> 4该链表的过程如下:

  K = 5,所遍历的节点以及K值的变化:1 -- > 2 --> 3 --> 4  4,3,2,1;

  K = 4,所遍历的节点以及K值的变化:1 -- > 2 --> 3 --> 4  3,2,1,0;

  K = 3,所遍历的节点以及K值的变化:1 -- > 2 --> 3 --> 4  2,1,0,-1;

  K = 2,所遍历的节点以及K值的变化:1 -- > 2 --> 3 --> 4  1,0,-1,-2;

  由上可知,遍历链表中的节点,每经过一个节点K值减1的过程中,当K > 1时,说明链表中要删除的倒数第K个节点不存在,此时已经超出链表的长度;当K = 0时,此时正好要删除的是链表中的第一个节点,这是只需头节点指向头节点的下一个节点即可;那么对于K < 0时,该如何删除链表中倒数第K的节点呢?

  经过上面的步骤后,如果K<0,此时重新遍历链表,只不过这时是每经过一个节点K值增1。如下示例(K值保存经过减1后的结果):

  K = -1,所遍历的节点以及K值的变化:1  0;

  K = -2,所遍历的节点以及K值的变化:1 -- > 2   -1,0;

  在遍历链表K值增1的过程中,当K = 0时,所在的位置正好是要删除倒数第K个节点的前一个节点,此时只需将前一个节点指向要删除的节点的下一节点即可。

代码实现(单链表):

技术图片
 1 class Node(object):
 2     def __init__(self, data):
 3         self.data = data
 4         self.next = None
 5 
 6 def createSingleLink():
 7     head = Node(1)
 8     cur = head
 9     for i in range(2, 10):
10         cur.next = Node(i)
11         cur = cur.next
12     return head
13 
14 def printSingleLink(head):
15     cur = head
16     while cur:
17         print(cur.data, end=‘‘)
18         if cur.next:
19             print(-->, end=‘‘)
20         cur = cur.next
21 
22 def removeLastKthNode(head, lastKth):
23     if head is None or lastKth < 0:
24         return head
25     cur = head
26     # lastKth -= 1
27     while cur:
28         lastKth -= 1
29         cur = cur.next
30     # print(lastKth)
31     if lastKth == 0:
32         head = head.next
33     if lastKth < 0:
34         cur = head
35         lastKth += 1
36         while lastKth < 0:
37             cur = cur.next
38             lastKth += 1
39         cur.next = cur.next.next
40     return head
41 
42 if __name__ == __main__:
43     singleHead = createSingleLink()
44     printSingleLink(singleHead)
45     print()
46     newSingleHead = removeLastKthNode(singleHead, 6)
47     printSingleLink(newSingleHead)
View Code

  上述代码是对删除单链表倒数第K个节点的实现,那么对于双链表的实现过程和单链表的过程相同,只不过在删除某一节时要注意节点的前驱指针的指向。

代码实现(双链表):

技术图片
 1 class Node(object):
 2     def __init__(self, data):
 3         self.last = None
 4         self.data = data
 5         self.next = None
 6 
 7 def createDoubleLink():
 8     head = Node(1)
 9     cur = head
10     for i in range(2, 10):
11         cur.next = Node(i)
12         cur = cur.next
13     return head
14 
15 def printLink(head):
16     cur = head
17     while cur:
18         print(cur.data, end=‘‘)
19         if cur.next:
20             print(-->, end=‘‘)
21         cur = cur.next
22 
23 def removeLastKthNode(head, lastKth):
24     if head is None or lastKth < 0:
25         return head
26     cur = head
27     while cur:
28         lastKth -= 1
29         cur = cur.next
30     if lastKth == 0:
31         head = head.next
32         head.last = None
33     if lastKth < 0:
34         cur = head
35         lastKth += 1
36         while lastKth < 0:
37             cur = cur.next
38             lastKth += 1
39         if cur.next.next:
40             cur.next = cur.next.next
41             cur.next.last = cur
42         else:
43             cur.next = None
44     return head
45 
46 if __name__ == __main__:
47     doubleLinkHead = createDoubleLink()
48     printLink(doubleLinkHead)
49     print()
50     newDoubleLinkHead = removeLastKthNode(doubleLinkHead, 6)
51     printLink(newDoubleLinkHead)
View Code

 

以上是关于链表中删除倒数第K个节点的主要内容,如果未能解决你的问题,请参考以下文章

算法总结之 在单链表和双链表中删除倒数第k个节点

[算法]在单链表和双链表中删除倒数第k个结点

链表经典面试题(反转链表,中间节点,倒数第k个节点,合并分割链表,删除重复节点)

2.2 在单链表和双链表中删除倒数第K个节点

22 链表中倒数第k个节点(第3章 高质量的代码-代码的鲁棒性)

刷题记录-剑指offer22:链表中倒数第k个节点