分别实现两个函数,一个可以删除单链表中倒数第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)