左神算法学习笔记 - 012【入门】链表入门题目-划分链表

8

【算法讲解012【入门】链表入门题目-划分链表】 https://www.bilibili.com/video/BV1SV4y1i76r/?share_source=copy_web&vd_source=939a5033dc1ec4f712d59a4a4042e169

继续一道经典的链表题目,分隔链表。


题目的要求是,给定一个链表和一个值,然后把整个链表按照 < 整个值和 > 这个值进行划分,使得链表左侧是小于这个值的区域,链表右侧是大于这个值的区域。

这个题与「合并两个有序链表」以及「链表相加」的题目一样,都有使用虚拟头节点和不使用两种写法,个人认为使用头节点的版本相对好写一点:

class Solution {
    public ListNode partition(ListNode head, int x) {
        ListNode dummy1 = new ListNode(101);
        ListNode dummy2 = new ListNode(101);

        ListNode p1 = dummy1, p2 = dummy2;
        ListNode p = head;

        while (p != null) {
            if (p.val < x) {
                p1.next = p;
                p1 = p1.next;
            } else {
                p2.next = p;
                p2 = p2.next;
            }

            p = p.next;
        }

        p1.next = dummy2.next;
        p2.next = null; // 这一步是避免最后的链表有环,也就是把右侧的末尾断开即可

        return dummy1.next;
    }
}

左神的版本依旧不推荐使用头节点:

class Solution {
    public ListNode partition(ListNode head, int x) {
        ListNode leftHead = null, leftTail = null;
        ListNode rightHead = null, rightTail = null;
        ListNode next = null;
        
        while (head != null) {
            next = head.next;
            head.next = null;

            if (head.val < x) {
                if (leftHead == null) {
                    leftHead = head;
                } else {
                    leftTail.next = head;
                }
                leftTail = head;
            } else {
                if (rightHead == null) {
                    rightHead = head;
                } else {
                    rightTail.next = head;
                }
                rightTail = head;
            }
            head = next;
        }

        if (leftHead == null) {
            return rightHead;
        }

        leftTail.next = rightHead;

        return leftHead;
    }
}
  • 记住关键点是「小头小尾,大头大尾 + 一个 next 指针」五个变量

  • 然后 head 在链表上遍历

  • 比用头节点麻烦的一点是,需要针对小链表和大链表的 head 一开始为空的情况,做一个判空处理

  • 最后还需要判断一下左边链表有没有,没有就返回右头,有就左连右,返回左头