2020
2121// Follow up: Can you sort the linked list in O(n logn) time and O(1) memory (i.e. constant space)?
2222
23+ // https://leetcode.com/problems/sort-list/
24+
2325use crate :: util:: linked_list:: ListNode ;
2426
2527// Definition for singly-linked list.
@@ -64,14 +66,26 @@ impl Solution {
6466 head
6567 }
6668
67- pub fn sort_list ( head : Option < Box < ListNode > > ) -> Option < Box < ListNode > > {
69+ pub fn sort_list_half_cut ( head : Option < Box < ListNode > > ) -> Option < Box < ListNode > > {
6870 if head. is_none ( ) || head. as_ref ( ) . unwrap ( ) . next . is_none ( ) {
6971 return head;
7072 }
7173
7274 let ( h1, h2) = Solution :: half_cut ( head) ;
73- let h1 = Solution :: sort_list ( h1) ;
74- let h2 = Solution :: sort_list ( h2) ;
75+ let h1 = Solution :: sort_list_half_cut ( h1) ;
76+ let h2 = Solution :: sort_list_half_cut ( h2) ;
77+
78+ Solution :: merge ( h1, h2)
79+ }
80+
81+ pub fn sort_list_half_cut_len ( head : Option < Box < ListNode > > ) -> Option < Box < ListNode > > {
82+ if head. is_none ( ) || head. as_ref ( ) . unwrap ( ) . next . is_none ( ) {
83+ return head;
84+ }
85+
86+ let ( h1, h2) = Solution :: half_cut_len ( head) ;
87+ let h1 = Solution :: sort_list_half_cut_len ( h1) ;
88+ let h2 = Solution :: sort_list_half_cut_len ( h2) ;
7589
7690 Solution :: merge ( h1, h2)
7791 }
@@ -100,30 +114,63 @@ impl Solution {
100114 }
101115
102116 if h1. as_ref ( ) . unwrap ( ) . val < h2. as_ref ( ) . unwrap ( ) . val {
103- pre . next = Some ( Box :: new ( ListNode :: new ( h1. as_ref ( ) . unwrap ( ) . val ) ) ) ;
104- // h1.clone ();
105- h1 = h1 . as_mut ( ) . unwrap ( ) . next . take ( ) ;
117+ let n = h1. as_mut ( ) . unwrap ( ) . next . take ( ) ;
118+ pre . next = h1. take ( ) ;
119+ h1 = n ;
106120 } else {
107- pre . next = Some ( Box :: new ( ListNode :: new ( h2. as_ref ( ) . unwrap ( ) . val ) ) ) ;
108- // pre.next = h2.clone ();
109- h2 = h2 . as_mut ( ) . unwrap ( ) . next . take ( ) ;
121+ let n = h2. as_mut ( ) . unwrap ( ) . next . take ( ) ;
122+ pre. next = h2. take ( ) ;
123+ h2 = n ;
110124 }
111125 pre = pre. next . as_deref_mut ( ) . unwrap ( ) ;
112126 }
113127
114128 head_pointer. next
115129 }
116130
131+ fn half_cut_len (
132+ mut head : Option < Box < ListNode > > ,
133+ ) -> ( Option < Box < ListNode > > , Option < Box < ListNode > > ) {
134+ if head. is_none ( ) || head. as_ref ( ) . unwrap ( ) . next . is_none ( ) {
135+ return ( head, None ) ;
136+ }
137+
138+ let len = Solution :: len ( & mut head) ;
139+ let mid = len / 2 ;
140+
141+ let mut head_pointer = ListNode :: new ( 0 ) ;
142+ head_pointer. next = head;
143+ let mut head2 = & mut head_pointer;
144+ for _i in 0 ..mid {
145+ head2 = head2. next . as_mut ( ) . unwrap ( ) ;
146+ }
147+ let head2 = head2. next . take ( ) ;
148+
149+ ( head_pointer. next , head2)
150+ }
151+
152+ fn len ( head : & mut Option < Box < ListNode > > ) -> i32 {
153+ let mut len = 0 ;
154+ let mut head = head;
155+ while let Some ( ref mut n) = head {
156+ head = & mut n. next ;
157+ len += 1 ;
158+ }
159+
160+ len
161+ }
162+
117163 fn half_cut ( head : Option < Box < ListNode > > ) -> ( Option < Box < ListNode > > , Option < Box < ListNode > > ) {
118164 if head. is_none ( ) || head. as_ref ( ) . unwrap ( ) . next . is_none ( ) {
119165 return ( head, None ) ;
120166 }
121167
168+ let mut head = head;
122169 let mut head_pointer = ListNode :: new ( 0 ) ;
123- head_pointer. next = head. clone ( ) ;
170+ head_pointer. next = head. take ( ) ;
124171
125172 let mut slow = & mut head_pointer;
126- let mut fast = Some ( Box :: new ( slow. clone ( ) ) ) ;
173+ let mut fast = Some ( Box :: new ( slow. clone ( ) ) ) ; // clone() kind of slow down the algorithm
127174 while fast. is_some ( ) && fast. as_ref ( ) . unwrap ( ) . next . is_some ( ) {
128175 slow = slow. next . as_mut ( ) . unwrap ( ) ;
129176 fast = fast. as_mut ( ) . unwrap ( ) . next . as_mut ( ) . unwrap ( ) . next . take ( ) ;
@@ -143,15 +190,28 @@ mod tests {
143190 #[ test]
144191 fn test_148 ( ) {
145192 assert_eq ! (
146- Solution :: sort_list( linked_list:: to_list( vec![ 4 , 2 , 1 , 3 ] ) ) ,
193+ Solution :: sort_list_half_cut( linked_list:: to_list( vec![ 4 , 2 , 1 , 3 ] ) ) ,
194+ linked_list:: to_list( vec![ 1 , 2 , 3 , 4 ] )
195+ ) ;
196+ assert_eq ! (
197+ Solution :: sort_list_half_cut( linked_list:: to_list( vec![ -1 , 5 , 3 , 4 , 0 ] ) ) ,
198+ linked_list:: to_list( vec![ -1 , 0 , 3 , 4 , 5 ] )
199+ ) ;
200+ assert_eq ! (
201+ Solution :: sort_list_half_cut( linked_list:: to_list( vec![ ] ) ) ,
202+ linked_list:: to_list( vec![ ] )
203+ ) ;
204+
205+ assert_eq ! (
206+ Solution :: sort_list_half_cut_len( linked_list:: to_list( vec![ 4 , 2 , 1 , 3 ] ) ) ,
147207 linked_list:: to_list( vec![ 1 , 2 , 3 , 4 ] )
148208 ) ;
149209 assert_eq ! (
150- Solution :: sort_list ( linked_list:: to_list( vec![ -1 , 5 , 3 , 4 , 0 ] ) ) ,
210+ Solution :: sort_list_half_cut_len ( linked_list:: to_list( vec![ -1 , 5 , 3 , 4 , 0 ] ) ) ,
151211 linked_list:: to_list( vec![ -1 , 0 , 3 , 4 , 5 ] )
152212 ) ;
153213 assert_eq ! (
154- Solution :: sort_list ( linked_list:: to_list( vec![ ] ) ) ,
214+ Solution :: sort_list_half_cut_len ( linked_list:: to_list( vec![ ] ) ) ,
155215 linked_list:: to_list( vec![ ] )
156216 ) ;
157217
@@ -172,13 +232,23 @@ mod tests {
172232 extern crate test;
173233 use test:: { Bencher , black_box} ;
174234
175- #[ rustfmt:: skip]
176- // test problem::p0148_sort_list::tests::bench_sort_list ... bench: 16,858.58 ns/iter (+/- 419.48)
177- // test problem::p0148_sort_list::tests::bench_sort_list_with_vec ... bench: 1,120.72 ns/iter (+/- 54.88)
235+ #[ rustfmt:: skip]
236+ // test problem::p0148_sort_list::tests::bench_sort_list_half_cut ... bench: 7,633.79 ns/iter (+/- 207.15)
237+ // test problem::p0148_sort_list::tests::bench_sort_list_half_cut_len ... bench: 1,823.08 ns/iter (+/- 40.39)
238+ // test problem::p0148_sort_list::tests::bench_sort_list_with_vec ... bench: 1,034.86 ns/iter (+/- 30.86)
239+ #[ bench]
240+ fn bench_sort_list_half_cut ( b : & mut Bencher ) {
241+ b. iter ( || {
242+ black_box ( Solution :: sort_list_half_cut ( linked_list:: to_list (
243+ ( 1 ..=100 ) . rev ( ) . collect ( ) ,
244+ ) ) )
245+ } ) ;
246+ }
247+
178248 #[ bench]
179- fn bench_sort_list ( b : & mut Bencher ) {
249+ fn bench_sort_list_half_cut_len ( b : & mut Bencher ) {
180250 b. iter ( || {
181- black_box ( Solution :: sort_list ( linked_list:: to_list (
251+ black_box ( Solution :: sort_list_half_cut_len ( linked_list:: to_list (
182252 ( 1 ..=100 ) . rev ( ) . collect ( ) ,
183253 ) ) )
184254 } ) ;
0 commit comments