排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

题解:归并排序

          

         

                       

 

                                                   

               

 

               

                                                         

                            

                       

                       

                    

之后就依次类推:(merge操作可以参考之前的博客:合并两个有序链表

上代码Java 

public class Solution2
 {
	 public ListNode sortList(ListNode head)
	 {
		 if (head == null || head.next == null) 
		 {
			 return head;
		} 
		// 这里设置 64 ,是一个绰绰有余的数字,可以满足结点数量为 2^64 这么多的单链表的排序
		ListNode[] counter = new ListNode[64];
		ListNode curNode = head; 
		// 遍历到的最大的 counter 数组的索引
		int maxIndex = 0; 
		while (curNode != null) 
		{ 
			// 先把当前元素暂存起来,马上我们就要把它放到 counter 数组合适的位置上 
			ListNode carryNode = curNode;
			// curNode 指针马上后移,方便下次处理 
			curNode = curNode.next; 
			// 拿出的节点就和原来的链表没有关系了,我们在 counter 数组中完成排序,所以要切断它和原链表的关系 
			carryNode.next = null;
			// 尝试从 counter 数组 0 号索引开始放置 
			int i = 0;
			// 只要非空当前位置非空,就进行一次 merge,merge 以后尝试放到下一格,如果下一格非空就继续合并 
			// 合并以后再尝试放到下一格,直到下一格为空,直接放在那个为空的下一格就好
			while (counter[i] != null) 
			{
				ListNode newMergeNode = mergeOfTwoSortedListNode(carryNode, counter[i]);
				counter[i] = null; i++; carryNode = newMergeNode; 
			}
			// 遇到了空,就把 carryNode 放在数组的这个位置上
			counter[i] = carryNode; 
			// 记录最多使用到 counter 数组的第几位,最后合并的时候要用上
			if (i > maxIndex) 
			{
				maxIndex = i; 
			}
		}
		// 遍历整个 count 数组,将它们全部归并,这个操作就和归并 n 个有序单链表是一样的了,我们这里采用两两归并 
		// 还可以采用 LeetCode 第 23 题的办法完成这一步 
		// 参考:https://liweiwei1419.github.io/leetcode-solution/leetcode-0023-merge-k-sorted-lists/ 
		ListNode res = null;
		for (int i = 0; i <= maxIndex; i++) 
		{
			if (counter[i] != null)
			{
				res = mergeOfTwoSortedListNode(res, counter[i]);
			} 
		} 
		return res; 
	} /**
     * 归并两个已经排好序的单链表,是我们非常熟悉的操作了,可以递归完成,也可以穿针引线,这里我们递归完成
     *
     * @param l1 顺序存放的单链表1
     * @param l2 顺序存放的单链表2
     * @return 合并以后的单链表
     */ 
	 private ListNode mergeOfTwoSortedListNode(ListNode l1, ListNode l2) 
	 {
		 if (l1 == null) 
		 { 
			return l2; 
		 } 
		 if (l2 == null) 
		 {
			 return l1; 
		} 
		if (l1.val < l2.val) 
		{ 
			l1.next = mergeOfTwoSortedListNode(l1.next, l2);
			return l1; 
		} 
		else 
		{ 
			l2.next = mergeOfTwoSortedListNode(l1, l2.next); 
			return l2;
		} 
	} 
	public static void main(String[] args) 
	{
		int[] nums = new int[]{9, 8, 2, 7, 6, 5, 4, 3, 1};
		ListNode head = new ListNode(nums);
		Solution2 solution2 = new Solution2();
		ListNode sortList = solution2.sortList(head); 
		System.out.println(sortList); 
	} 
}

Python

class Solution: 
    def sortList(self, head: ListNode) -> ListNode:
        if not (head and head.next): 
            return head 
        pre, slow, fast = None, head, head 
        while fast and fast.next: 
            pre, slow, fast = slow, slow.next, fast.next.next
        pre.next = None 
        return self.mergeTwoLists(*map(self.sortList, (head, slow))) 
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: 
        if l1 and l2:
            if l1.val > l2.val:
                l1, l2 = l2, l1
                l1.next = self.mergeTwoLists(l1.next, l2) 
        return l1 or l2

 

“自顶向下”的“归并排序”的写法 Python 

class ListNode:
    def __init__(self, x): 
        self.val = x 
        self.next = None
        
class Solution: 
    def sortList(self, head: ListNode) -> ListNode: 
        if head is None or head.next is None:
            return head 
        # 找到中点 slow = head fast = head
        # 使用这种方式,当结点个数为 2 个时候,slow 在左结点 
        # 不会导致死循环
        while fast.next and fast.next.next: 
            slow = slow.next
            fast = fast.next.next
        head2 = slow.next
        slow.next = None
        
        lnode = self.sortList(head)
        rnode = self.sortList(head2) 
        
        return self.__merge_two_sorted_list(lnode, rnode)

    def __merge_two_sorted_list(self, head1, head2): 
        if head1 is None:
            return head2
        if head2 is None:
            return head1
        if head1.val < head2.val: 
            head1.next = self.__merge_two_sorted_list(head1.next, head2) 
            return head1 
        else:
            head2.next = self.__merge_two_sorted_list(head1, head2.next) 
            return head2

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值