1
+ use std:: cmp:: Reverse ;
2
+ use std:: collections:: BinaryHeap ;
1
3
use std:: collections:: HashMap ;
2
- use std:: collections:: HashSet ;
3
4
4
5
/// You are given a list of airline `tickets` where `tickets[i] = [fromi, toi]`
5
6
/// represent the departure and arrival airports of one flight. Reconstruct
@@ -19,65 +20,35 @@ struct Solution;
19
20
20
21
impl Solution {
21
22
22
- fn to_adj_map ( tickets : Vec < Vec < String > > ) -> HashMap < String , HashSet < String > > {
23
- let mut results = HashMap :: new ( ) ;
24
-
25
- for ticket in tickets {
26
- results
27
- . entry ( ticket[ 0 ] . clone ( ) )
28
- . or_insert ( HashSet :: new ( ) )
29
- . insert ( ticket[ 1 ] . clone ( ) ) ;
30
- }
31
-
32
- results
33
- }
34
-
35
- fn remove ( map : & mut HashMap < String , HashSet < String > > , key : & String , value : & String ) {
36
- if map. contains_key ( key) {
37
- let set = map. get_mut ( key) . unwrap ( ) ;
38
- if set. len ( ) == 1 {
39
- map. remove ( key) ;
40
- } else {
41
- set. remove ( value) ;
42
- }
43
- }
44
- }
45
-
46
- fn worker (
47
- results : & mut Vec < String > ,
48
- map : HashMap < String , HashSet < String > > ,
49
- path : Vec < String > ,
50
- current : String
23
+ fn dfs (
24
+ result : & mut Vec < String > ,
25
+ adj_map : & mut HashMap < String , BinaryHeap < Reverse < String > > > ,
26
+ value : & str
51
27
) {
52
- if map. len ( ) == 0 {
53
- if results. len ( ) == 0 {
54
- * results = path. clone ( ) ;
55
- } else if & path < & results{
56
- * results = path. clone ( ) ;
57
- }
58
- } else if map. contains_key ( & current) {
59
- for next in & map[ & current] {
60
- let mut next_path = path. clone ( ) ;
61
- next_path. push ( next. clone ( ) ) ;
62
- let mut map = map. clone ( ) ;
63
- Self :: remove ( & mut map, & current, next) ;
64
- Self :: worker ( results, map, next_path, next. clone ( ) ) ;
65
- }
28
+ while let Some ( Reverse ( next) ) = adj_map. get_mut ( value) . and_then ( |dests| dests. pop ( ) ) {
29
+ Self :: dfs ( result, adj_map, & next) ;
66
30
}
31
+ result. push ( value. to_string ( ) ) ;
67
32
}
68
33
69
- // TODO: Improve
70
- // Simple solution that I know if submitted will fail for time limit exceeded.
71
34
pub fn find_itinerary ( tickets : Vec < Vec < String > > ) -> Vec < String > {
72
- let mut results = Vec :: new ( ) ;
35
+ let mut result = vec ! [ ] ;
36
+ let mut adj_map: HashMap < String , BinaryHeap < Reverse < String > > > = HashMap :: new ( ) ;
73
37
74
- let map = Self :: to_adj_map ( tickets) ;
75
- let initial = vec ! [ "JFK" . to_string( ) ] ;
76
- let current = "JFK" . to_string ( ) ;
38
+ for ticket in tickets {
39
+ let source = ticket[ 0 ] . clone ( ) ;
40
+ let destination = ticket[ 1 ] . clone ( ) ;
41
+
42
+ adj_map
43
+ . entry ( source)
44
+ . or_insert ( BinaryHeap :: new ( ) )
45
+ . push ( Reverse ( destination) ) ;
46
+ }
77
47
78
- Self :: worker ( & mut results , map , initial , current ) ;
48
+ Self :: dfs ( & mut result , & mut adj_map , "JFK" ) ;
79
49
80
- results
50
+ result. reverse ( ) ;
51
+ result
81
52
}
82
53
83
54
}
@@ -86,7 +57,6 @@ impl Solution {
86
57
mod tests {
87
58
use super :: Solution ;
88
59
89
- #[ ignore]
90
60
#[ test]
91
61
fn example_1 ( ) {
92
62
let tickets = vec ! [
@@ -99,7 +69,6 @@ mod tests {
99
69
assert_eq ! ( result, vec![ "JFK" , "MUC" , "LHR" , "SFO" , "SJC" ] ) ;
100
70
}
101
71
102
- #[ ignore]
103
72
#[ test]
104
73
fn example_2 ( ) {
105
74
let tickets = vec ! [
@@ -113,4 +82,22 @@ mod tests {
113
82
assert_eq ! ( result, vec![ "JFK" , "ATL" , "JFK" , "SFO" , "ATL" , "SFO" ] ) ;
114
83
}
115
84
85
+ #[ test]
86
+ fn example_3 ( ) {
87
+ let tickets = vec ! [
88
+ vec![ str !( "EZE" ) , str !( "AXA" ) ] ,
89
+ vec![ str !( "TIA" ) , str !( "ANU" ) ] ,
90
+ vec![ str !( "ANU" ) , str !( "JFK" ) ] ,
91
+ vec![ str !( "JFK" ) , str !( "ANU" ) ] ,
92
+ vec![ str !( "ANU" ) , str !( "EZE" ) ] ,
93
+ vec![ str !( "TIA" ) , str !( "ANU" ) ] ,
94
+ vec![ str !( "AXA" ) , str !( "TIA" ) ] ,
95
+ vec![ str !( "TIA" ) , str !( "JFK" ) ] ,
96
+ vec![ str !( "ANU" ) , str !( "TIA" ) ] ,
97
+ vec![ str !( "JFK" ) , str !( "TIA" ) ] ,
98
+ ] ;
99
+ let result = Solution :: find_itinerary ( tickets) ;
100
+ assert_eq ! ( result, vec![ "JFK" , "ANU" , "EZE" , "AXA" , "TIA" , "ANU" , "JFK" , "TIA" , "ANU" , "TIA" , "JFK" ] ) ;
101
+ }
102
+
116
103
}
0 commit comments