反转链表与分组反转链表

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);
    }


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