天天AC系列(十):兩兩交換鏈表中的節點

1 題目

LeetCode第24題,交換鏈表的相鄰節點.
在這裏插入圖片描述java

2 直接交換

直接交換的思想很簡單,遍歷一次鏈表,進行兩兩交換.node

ListNode newHead = new ListNode(0);
newHead.next = head;
ListNode before = newHead;
ListNode first = head;
ListNode second = head.next;
ListNode move;

while(true)
{
    move = second.next;
    first.next = second.next;
    second.next = first;

    before.next = second;
    before = first;

    first = move;

    if(move != null && move.next != null)
    {
        second = move.next;
        move = move.next.next;
    }
    else 
        break;
}
return newHead.next;

雖然思想簡單,可是,並很差實現,有點繞,首先增長一個頭節點,first,second當前要交換的兩個節點,before爲first的前一個節點,用來連上first,move是爲了更新first與second節點的節點,進入while循環後,首先把first與second交換,接着用before連上first同時更新before,而後利用move更新first與second.
在這裏插入圖片描述git

3 遞歸交換

遞歸交換就是每次只交換頭兩個節點,而後把第三個節點做爲下一次遞歸交換的頭結點繼續遞歸交換.github

if(head != null && head.next != null)
{
    ListNode t = head.next;
    head.next = swapPairs(t.next);
    t.next = head;
    return t;
}
return head;

要注意交換的順序,先賦值head.next,head.next爲剩下的節點,而後把t連上head.
在這裏插入圖片描述ide

4 插入法

新建一個鏈表,採用尾插法,依次插入交換的節點.
對於原鏈表設置兩個指針a與b,令a指向首個節點,b指向第二個節點,而後對於新鏈表,先插入b,再插入a,最後更新a,b,使a,b都指向後繼的後繼,這樣依次插入b與a就會獲得所需的鏈表.優化

if(head == null || head.next == null)
    return head;
ListNode a = head;
ListNode b = head.next;
ListNode newHead = new ListNode(0);
ListNode t = newHead;
while(a != null && b != null)
{
    t.next = new ListNode(b.val);
    t = t.next;
    t.next = new ListNode(a.val);
    t = t.next;
    if(b.next != null)
        b = b.next.next;
    a = a.next.next;
}
if(a != null)
    t.next = new ListNode(a.val);
return newHead.next;

在更新a,b時,對於a不須要判斷a.next是否爲空,由於a.next確定爲b,確定不爲空,可是對於b,當到達最後一個節點時,b.next爲空,所以須要加上判斷.當a,b其中一個爲空後跳出循環,最後的判斷a是否爲空表示節點個數爲奇數,此時a指向最後一個節點,直接插入a.
在這裏插入圖片描述3d

5 插入法改進

對於上面的插入法,因爲ab是連在一塊兒的,所以能夠只使用其中一個,再優化判空與插入操做.指針

ListNode newHead = new ListNode(0);
ListNode t = newHead;
while(head != null)
{
    if(head.next != null)
    {
        t.next = new ListNode(head.next.val);
        t = t.next;
    }
    t.next = new ListNode(head.val);
    t = t.next;
    if(head.next == null)
        break;
    head = head.next.next;
}
return newHead.next;

要注意while中的判空條件,由於節點的個數有多是奇數,在插入後一個節點前須要先判斷是否爲空,再插入前一個節點.
在這裏插入圖片描述code

6 源碼

githubblog

碼雲

相關文章
相關標籤/搜索