晚日寒鸦一片愁。柳塘新绿却温柔。若教眼底无离恨,不信人间有白头。
肠已断,泪难收。相思重上小红楼。情知已被山遮断,频倚阑干不自由。
题目描述
leetcode链接: https://leetcode-cn.com/problems/insertion-sort-list/
简而言之,就是对链表进行排序
示例1
输入 :[4,2,1,3]
输出 :[1,2,3,4]
示例2
输入 :head = [-1,5,3,4,0]
输出 :[-1,0,3,4,5]
链表定义以及接口函数签名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #[derive(PartialEq, Eq, Clone, Debug)] pub struct ListNode { pub val: i32 , pub next: Option <Box <ListNode>> } impl ListNode { #[inline] fn new (val: i32 ) -> Self { ListNode { next: None , val } } } impl Solution { pub fn insertion_sort_list (head: Option <Box <ListNode>>) -> Option <Box <ListNode>> { } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 struct ListNode { int val; ListNode *next; ListNode () : val (0 ), next (nullptr ) {} ListNode (int x) : val (x), next (nullptr ) {} ListNode (int x, ListNode *next) : val (x), next (next) {} }; class Solution {public : ListNode* insertionSortList (ListNode* head) { } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 insertionSortList (ListNode head) { } }
问题分析
可以使用插入排序的方法,每次从原链表中取出一个元素,然后插入到结果链表中的适当位置。
同时,参考合并两个有序链表的方法,可以设计出归并排序。即将链表分为两段,递归地对这两端链表进行排序,然后使用合并两个有序链表的方法对其进行排序即可。归并排序的时间复杂度为O ( l o g n ) O(logn) O ( l o g n ) 。
具体实现-插入排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : ListNode* insertionSortList (ListNode* head) { ListNode ret_head (0x80000000 ) ; while (head) { ListNode * cur = head; head = head->next; cur->next = nullptr ; ListNode * p = &ret_head; while (p->next != nullptr && p->next->val < cur->val) p = p->next; cur->next = p->next; p->next = cur; } return ret_head.next; } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public ListNode insertionSortList (ListNode head) { ListNode ret_head = new ListNode (0x80000000 ); while (head != null ) { ListNode cur = head; head = head.next; cur.next = null ; ListNode p = ret_head; while (p.next != null && p.next.val < cur.val) p = p.next; cur.next = p.next; p.next = cur; } return ret_head.next; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 impl Solution { pub fn insertion_sort_list (head: Option <Box <ListNode>>) -> Option <Box <ListNode>> { let mut ret_head = Box ::new (ListNode::new (-2147483648i32 )); let mut head = head; while let Some (current) = head.as_mut () { let current_next : Option <Box <ListNode>> = current.next.take (); let mut p = &mut ret_head; while p.next != None && p.next.as_ref ().unwrap ().val < current.val { p = p.next.as_mut ().unwrap (); } let p_next = p.next.take (); current.next = p_next; p.next = head; head = current_next; } ret_head.next } }
具体实现-归并排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 impl Solution { pub fn insertion_sort_list (head: Option <Box <ListNode>>) -> Option <Box <ListNode>> { if head == None { return None ; } let li = head.as_ref ().unwrap (); if li.next == None { return head; } let mut head = head; let mut n = 0 ; let mut p = &head; while let Some (li) = p { n += 1 ; p = &li.next; } let mut cur = head.as_mut ().unwrap (); let mid = n / 2 - 1 ; for _ in 0 ..mid { cur = cur.next.as_mut ().unwrap (); } let hold = cur.next.take (); let mut left = Solution::insertion_sort_list (head); let mut right = Solution::insertion_sort_list (hold); let mut head = Box ::new (ListNode::new (0 )); let mut cur = &mut head; while let (Some (li1), Some (li2)) = (left.as_mut (), right.as_mut ()) { if li1.val < li2.val { let hold = li1.next.take (); cur.next = left; left = hold; } else { let hold = li2.next.take (); cur.next = right; right = hold; } cur = cur.next.as_mut ().unwrap (); } if let Some (li) = left { cur.next = Some (li); } else { cur.next = right; } head.next } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 class Solution { public : ListNode *insertionSortList (ListNode *head) { if (head->next == nullptr ) return head; int n = 0 ; for (ListNode *cur = head; cur != nullptr ; cur = cur->next) { n++; } int m = n / 2 ; ListNode *mid = head; for (int i = 0 ; i < m - 1 ; i++) { mid = mid->next; } ListNode *hold = mid->next; mid->next = nullptr ; mid = hold; ListNode *left = insertionSortList (head); ListNode *right = insertionSortList (mid); ListNode *ans = nullptr ; if (left->val > right->val) { ans = right; right = right->next; } else { ans = left; left = left->next; } ListNode *cur = ans; while (left != nullptr && right != nullptr ) { if (left->val > right->val) { cur->next = right; right = right->next; } else { cur->next = left; left = left->next; } cur = cur->next; } if (left != nullptr ) cur->next = left; else cur->next = right; return ans; } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Solution { public ListNode insertionSortList (ListNode head) { if (head.next == null ) return head; int n = 0 ; for (ListNode cur=head; cur != null ; cur = cur.next) { n++; } int m = n / 2 ; ListNode mid = head; for (int i = 0 ; i < m - 1 ; i++) { mid = mid.next; } ListNode hold = mid.next; mid.next = null ; mid = hold; ListNode left = insertionSortList(head); ListNode right = insertionSortList(mid); head = new ListNode (0 ); ListNode cur = head; while (left != null && right != null ) { if (left.val < right.val) { cur.next = left; left = left.next; } else { cur.next = right; right = right.next; } cur = cur.next; } if (left != null ) cur.next = left; else cur.next = right; return head.next; } }