[路飞][LeetCode]148_排序链表

122 阅读1分钟

「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战

看一百遍美女,美女也不一定是你的。但你刷一百遍算法,知识就是你的了~~

谁能九层台,不用累土起!

题目地址

题目

给你链表的头结点 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

解题思路

老规矩能暴力解就暴力解

  • 我们将链表转换成数组
  • 对数组进行排序
  • 重新组成链表

解题代码

var sortList = function(head) {
    if(!head) return head
    let arr = []
    while(head){
        let temp = head.next
        head.next = null
        arr.push(head)
        head = temp
    }
   
    arr.sort((a,b)=> a.val-b.val)
    arr.forEach((v,i)=>{
        v.next = arr[i+1]||null
    })
    return arr[0]
};

归并排序

  • 我们定义两个指针,一个快指针一个慢指针
  • 快指针每次走2个节点,慢指针每次1一个节点
  • 当快指针到链表尾部时,慢指针到达中心点
  • 以中心点将链表分成两段
  • 将其排序后组成一个新的有序链表
var sortList = function(head) {
   if(!head||!head.next) return head  // 处理需要排查的逻辑

    let slow = head
    let fast = head.next
    while(fast&&fast.next){ // 双指针寻找中心位置
        slow = slow.next
        fast = fast.next.next
    }
    let mid = slow.next
    slow.next = null

    let left = sortList(head) 
    let right = sortList(mid)
    let res = new ListNode(-1)  //生成虚拟头节点
    let vhead = res

    while(left&&right){  // 合并链表只需要调整指针的指向
        // 连接较小的节点
        if(left.val<right.val){
            vhead.next = left
            left = left.next
        }else{
            vhead.next = right
            right = right.next
        }
        vhead = vhead.next 
    }
    vhead.next = left ===null?right:left // 将left的尾结点与right相连,从而完成链表的组合
    return res.next
};

许是她在江湖看了太多风景 而你刚好是她想停留的一处 总有离别的时候 说她也是说你。

如有任何问题或建议,欢迎留言讨论!