Leetcode 332. Reconstruct Itinerary
dfs: 熟悉深度优先搜索的代码结构,回溯+递归,这个版本可以进行优化的地方:其实不需要对链表进行排序,只需要维持一个最大堆的结构就行了。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.PriorityQueue;
public class Solution {
public static void main(String[] args){
//String[][] tickets = {{"JFK","SFO"},{"JFK","ATL"},{"SFO","ATL"},{"ATL","JFK"},{"ATL","SFO"}};
String[][] tickets = {{"JFK","KUL"},{"JFK","NRT"},{"NRT","JFK"}};
Solution s = new Solution();
List<String> result = s.findItinerary(tickets);
}
class SortByString implements Comparator<String> {
public int compare(String o1, String o2) {
String s1 = (String) o1;
String s2 = (String) o2;
int flag = -1;
for(int i=0;i<s1.length();i++){
if(s1.charAt(i)<s2.charAt(i)){
flag = 0;
break;
}else{
flag = 1;
break;
}
}
return flag;
}
}
public List<String> findItinerary(String[][] tickets) {
HashMap<String, ArrayList<String>> fromto = new HashMap<String,ArrayList<String>>();
HashMap<String, int[]> used = new HashMap<String,int[]>();
//HashMap<String, PriorityQueue<String>> ticketsMap = new HashMap<>();
for(int i=0;i<tickets.length;i++){
String[] ticket = tickets[i];
if(!fromto.containsKey(ticket[0])){
fromto.put(ticket[0], new ArrayList<String>());
//used.put(ticket[0], new ArrayList<Integer>());
}
fromto.get(ticket[0]).add(ticket[1]);
//used.get(ticket[0]).add(0);
}
for(String s : fromto.keySet()){
int n = fromto.get(s).size();
int[] use = new int[n];
used.put(s, use);
}
//comparator
Comparator<String> comparator = new Comparator<String>(){
public int compare(String s1, String s2) {
//int min = s1.length()<s2.length()?s1.length():s2.length();
int flag = -1;
for(int i=0;i<s1.length();i++){
if(s1.charAt(i)<s2.charAt(i)){
flag = 1;
break;
}else{
flag = 0;
break;
}
}
return flag;
}
};
for(String start: fromto.keySet()){
ArrayList<String> tmp = fromto.get(start);
Collections.sort(tmp);
fromto.put(start,tmp);
//fromto.put(start, value)
}
//
List<String> res = new ArrayList<String>();
//res.add("JFK");
List<List<String>> result = new ArrayList<List<String>>();
dfs("JFK",fromto,used,res,result,tickets.length);
return result.get(0);
}
private int dfs(String start, HashMap<String, ArrayList<String>> fromto, HashMap<String, int[]> used,
List<String> res, List<List<String>> result, int len) {
// TODO Auto-generated method stub
if(res.size()>len) return 1;
if(isCompelete(used)){
res.add(start);
result.add(new ArrayList<String>(res));
return 0;
}else{
int re = 1; // 1 stands for fair .
for(int i=0;i<fromto.get(start).size();i++){
if(used.get(start)[i]==0){
used.get(start)[i] = 1;
String next = fromto.get(start).get(i);
res.add(start);
if(!isCompelete(used)&&!fromto.containsKey(next)){ // backtrack
used.get(start)[i] = 0;
res.remove(res.size()-1);
continue;
}
re = dfs(next,fromto,used,res,result,len);
if(re==0){
break;
}
used.get(start)[i] = 0;
res.remove(res.size()-1);
}
}
return re;
}
}
private boolean isCompelete(HashMap<String, int[]> used) {
// TODO Auto-generated method stub\
boolean flag = true;
for(String s:used.keySet()){
for(int use :used.get(s)){
if(use==0){
flag = false;
}
}
}
return flag;
}
}
Solution 别人给的Greedy 解法:
public List<String> findItinerary(String[][] tickets) {
List<String> ans = new ArrayList<String>();
if(tickets == null || tickets.length == 0) return ans;
Map<String, PriorityQueue<String>> ticketsMap = new HashMap<>();
for(int i = 0; i < tickets.length; i++) {
if(!ticketsMap.containsKey(tickets[i][0])) ticketsMap.put(tickets[i][0], new PriorityQueue<String>());
ticketsMap.get(tickets[i][0]).add(tickets[i][1]);
}
String curr = "JFK";
Stack<String> drawBack = new Stack<String>();
for(int i = 0; i < tickets.length; i++) {
while(!ticketsMap.containsKey(curr) || ticketsMap.get(curr).isEmpty()) {
drawBack.push(curr);
curr = ans.remove(ans.size()-1);
}
ans.add(curr);
curr = ticketsMap.get(curr).poll();
}
ans.add(curr);
while(!drawBack.isEmpty()) ans.add(drawBack.pop());
return ans;
}