时间复杂度为nlogn的算法总结

本文总结了在O(n log n)时间复杂度下对链表进行排序的方法,主要讨论了如何利用归并排序的思想,通过切割链表找中点和递归合并两个步骤来实现。具体包括快慢指针法寻找链表中点,以及双指针法合并排序链表。详细阐述了这两个关键环节,并提供了leetcode相关题解。
摘要由CSDN通过智能技术生成

1. 排序链表

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

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

示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5

题解
题目要求时间空间复杂度分别为O(nlogn)O(1),根据时间复杂度我们自然想到二分法,从而联想到归并排序;

通过递归实现链表归并排序,有以下两个环节:
分割 cut 环节: 找到当前链表中点,并从中点将链表断开(以便在下次递归 cut 时,链表片段拥有正确边界);

我们使用fast,slow 快慢双指针法,奇数个节点找到中点,偶数个节点找到中心左边的节点。
找到中点 slow 后,执行 slow.next = None 将链表切断。
递归分割时,输入当前链表左端点 head 和中心节点 slow 的下一个节点 tmp(因为链表是从 slow 切断的)。
cut 递归终止条件: 当head.next == None时,说明只有一个节点了,直接返回此节点

合并 merge 环节: 将两个排序链表合并,转化为一个排序链表。
双指针法合并,建立辅助ListNodeh作为头部。
设置两指针 left, right 分别指向两链表头部,比较两指针处节点值大小,由小到大加入合并链表头部,指针交替前进,直至添加完两个链表。
返回辅助ListNodeh作为头部的下个节点h.next
时间复杂度 O(l + r)l,r分别代表两个链表长度
在这里插入图片描述
程序:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值