148. 排序链表
148. 排序链表
思路:
采用对数组进行归并排序的相同思路,依旧是对链表进行递归,递归到只有一个元素的时候,在对链表进行合并操作。
只不过,在查找链表的中间点的方式是利用快慢指针。在合并两个有序链表的时候,创建哨兵进行合并。
图解答案,自顶向下归并排序:https://leetcode-cn.com/problems/sort-list/solution/jin-dao-gui-bing-pai-xu-kan-tu-jiu-dong-wz6y1/
package 链表; public class 排序链表 { public static void main(String[] args) { ListNode listNode = new ListNode(4); ListNode listNode1 = new ListNode(2); ListNode listNode2 = new ListNode(1); ListNode listNode3 = new ListNode(3); listNode.next = listNode1; listNode1.next = listNode2; listNode2.next = listNode3; ListNode result = new 排序链表().sortList(listNode); System.out.println(result); } // 将链表进行排序 // 自顶向下归并 public ListNode sortList(ListNode head) { if(head==null){ return head; } return sortList(head, null); } // 对链表的一部分进行排序 public ListNode sortList(ListNode head, ListNode tail) { if (head.next == tail) { head.next = null; return head; } // 找到链表的中点,中点之前一部分,中点之后一部分 ListNode slow = head; ListNode fast = head; while (fast != tail) { slow = slow.next; fast = fast.next; if (fast != tail) { fast = fast.next; } } ListNode mid = slow; return merge(sortList(head, mid), sortList(mid, tail)); } // 合并两个有序链表 public ListNode merge(ListNode listNode1, ListNode listNode2) { ListNode head = new ListNode(-1); ListNode node = head; while (listNode1 != null && listNode2 != null) { if (listNode1.val < listNode2.val) { node.next = listNode1; listNode1 = listNode1.next; } else { node.next = listNode2; listNode2 = listNode2.next; } node = node.next; } node.next = listNode1 == null ? listNode2 : listNode1; return head.next; } }
。。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode sortList(ListNode head) { if(head==null || head.next==null){ return head; } // divide list to two part ListNode pre=head, slow=head, fast=head; while(fast!=null && fast.next!=null){ pre = slow; slow = slow.next; fast = fast.next.next; } pre.next = null; // sort every part ListNode head1 = sortList(head); ListNode head2 = sortList(slow); // merge two sorted part return merge(head1, head2); } // merge two list public ListNode merge(ListNode head1, ListNode head2) { ListNode head = new ListNode(-1); ListNode node = head; while(head1!=null && head2!=null){ if(head1.val>=head2.val){ node.next = head2; head2 = head2.next; }else{ node.next = head1; head1 = head1.next; } node = node.next; } if(head1!=null){ node.next = head1; } if(head2!=null){ node.next = head2; } return head.next; } }
..
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)