【每日一题】LeetCode 148. 排序链表 TypeScript

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表

示例 1:

复制代码
输入:head = [4,2,1,3]
输出:[1,2,3,4]

示例 2:

复制代码
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]

示例 3:

复制代码
输入:head = []
输出:[]

提示:

  • 链表中节点的数目在范围 [0, 5 * 104]
  • -105 <= Node.val <= 105

核心思路:

1.找出中心节点,分成两段链表

2.将两段链表进行升序排序

TypeScript 复制代码
/**
 * 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 sortList(head: ListNode | null): ListNode | null {
    if(head===null || head.next===null) return head
    let slow = head
    let fast = head.next
    while(fast!=null && fast.next!=null){
        slow = slow.next
        fast = fast.next.next
    }
    let mid:ListNode | null = slow.next
    slow.next = null
    const left = sortList(head)
    const right = sortList(mid)
    return merge(left,right)
}
function merge(left: ListNode | null,right: ListNode | null): ListNode | null {
    const res = new ListNode(-1)
    let cur = res
    while(left!=null && right!=null){
        if(left.val<right.val){
            cur.next = left
            left= left.next
        }else{
            cur.next = right
            right = right.next
        }
        cur = cur.next
    }
    cur.next = left===null?right:left
    return res.next
}

注释版

TypeScript 复制代码
/**
 * 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 sortList(head: ListNode | null): ListNode | null {
    //这里返回的是head,是因为考虑到head只有一个元素,返回元素本身,递归出口
    if(head===null || head.next===null) return head
    //定义慢指针
    let slow = head
    //初始化快指针 
    let fast = head.next
    //快指针走两步,慢指针走一步
    while(fast!=null && fast.next!=null){
        slow = slow.next
        fast = fast.next.next
    }
    //以slow.next分割,mid是slow指向的下一个
    let mid:ListNode | null = slow.next
    //原链表被分成了(head,slow(包含))、(slow的下一个节点,head末尾)
    slow.next = null
    //再次往下分两段,直到head的长度为0或者1,递归出口
    const left = sortList(head)
    const right = sortList(mid)
    //合并两段链表
    return merge(left,right)
}
 //自定义合并函数
function merge(left: ListNode | null,right: ListNode | null): ListNode | null {
    //创建新链表,装排序后的链表
    const res = new ListNode(-1)
    //链表里的指针
    let cur = res
    //左右链表的长度一致且部委空
    while(left!=null && right!=null){
        //谁小,谁就是cur.next
        if(left.val<right.val){
            cur.next = left
            left= left.next
        }else{
            cur.next = right
            right = right.next
        }
        //自增
        cur = cur.next
    }
    //两个链表长度不同,cur.next指向剩余的链表
    cur.next = left===null?right:left
    //去掉头节点的链表
    return res.next
}

共勉