1. 解题思路
看到这题的第一反应就是利用数组的sort函数来自动排序然后更新链表中的节点值,这个思路很简单,就不画图解说,直接上代码。
2. 核心代码
# class ListNode: # def __init__(self, x): # self.val = x # self.next = None # # @param head ListNode类 the head node # @return ListNode类 class Solution: def sortInList(self , head): # write code here #获取头部节点 h = head #创建一个排序数组 l = [] #当节点存在的时候,依次添加节点值到数组 while h: l.append(h.val) h = h.next l.sort() #利用sort函数对数组进行升序排列 #创建新链表 h = head i = 0 #索引从0开始 #把排完序的数组重新赋值给新的链表,此时的链表的所有节点都是按升序排列的 while h: h.val = l[i] h = h.next i += 1 return head
3. 复杂度分析
- 时间复杂度: (n为链表的长度,数组排序的时间复杂度为 )
- 空间复杂度: (新建的排序数组大小与链表长度n有关)
----------------------------------------------我是有点复杂的解法二分割线----------------------------------------------
4. 解法二
4.1 思路:归并排序(递归法)
此题另一种解法就是利用分治思想中比较经典的归并排序(Merge Sort)算法。
PS : 简单解释一下归并排序的含义👉:
把数组从中间开始切割成前后两部分,然后分别对前后两部分排序;再把排好序的两部分合并,此时的数组就是我们要找的有序数组。
具体到本题的思路:
- 找到切割链表的中间点,把链表分成左右两部分;然后通过递归找的终止条件(即只有一个节点的时候);
- 接下来分别对左右两边的链表进行排序,然后合并排好序的链表。
这里结合示例1进行图解:
4.2 核心代码
# class ListNode: # def __init__(self, x): # self.val = x # self.next = None # # @param head ListNode类 the head node # @return ListNode类 class Solution: def sortInList(self , head): # write code here #首先链表只有一个节点或没有节点的情况 if not head or not head.next: return head #创建快慢两种指针 slow, fast = head, head #去找中间位置来切断链表 while fast.next and fast.next.next: slow, fast = slow.next, fast.next.next mid = slow.next slow.next = None #找到左右两部分 left, right = self.sortInList(head), self.sortInList(mid) #一直递归下去,直到左右两部分的节点都被切割开 #分别对左右两边进行排序(升序)并合并 res = ListNode(0) tail = res while left and right: if left.val < right.val: #如果左边节点的值时小于右边的时候 tail.next, left = left, left.next #那么tail将会在左边进行排序;否则在右边 else: tail.next, right = right, right.next tail = tail.next #仅有左边或右边的情况 if left: tail.next = left if right: tail.next = right return res.next
4.3 复杂度分析
- 时间复杂度: (n为链表的长度,分解链表的时间为log n,合并两个有序链表的时间为n)
- 空间复杂度: (n 为链表的长度,空间复杂度主要取决于递归调用的栈空间)