牛客-NC70-单链表的排序

NC70. 单链表的排序(easy)


方法一:归并排序(递归)

思路:这道题考察链表排序问题,朴素解法(暴力解)是直接遍历存值再遍历修改值;但更容易打动面试官的可能是归并排序了吧。
我们分两步完成该题,首先是分割,怎么分?需要使用快慢指针去寻找链表的中点,然后以中点为分割点,将链表分为左链表和右链表。再递归进行分割,当head == null || head.next == null达到递归终止条件。如下图的递归终止图,ps:图片来自于K神
举个例子:left = 3, right = 2时,此时,我们需要进行归并排序,也就是图中的merge操作,合并结束后进行回调,最终我们能够完成整个链表的排序。可以写出以下代码:

import java.util.*;

/* * public class ListNode { * int val; * ListNode next = null; * } */

public class Solution {
   
    /** * * @param head ListNode类 the head node * @return ListNode类 */
    public ListNode sortInList (ListNode head) {
   
        // write code here
        if (head == null || head.next == null) {
   
            return head;
        }
        ListNode slow = head;
        ListNode fast = head.next;
        while (fast != null && fast.next != null) {
   
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode mid = slow.next; // 后半部分
        slow.next = null;

        ListNode left = sortInList(head); // 左部分
        ListNode right = sortInList(mid); // 右部分
        ListNode hummyNode = new ListNode(-1);
        ListNode cur = hummyNode;
        while (left != null && right != null) {
   
            if (left.val >= right.val) {
   
                cur.next = right;
                right = right.next;
            } else {
   
                cur.next = left;
                left = left.next;
            }
            cur = cur.next;
        }
        cur.next = left != null ? left : right;
        return hummyNode.next;
    }
}

时间复杂度: O(nlogn),归并排序时间复杂度。
空间复杂度: O(logn),递归调用函数将带来O(logn)的空间复杂度。
总结:这道题归并方法应该算是最优解,但递归的归并排序并不是最优解,这里分享给大家一个能够达到O(1)的空间复杂度的归并方法,K神

全部评论

相关推荐

coffrar:全都是已读😅沟通一千五百多个了
点赞 评论 收藏
分享
01-26 22:20
已编辑
门头沟学院 Java
Java抽象带篮子:项目很nb了,现在好好准备八股和算法吧,早点找实习,可以看看我的置顶帖子。帖子里写了怎么改简历,怎么包装实习经历,还有2个高质量可速成的项目话术,和我的牛客八股笔记专栏
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务