反轉鏈表與分組反轉鏈表

1.反轉鏈表

經典的反轉鏈表,先上代碼

public class ListNode {

    int data;
    ListNode next;

    public ListNode(int data) {
        this.data = data;
    }
}


public class PrintList {

    public static void print(ListNode root) {
        while (root != null) {
            System.out.print(root.data + " ");
            root = root.next;
        }
        System.out.println();
    }
}
public class Reverse {

    public ListNode init() {
        ListNode n1 = new ListNode(1);
        ListNode n2 = new ListNode(2);
        ListNode n3 = new ListNode(3);
        n1.next = n2;
        n2.next = n3;
        return n1;
    }

    public ListNode reverse(ListNode root) {
        if (root == null || root.next == null) {
            return root;
        }

        ListNode pre = null, cur = root;
        while (cur != null) {
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }


    public static void main(String[] args) {
        Reverse obj = new Reverse();
        ListNode root = obj.init();
        ListNode result = obj.reverse(root);
        PrintList.print(result);
    }
}

主要步驟爲:
1.將當前節點的next節點保存爲tmp節點。
2.將當前節點的next節點設置爲pre節點(實現反轉)。
3.將pre節點設爲當前節點。
4.將當前節點設爲第一步保存的tmp節點。

2.分組反轉鏈表

給定一個鏈表,每k個節點一組進行反轉,k是正整數,其值小於或等於鏈表長。
如果節點的總數不爲k的整數倍,那麼最後剩餘的節點將保持原有的順序。

例如鏈表爲:
1->2->3->4->5
k=2時,反轉後的結果爲 2->1->4->3->5
k=3時,反轉後的結果爲 3->2->1->4->5

解題思路可以抽象爲:
1.先反轉以 root 開頭的 k 個元素。
2.將第 k + 1 個元素作爲 head 遞歸調用 reverseKGroup 函數(即反轉的函數)
3.將上面兩個過程的結果連接起來。

public class ReverseKs {

    public ListNode init() {
        ListNode n1 = new ListNode(1);
        ListNode n2 = new ListNode(2);
        ListNode n3 = new ListNode(3);
        ListNode n4 = new ListNode(4);
        ListNode n5 = new ListNode(5);
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;
        return n1;
    }

    public ListNode reverse(ListNode a, ListNode b) {
        ListNode pre = null, cur = a;
        while (cur != b) {
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }

        return pre;
    }

    public ListNode reverseKGroup(ListNode root, int k) {
        if (root == null) return null;
        ListNode a = root, b = root;
        for(int i=0; i<k; i++) {
            // 小於 k 個,不需要反轉
            if (b == null) return root;
            b = b.next;
        }
        ListNode newhead = reverse(a, b);
        // 遞歸反轉後續鏈表,連接起來
        a.next = reverseKGroup(b, k);
        return newhead;
    }

    public static void main(String[] args) {
        ReverseKs reverseKs = new ReverseKs();
        ListNode root = reverseKs.init();
        ListNode result = reverseKs.reverseKGroup(root, 3);
        PrintList.print(result);
    }


}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章