首页 > 其他分享 >【归并排序】【链表】LeetCode 148. 排序链表

【归并排序】【链表】LeetCode 148. 排序链表

时间:2022-12-30 21:33:15浏览次数:64  
标签:head slow ListNode next 链表 排序 LeetCode left

题目链接

148. 排序链表

思想

  • 分割 cut 环节: 找到当前链表中点,并从中点将链表断开(以便在下次递归 cut 时,链表片段拥有正确边界)

    • 我们使用 fast,slow 快慢双指针法,奇数个节点找到中点,偶数个节点找到中心左边的节点。

    • 找到中点 slow 后,执行 slow.next = None 将链表切断。

    • 递归分割时,输入当前链表左端点 head 和中心节点 slow 的下一个节点 mid(因为链表是从 slow 切断的)。

    • cut 递归终止条件: 当head.next == None时,说明只有一个节点了,直接返回此节点。

  • 合并 merge 环节: 将两个排序链表合并,转化为一个排序链表。

    • 双指针法合并,建立辅助ListNode dummy 作为头部。

    • 设置两指针 left, right 分别指向两链表头部,比较两指针处节点值大小,由小到大加入合并链表头部,指针交替前进,直至添加完两个链表。

    • 返回辅助ListNode dummy 作为头部的下个节点 dummy.next。

    • 时间复杂度 O(l + r),l, r 分别代表两个链表长度。

  • 当题目输入的 head == None 时,直接返回None。

image

代码

class Solution {
    public ListNode sortList(ListNode head) {

        // end condition
        if (head == null || head.next == null) {
            return head;
        }

        // find the middle node
        ListNode slow = head;
        ListNode fast = head.next;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode mid = slow.next;

        // split the list into two parts
        slow.next = null;
        ListNode left = sortList(head);
        ListNode right = sortList(mid);

        // sort the two parts
        ListNode dummy = new ListNode(0);
        ListNode p = dummy;

        while (left != null && right != null) {
            if (left.val < right.val) {
                p.next = left;
                left = left.next;
            } else {
                p.next = right;
                right = right.next;
            }
            p = p.next;
        }

        // merge the two parts
        if (left != null) {
            p.next = left;
        } else {
            p.next = right;
        }

        return dummy.next;
    }
}

标签:head,slow,ListNode,next,链表,排序,LeetCode,left
From: https://www.cnblogs.com/shixuanliu/p/17015854.html

相关文章

  • 【LeetCode数组#3有序数组的平方】有序数组平方
    有序数组的平方力扣题目链接(opensnewwindow)给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。示例1:输入:num......
  • 算法刷题 Day 3 | 203.移除链表元素 & 707.设计链表 & 206.反转链表
    203.移除链表元素建议:本题最关键是要理解虚拟头结点的使用技巧,这个对链表题目很重要。Tips:这道题本身没有什么难度,回顾一下链表的定义和虚拟头节点的使用即可我的......
  • #yyds干货盘点# LeetCode程序员面试金典:配对交换
    题目:配对交换。编写程序,交换某个整数的奇数位和偶数位,尽量使用较少的指令(也就是说,位0与位1交换,位2与位3交换,以此类推)。示例1:输入:num=2(或者0b10)输出1(或者0b01)示例2:......
  • #yyds干货盘点# LeetCode程序员面试金典:绘制直线
    题目:已知一个由像素点组成的单色屏幕,每行均有 w​ 个像素点,所有像素点初始为 0​,左上角位置为 (0,0)。现将每行的像素点按照「每 32​ 个像素点」为一组存放在一个 i......
  • 21. 合并两个有序链表
    背景这个题目一般用来学习数据结构时练手用。但我们今天只研究递归,按tag刷。题目链接:https://leetcode.cn/problems/merge-two-sorted-lists/description/递归解题一般......
  • 有向图的拓扑排序——DFS
    在有向图的拓扑排序——BFS这篇文章中,介绍了有向图的拓扑排序的定义以及使用广度优先搜索(BFS)对有向图进行拓扑排序的方法,这里再介绍另一种方法:深度优先搜索(DFS)。算法考虑......
  • 递归移除链表元素、翻转链表(leetcode easy 203、206)、设计链表(leetcode medium 707
    移除链表元素题目链接:https://leetcode.cn/problems/remove-linked-list-elements/思路:主要考虑移除元素后需要让被移除元素前置节点的next指向其后置节点,采用......
  • 归并排序 以及衍生作品 逆序数统计
     首先介绍归并排序: 国际惯例,我引入比喻,各位看官随意听听抽象代师。 我将归并排序比喻成“斗兽场排序”,什么意思呢?就是将原来的一个数组一分为二,将数字比喻斗士,A组B......
  • leetcode-557. 反转字符串中的单词 III
    557.反转字符串中的单词III-力扣(Leetcode)与代码[[leetcode-541.反转字符串II]]相关联,swapStrBytes函数,使用了上次的代码funcreverseWords(sstring)string{......
  • leetcode-551. 学生出勤记录 I
    551.学生出勤记录I-力扣(Leetcode)字符串序列计数funccheckRecord(sstring)bool{absentCnt:=0cLateCnt:=0fori:=0;i<len(s);i++{......