链表中删除倒数第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)
上述代码是对删除单链表倒数第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)
以上是关于链表中删除倒数第K个节点的主要内容,如果未能解决你的问题,请参考以下文章
链表经典面试题(反转链表,中间节点,倒数第k个节点,合并分割链表,删除重复节点)