这段时间刷leetcode算法题给我刷的有点崩溃了,随着秋招时间一天一天临近了,然鹅我的算法题刷的依然是一塌糊涂,很多难点的算法题还是不会写,心里也越来越紧张。但还是得刷下去哇。

    刚开始刷的两道链表中判断是否有环感觉还是挺简单的,很快就写出来了,然后刷到了链表的排序这道题,着实不太好懂。但是不好懂也得弄懂,没有办法,只能一步一步来了,下面就开始吧。

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

对数组做归并排序的空间复杂度为 O(n)O(n),分别由新开辟数组O(n)O(n)和递归函数调用O(logn)O(logn)组成,而根据链表特性:

数组额外空间:链表可以通过修改引用来更改节点顺序,无需像数组一样开辟额外空间;
递归额外空间:递归调用函数将带来O(logn)O(logn)的空间复杂度,因此若希望达到O(1)O(1)空间复杂度,则不能使用递归。
通过递归实现链表归并排序,有以下两个环节:

分割 cut 环节: 找到当前链表中点,并从中点将链表断开(以便在下次递归 cut 时,链表片段拥有正确边界);
我们使用 fast,slow 快慢双指针法,奇数个节点找到中点,偶数个节点找到中心左边的节点。
找到中点 slow 后,执行 slow.next = None 将链表切断。
递归分割时,输入当前链表左端点 head 和中心节点 slow 的下一个节点 tmp(因为链表是从 slow 切断的)。
cut 递归终止条件: 当head.next == None时,说明只有一个节点了,直接返回此节点。
合并 merge 环节: 将两个排序链表合并,转化为一个排序链表。
双指针法合并,建立辅助ListNode h 作为头部。
设置两指针 left, right 分别指向两链表头部,比较两指针处节点值大小,由小到大加入合并链表头部,指针交替前进,直至添加完两个链表。
返回辅助ListNode h 作为头部的下个节点 h.next。
时间复杂度 O(l + r),l, r 分别代表两个链表长度。
当题目输入的 head == None 时,直接返回None。

今日题目:排序链表

class Solution {

    public ListNode sortList(ListNode head) {

//如果节点为null或者下一个节点为null则说明分割无法进行了,只有返回。

       if(head==null||head.next==null){

           return head;

       }

//此处定义一个快节点和一个慢节点的目的就是为了将链表均分,这也符合归并排序的思想,先将数组或者链表从中间分隔开成为两条链表或者两个数组,然后再递归划分,直到达到划分终止条件未知

       ListNode fast = head.next,slow=head;

       while(fast!=null&&fast.next!=null){

           slow=slow.next;

           fast=fast.next.next;

       }

//切分完以后就得合并了,归并归并无非就两步,第一步分割,第二步合并

       ListNode temp = slow.next;

       slow.next = null;

//得到分割后的左子链表

       ListNode left = sortList(head);

//得到分割后的右子链表

       ListNode right = sortList(temp);

       ListNode h = new ListNode(0);

       ListNode res = h;

//将分割后的链表进行排序并合并

       while(left!=null&&right!=null){

           if(left.val<right.val){

               h.next = left;

               left = left.next;

           }

           else{

               h.next=right;

               right = right.next;

           }

           h = h.next;

       }

       h.next = left!=null?left:right;

       return res.next;

 

    }

}

相关文章:

  • 2021-05-08
  • 2022-02-11
  • 2021-11-26
猜你喜欢
  • 2021-12-09
  • 2022-12-23
  • 2021-07-26
  • 2021-12-05
  • 2021-06-22
  • 2021-07-02
  • 2022-01-09
相关资源
相似解决方案