Repository navigation
Expand file tree
/
Copy pathNo332.reconstruct-itinerary.js
More file actions
153 lines (131 loc) · 4.21 KB
/
Copy pathNo332.reconstruct-itinerary.js
File metadata and controls
153 lines (131 loc) · 4.21 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/**
* Difficulty:
* Medium
*
* Desc:
* Given a list of airline tickets represented by pairs of departure and arrival airports [from, to],
* reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK.
* Thus, the itinerary must begin with JFK.
*
* Note:
* 1. If there are multiple valid itineraries,
* you should return the itinerary that has the smallest lexical order when read as a single string. For example, the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"].
* 2. All airports are represented by three capital letters (IATA code).
* 3. You may assume all tickets form at least one valid itinerary.
*
* Example:
* tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
* Return ["JFK", "MUC", "LHR", "SFO", "SJC"].
*
* tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
* Return ["JFK","ATL","JFK","SFO","ATL","SFO"].
* Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"]. But it is larger in lexical order.
*/
/**
* 根据题意,给出一组机票,里面每个数组代表从出发机场到到达机场。
* 要求返回一个可以使用上全部机票的顺序。要求:
* 1. 机票必须全部用完
* 2. 到达机场有多种选择时,选择字典顺序靠前的那个
*/
var searchInsert = function(nums, target) {
var left = 0;
var right = nums.length - 1;
var index = null;
while (left <= right) {
var midIndex = Math.floor((left + right) / 2);
var mid = nums[midIndex];
if (mid === target) {
index = midIndex;
break;
} else if (mid > target) {
right = midIndex - 1;
} else {
left = midIndex + 1;
}
}
if (index === null) {
left -= 1;
var num = nums[left];
if (num > target) {
if (left - 1 < 0 || nums[left - 1] < target) {
index = left;
}
} else {
if (left + 1 > nums.length -1 || nums[left + 1] > target) {
index = left + 1;
}
}
}
return index;
};
const insert = (arr, val) => {
const index = searchInsert(arr, val);
const r = arr.slice(0, index);
r.push(val);
return r.concat(arr.slice(index));
};
class Digraph {
constructor(datas) {
this.adj = {};
this.count = datas.length;
this.init(datas);
}
init(datas) {
for (const data of datas) {
const [start, end] = data;
if (!this.adj[start]) this.adj[start] = [];
this.adj[start] = insert(this.adj[start], end);
}
}
get size() {
return this.count + 1;
}
}
class WalkDigraph {
constructor(digraph, start) {
this.paths = [];
this.walk(digraph, start);
}
walk(digraph, point) {
this.paths.push(point);
const points = digraph.adj[point];
if (!points || !points.length) {
const r = this.size === digraph.size;
if (!r) this.paths.pop();
return r;
}
let loop = 0;
while (loop < digraph.adj[point].length) {
const nextPoint = digraph.adj[point].shift();
const result = this.walk(digraph, nextPoint);
if (!result) {
digraph.adj[point].push(nextPoint);
} else {
return true;
}
loop += 1;
}
digraph.adj[point] = points;
this.paths.pop();
return false;
}
get size() {
return this.paths.length;
}
}
/**
* @param {string[][]} tickets
* @return {string[]}
*/
var findItinerary = function(tickets) {
const digraph = new Digraph(tickets);
const walkDigraph = new WalkDigraph(digraph, 'JFK');
return walkDigraph.paths;
};
// Test case
// [ 'JFK', 'NRT', 'JFK', 'KUL' ]
console.log(findItinerary([['JFK','KUL'],['JFK','NRT'],['NRT','JFK']]));
// ["JFK", "AXA", "AUA", "ADL", "ANU", "AUA", "ANU", "EZE", "ADL", "EZE", "ANU", "JFK", "AXA", "EZE", "TIA", "AUA", "AXA", "TIA", "ADL", "EZE", "HBA"]
console.log(findItinerary([["EZE","TIA"],["EZE","HBA"],["AXA","TIA"],["JFK","AXA"],["ANU","JFK"],["ADL","ANU"],["TIA","AUA"],["ANU","AUA"],["ADL","EZE"],["ADL","EZE"],["EZE","ADL"],["AXA","EZE"],["AUA","AXA"],["JFK","AXA"],["AXA","AUA"],["AUA","ADL"],["ANU","EZE"],["TIA","ADL"],["EZE","ANU"],["AUA","ANU"]]));
// [ 'JFK', 'ATL', 'JFK', 'SFO', 'ATL', 'SFO' ]
console.log(findItinerary([["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]));