leecode-面试题 02.04. 分割链表

36 阅读2分钟

前言

记录一下算法的学习

题目描述

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

你不需要 保留 每个分区中各节点的初始相对位置。

示例 1:

输入: head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

示例 2:

输入: head = [2,1], x = 2
输出:[1,2]

 

提示:

  • 链表中节点的数目在范围 [0, 200] 内
  • -100 <= Node.val <= 100
  • -200 <= x <= 200

解题思路

  1. 根据题意,只需要分割两个区域,分别是小于x值的区域small,大于等于x的区域large
  2. 题目中有一个条件,我们可以不保留两个区域的初始节点位置
  3. 通过遍历整个链表,将小于x的放入small,将大于等于x的放入large
  4. 当遍历完成后,只需要把small的next指向large的头节点

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} x
 * @return {ListNode}
 */
var partition = function (head, x) {
    // 1. 创建两个区块,还需要创建2个区块的头节点,方便拼接
    let small = new ListNode(0)
    const smallHead = small // 初始指向small
    let large = new ListNode(0)
    const largeHead = large
    // 循环遍历head
    while (head) {
        // 判断x
        if (head.val < x) {
            small.next = head
            small = small.next
        }else {
            large.next = head
            large = large.next
        }
        head = head.next
    }
    // 需要讲large.next 指向 null,
    // 由于我们的large指向的是head引用,需要清空,防止next为小于x的节点
    large.next = null
    // 遍历完成后,将两个区块拼接
    small.next = largeHead.next
    // 返回smallHead的next,因为smallHead的头节点为我们创建的节点
    return smallHead.next
 }

复杂度分析

  • 时间复杂度:需要遍历n长度所以时间复杂度为O(n)
  • 空间复杂度:为常数 O(1)

最后

每天进步一点点