1. 程式人生 > >連結串列問題——在單鏈表和雙鏈表中刪除倒數第K個節點

連結串列問題——在單鏈表和雙鏈表中刪除倒數第K個節點

【題目】
  分別實現兩個函式,一個可以刪除單鏈表中倒數第K個節點,另一個可以刪除雙鏈表中倒數第K個節點。

【要求】
  如果連結串列長度為N,時間複雜度達到O(N),時間複雜度達到O(N),額外空間複雜度達到O(1)

【解答】
  本題較為簡單,實現方式也是多種多樣的,這裡只介紹一種方法。
  先來看看單鏈表如何調整。如果連結串列為空或者K值小於1,這種情況下,引數是無效的,直接返回即可。除此之外,讓連結串列從頭開始走到尾,每移動一步,就讓k的值減1。
  連結串列:1->2->3,K=4,連結串列根本不存在倒數第4個節點。
  走到的節點:1->2->3
  K變化為:3 2 1
  
  連結串列:1->2->3,K=3,連結串列倒數第3個節點是1節點
  走到的節點:1->2->3
  K變化為:2 1 0
  
  連結串列:1->2->3,K=2,連結串列倒數第2個節點是2節點
  走到的節點:1->2->3
  K變化為:1 0 -1
  
  由以上三種情況可知,讓連結串列從頭開始走到尾,每移動一步,就讓K值減1,當連結串列走到結尾時,如果K值大於0,說明不用調整連結串列,因為連結串列根本沒有倒數第K個節點,此時將原連結串列直接返回即可;如果K值等於0,說明連結串列倒數第K個節點就是頭結點,此時直接返回head.next,也就是原連結串列的第二個節點,讓第二個節點作為連結串列的頭返回即可,相當於刪除頭節點;接下來,說明一下如果K值小於0,該如何處理。
  先明確一點,如果要刪除連結串列的頭結點之後的某個節點,實際上需要找到要刪除節點的前一個節點,比如:1->2->3,如果想刪除節點2,則需要找到節點1,然後把節點1連到節點3上(1->3),以此來打到刪除節點2的目的。
  如果K值小於0,如何找到要刪除節點的前一個節點呢?方法如下:
  1.重新從頭節點開始走,每移動一步,就讓K的值加1。
  2.當K等於0是,移動停止,移動到的節點就是要刪除節點的前一個節點。

【程式碼實現】

public class Node{
    public int value;
    public Node next;

    public Node(int data){
        this.value = data;
    }
}

public Node removeLastKthNode(Node head,int lastKth){
    if(head == null || lastKth < 1){
        return head;
    }
    Node cur = head;
    while(cur != null
){ lastKth--; cur = cur.next; } if(lastKth==0){ head = head.next; } if(lastKth<0){ cur = head; while(++lastKth!=0){ cur = cur.next; } cur.next = cur.next.next; } return head; }

雙鏈表的調整和單鏈表的處理幾乎一樣,只需要注意雙鏈表的刪除和單鏈表的刪除不一樣就好了

【程式碼實現】

public class DoubleNode{
    public int value;
    public DoubleNode last;
    public DoubleNode next;

    public DoubleNode(int data){
        this.value = data;
    }
}

public DoubleNode removeLastKthNode(DoubleNode head,int lastKth){
    if(head==null || lastKth < 1){
        return head;
    }
    DoubleNode cur = head;
    while(cur!=null){
        lastKth--;
        cur = cur.next;
    }
    if(lastKth==0){
        head = head.next;
        head.last = null;
    }
    if(lastKth<0){
        cur = head;
        while(++lastKth!=0){
            cur = cur.next;
        }
        DoubleNode newNext = cur.next.next;
        cur.next = newNext;
        if(newNext!=null){
            newNext.last = cur;
        }
    }
    return head;
}