每日一题之分割链表

![在这里插入图片描述](https://img-在这里插入图片描述
blog.csdnimg.cn/6b961d2814414fa1924f6b2f040cd339.png)

解题思路

  • 找到第一个大于等于x的节点staticNode,之后所有小于x的非法节点都会插入该节点之前
  • 判断staticNode之前是否存在小于x的合法节点。有则将最靠近staticNode的节点设置为vaildNode。没有则为null
  • 双指针遍历链表,从vaildNode开始遍历。找出非法节点,插入validNode之后。同时validNode = validNode.next;
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

function partition(head: ListNode | null, x: number): ListNode | null {
    if(!head) return null;

    let res = head;

    // 找到第一个大于等于x的节点
    let staticNode = head;
    while (staticNode && staticNode.val < x) {
        staticNode = staticNode.next;
    }
    if(!staticNode) return head;

    // 找到第一个合法节点
    let validNode = head.val < staticNode.val ? head : null;

    if (validNode !== null) {
        res = validNode;
        while (validNode.next && validNode.next.val < staticNode.val) {
            validNode = validNode.next;

            if (validNode.next.val >= staticNode.val) {
                break;
            }
        }
    }

    // 找到合法的节点
    let current = head,
        pre = head.next;
    main: while (true) {

        if (validNode) {
            current = validNode;
            pre = validNode.next;
            
        }

        if(!pre) break;

        while (pre.val >= x) {
            pre = pre.next;
            current = current.next;
            if (!pre) {
                break main;
            }
            if (pre.val < x) {
                break;
            }
        }

        if (validNode) {
            current.next = pre.next;
            pre.next = validNode.next;
            validNode.next = pre;
            validNode = validNode.next
        } else {
            current.next = pre.next;
            pre.next = staticNode;
            res = pre;
            validNode = pre;
        }
    }

    return res;
}; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值