Reconstruct Itinerary

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 fromJFK. 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 1:
tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
Return ["JFK", "MUC", "LHR", "SFO", "SJC"].

Example 2:
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.


一口老血吐出来了,其实写的时候就知道肯定会超时的,哎。

我先把这些票都用一个map存起来,起点相同的在同一个list中。

{ATL=[JFK, SFO], SFO=[ATL], JFK=[SFO, ATL]}

然后就是死脑筋的用递归去做咯,捉急呀!

public class Solution {
    public List<String> findItinerary(String[][] tickets) {
        List<List<String>> itinerarys=new ArrayList<List<String>>();
        Map<String, List<String>> map=new HashMap<String, List<String>>();
        for(int i=0;i<tickets.length;i++){
            if(!map.containsKey(tickets[i][0])){
                List<String> arrivals=new ArrayList<String>();
                arrivals.add(tickets[i][1]);
                map.put(tickets[i][0], arrivals);
            }else{
                List<String> arrivals=map.get(tickets[i][0]);
                arrivals.add(tickets[i][1]);
                map.put(tickets[i][0], arrivals);
            }
        }
        List<String> itinerary=new ArrayList<String>();
        itinerary.add("JFK");
        getItinerarys(itinerarys, map, "JFK", itinerary);
        return getFirstItinerary(itinerarys);
    }
    
    private List<String> getFirstItinerary(List<List<String>> itinerarys) {
        // TODO Auto-generated method stub
        List<String> littleItinerary = itinerarys.get(0);
        for(int i=1;i<itinerarys.size();i++){
            littleItinerary=compare(littleItinerary, itinerarys.get(i))<0?littleItinerary:itinerarys.get(i);
        }
        return littleItinerary;
    }

    private int compare(List<String> littleItinerary, List<String> list) {
        // TODO Auto-generated method stub
        for(int i=0;i<littleItinerary.size();i++){
            if(littleItinerary.get(i).compareTo(list.get(i))>0){
                return 1;
            }
            if(littleItinerary.get(i).compareTo(list.get(i))<0){
                return -1;
            }
        }
        return 0;
    }

    public void getItinerarys(List<List<String>> itinerarys,
            Map<String, List<String>> map, String start, List<String> itinerary) {
        // TODO Auto-generated method stub
        if(!map.containsKey(start)&&map.size()==0){
            itinerarys.add(itinerary);
            return ;
        }
        if(!map.containsKey(start)){
            return ; 
        }
        
        List<String> newArrivalList=new ArrayList<String>(map.get(start));
        for(int i=0;i<newArrivalList.size();i++){
            
            List<String> newItinerary=new ArrayList<String>(itinerary);
            Map<String, List<String>> newMap=new HashMap<String, List<String>>();
            for(String key:map.keySet()){
                newMap.put(key, new ArrayList<String>(map.get(key)));
            }
            String arrival=newArrivalList.get(i);
            newItinerary.add(arrival);
            newMap.get(start).remove(i);
            if(newMap.get(start).size()==0){
                newMap.remove(start);
            }
            getItinerarys(itinerarys, newMap, arrival, newItinerary);
        }
    }
}

正确解法先加入list中的时候就进行排序,然后注意恢复状态的过程!


public class Solution {
    HashMap<String,List<String>> maps;
    int count;
    public List<String> findItinerary(String[][] tickets) {
        maps = new HashMap<>();
        initHashMap(tickets);

        count = tickets.length+1;
        List<String> res = new LinkedList<>();
        res.add("JFK");
        dfs(res);
        return res;
    }
    private boolean dfs(List<String> res){
       if(res.size() == count)
            return true;
        String top = res.get(res.size()-1);
        List<String> lists = maps.get(top);
        if(lists == null)
            return false;

        for(int i = 0;i<lists.size();i++){
            String tmp = lists.get(i);
            res.add(tmp);
            lists.remove(i);

            if(dfs(res))//当找到合适点之后,直接返回true
                return true;
            lists.add(i,tmp);//恢复现场
            res.remove(res.size()-1);
        }
        return false;
    }
    private void initHashMap(String[][] tickets){
        for(String[] tmp:tickets){
            String from = tmp[0];
            String to = tmp[1];

            if(!maps.containsKey(from)){
                maps.put(from,new LinkedList<>());
            }
            List<String> list = maps.get(from);

            int index = 0;
            int size = list.size();
            while(index < size){
                String cur = list.get(index);
                if(cur.compareTo(to) >= 0){
                    break;
                }
                index++;
            }
            list.add(index,to);
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值