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

来源:互联网 发布:windows loader好用吗 编辑:程序博客网 时间:2024/06/05 20:24

【题目】

  在单链表和双链表中删除倒数第K个节点。
  要求时间复杂度O(N),空间复杂度O(1)。

【基本思路】

  方法一。
  从链表头开始走到尾,每移动一步,k减1。移动完之后,如果k > 0,说明链表长度不够k,根本就没有倒数第k个值,返回头节点 head;如果k = 0,说明链表的长度等于k,头节点就是倒数第k个节点,返回 head.next;如果 k < 0,说明链表的长度大于k,再次从头遍历链表,这时,每遍历一步就让k加1,当 k = 0时,遍历到的节点就是倒数第k个节点的前一个节点,之后删除倒数第k个节点就很容易了。  
  为什么这么做是可行的?因为如果链表长度是N,要删除倒数第k个节点,显而易见,第N - k个节点就是倒数第k个节点的前一个节点。第一次遍历的完后,k的值变为k - N,第二次遍历的终止条件是k = 0,显然,k - N 加上 N - k 等于0,也就是说,k = 0的时候,实际上就是遍历了N - k个节点。所以当 k = 0时,遍历到的节点就是倒数第k个节点的前一个节点。

  方法二。
  设置两个指针 fast 、slow,fast先走k步,如果走不到第k步(None节点是可以走到的,但是None节点没有next,所以只能走到None),说明链表长度不够k,直接返回head;如果走到第k步,发现该节点是None节点,说明链表的长度等于k,头节点就是倒数第k个节点,返回 head.next;否则,令 fast 和 slow 开始同步往下移动,直到 fast 移动到最后一个节点(不包含None),此时slow就是倒数第 k 个节点的前一个节点,之后删除倒数第k个节点就很容易了。

  单链表和双链表删除倒数第k个节点的原理是一样的,只不过是双链表删除节点的时候稍微复杂一点。

【代码实现】

#python3.5#单链表class Node:    def __init__(self, val=None):        self.val = val        self.next = Nonedef removeLastKthNode1(head, k):    if head == None or k < 1:        return head    cur = head    while cur != None:        k -= 1        cur = cur.next    if k == 0:        return head.next    elif k < 0:        cur = head        while k+1 != 0:            cur = cur.next            k += 1        cur.next = cur.next.next    return headdef removeLastKthNode2(head, k):    if head == None or k < 1:        return head    fast = slow = head    while k > 0:        k -= 1        if fast == None:            return head        else:            fast = fast.next    if fast == None:        return head.next    while fast.next != None:        fast = fast.next        slow = slow.next    slow.next = slow.next.next    return head#双链表class DoubleNode:    def __init__(self, val = None):        self.val = val        self.pre = None        self.next = Nonedef removeLastKthDoubleNode1(head, k):    if head == None or k < 1:        return head    cur = head    while cur != None:        k -= 1        cur = cur.next    if k == 0:        head = head.next        head.pre = None    elif k < 0:        cur = head        while k+1 != 0:            k += 1            cur = cur.next        cur.next = cur.next.next        if cur.next != None:            cur.next.pre = cur    return headdef removeLastKthDoubleNode2(head, k):    if head == None or k < 1:        return head    fast = slow = head    while k > 0:        k -= 1        if fast != None:            fast = fast.next        else:            return head    if fast == None:        head = head.next        head.pre = None    else:        while fast.next != None:            slow = slow.next            fast = fast.next        slow.next = slow.next.next        if slow.next != None:            slow.next.pre = slow    return head
阅读全文
2 0
原创粉丝点击