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; } }
。。