「力扣」第 86 题:分隔链表(中等)


「力扣」第 86 题:分隔链表(中等)

链接:https://leetcode-cn.com/problems/partition-list

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

思路:分别拿两个虚拟头结点,最后拼在一起。

![image-20191204142152454](/Users/liwei/Library/Application Support/typora-user-images/image-20191204142152454.png)Java 代码:

class ListNode {
    int val;
    ListNode next;

    // 空间复杂度为常数的解法:穿针引线

    public ListNode(int[] nums) {
        if (nums == null || nums.length == 0) {
            throw new IllegalArgumentException("arr can not be empty");
        }
        this.val = nums[0];
        ListNode curr = this;
        for (int i = 1; i < nums.length; i++) {
            curr.next = new ListNode(nums[i]);
            curr = curr.next;
        }
    }

    @Override
    public String toString() {
        StringBuilder s = new StringBuilder();
        ListNode cur = this;
        while (cur != null) {
            s.append(cur.val);
            s.append(" -> ");
            cur = cur.next;
        }
        s.append("NULL");
        return s.toString();
    }
}

public class Solution {

    // 空间复杂度为常数的解法:穿针引线

    public ListNode partition(ListNode head, int x) {
        // 比 x 小的虚拟头结点
        ListNode dummyNodeL = new ListNode(-1);
        // 大于等于 x 的虚拟头结点
        ListNode dummyNodeR = new ListNode(-1);
        // 用于遍历
        ListNode curL = dummyNodeL;
        // 用于遍历
        ListNode curR = dummyNodeR;
        int val;
        while (head != null) {
            val = head.val;
            // 接在 L 的后面
            if (val < x) {
                curL.next = head;
                curL = curL.next;
            } else {
                // 接在 R 的后面
                curR.next = new ListNode(val);
                curR = curR.next;
            }
            head = head.next;
        }
        curL.next = dummyNodeR.next;
        // 特别注意:最后这一步不能忘记,否则会产生一个循环链表
        curR.next = null;
        return dummyNodeL.next;
    }

    public static void main(String[] args) {
        int[] nums = {1, 4, 3, 2, 5, 2};
        int x = 3;
        ListNode head = new ListNode(nums);
        Solution solution = new Solution();
        System.out.println("分隔链表之后:");
        ListNode partition = solution2.partition(head, x);
        System.out.println(partition);
    }
}

Python 代码:(反例)

# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None


class Solution(object):

    # 不是穿针引线,缺点:partition 的时候复制了结点

    def partition(self, head, x):
        """
        :type head: ListNode
        :type x: int
        :rtype: ListNode
        """

        dummy_node_l = ListNode(-1)
        dummy_node_r = ListNode(-1)

        cur_l = dummy_node_l
        cur_r = dummy_node_r

        while head is not None:
            val = head.val

            if val < x:
                cur_l.next = ListNode(val)
                cur_l = cur_l.next
            else:
                cur_r.next = ListNode(val)
                cur_r = cur_r.next

            head = head.next
        # 把较小的链表接在较大的链表后面,这一步容易忘记
        cur_l.next = dummy_node_r.next
        return dummy_node_l.next

文章作者: liweiwei1419
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 liweiwei1419 !
评论
 上一篇
「力扣」第 92 题:反转链表 II 「力扣」第 92 题:反转链表 II
「力扣」第 92 题:反转链表 II 链接 题解链接 反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。 说明:1 ≤ m ≤ n ≤ 链表长度。 示例: 输入: 1->2->3->4->5->NUL
下一篇 
「力扣」第 83 题:删除排序链表中的重复元素(简单) 「力扣」第 83 题:删除排序链表中的重复元素(简单)
「力扣」第 83 题:删除排序链表中的重复元素(简单) 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list; 传送门:删除排序链表中的重复元素。
  目录