「前端刷题」86. 分隔链表

272 阅读2分钟

「这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战」。

题目

链接:leetcode-cn.com/problems/pa…

给你一个链表的头节点 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

  • 这道题理解指针和链表之间的引用关系非常重要
  • 参考了大神的代码之后有个疑问就是这里只是修改指针的next节点,为什么链表也会被修改
  • smallPoint.next = cur //smallPoint指向before,实际等于before.next = cur
  • smallPoint = smallPoint.next //smallPoint的指向改变了,指向了before的next, 这时before的next和 smallPoint指向同一对象。

代码

/**
 * 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) {
    const listNode = new ListNode(0)
    listNode.next = head
    let before = new ListNode(0)
    let after = new ListNode(0)
    let smallPoint = before
    let bigPoint = after
    let cur = listNode.next
    while (cur) {
        if (cur.val >= x) {
            bigPoint.next = cur
            bigPoint = bigPoint.next
        } else {
            smallPoint.next = cur
            smallPoint = smallPoint.next
        }
        cur = cur.next
    }
    bigPoint.next = null
    smallPoint.next = after.next
    return before.next
};

思路2

楼主首先想到的是借助空间,把大于x的归为一链,把小于x的归为一链。最后把大的链表,接到小的链表后面。搞定。
所以直接遍历链表,复制节点,操作链接。啪,很快。

时间复杂度

O(n)

空间复杂度

O(n)

代码

/**
 * 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) {
    let ltX = {next: null}, gtX = {next: null};
    let lastltX = ltX, lastgtY = gtX;
    while (head) {
        let node = new ListNode(head.val);
        if (head.val < x) {
            lastltX.next = node;
            lastltX = node;
        } else {
            lastgtY.next = node;
            lastgtY = node;
        }
        head = head.next;
    }
    lastltX.next = gtX.next;
    return ltX.next;
};

思路3

  1. 如果头没有直接返回null
  2. 定义大小两个节点
  3. 定义大小两个指针
  4. for循环进行比较,如果比指定值小的放在小链表里,大的放在大链表里
  5. 拼接链表

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} x
 * @return {ListNode}
 */
var partition = function(head, x) {
    if(!head){return null};
    let big= new ListNode(), small = new ListNode();
    let bigNode = big, smallNode = small;
    for(let cur=head,next;cur; cur=next){
        next = cur.next;
        cur.next = null;
        if(cur.val < x){
            smallNode.next = cur;
            smallNode=cur;
        }else{
            bigNode.next = cur;
            bigNode = cur;
        }
    }
    smallNode.next = big.next;
    return small.next

};