Friday, February 5, 2016

LeetCode 332 - Reconstruct Itinerary


http://bookshadow.com/weblog/2016/02/05/leetcode-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 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 may 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.

题目大意:

给定一组机票,用出发机场和到达机场[from, to]来表示,重建行程的顺序。所有的机票都属于一个从JFK(肯尼迪国际机场)出发的旅客。因此,行程必须从JFK开始。
注意:
  1. 如果存在多重有效的行程,你应当返回字典序最小的那个。例如,行程["JFK", "LGA"]的字典序比["JFK", "LGB"]要小。
  2. 所有的机场用3个大写字母表示(IATA编码)。
  3. 你可以假设所有的机票均至少包含一条有效的行程。
X. DFS
解法I 深度优先搜索(DFS):
从出发机场开始,按照到达机场的字典序递归搜索
在搜索过程中删除已经访问过的机票
将到达机场分为两类:子行程中包含出发机场的记为left,不含出发机场的记为right
返回时left排在right之前
http://bookshadow.com/weblog/2016/02/05/leetcode-reconstruct-itinerary/

    def findItinerary(self, tickets):
        routes = collections.defaultdict(list)
        for s, e in tickets:
            routes[s].append(e)
        def solve(start):
            left, right = [], []
            for end in sorted(routes[start]):
                if end not in routes[start]:
                    continue
                routes[start].remove(end)
                subroutes = solve(end)
                if start in subroutes:
                    left += subroutes
                else:
                    right += subroutes
            return [start] + left + right
        return solve("JFK")

解法II 欧拉通路(Eulerian path):
https://en.wikipedia.org/wiki/Eulerian_path
an Eulerian trail (or Eulerian path) is a trail in a graph which visits every edge exactly once. Similarly, an Eulerian circuit or Eulerian cycle is an Eulerian trail which starts and ends on the same vertex
TODO: https://www.scribd.com/doc/296907217/Hierholzer-s-Algorithm
  • Choose any starting vertex v, and follow a trail of edges from that vertex until returning to v. It is not possible to get stuck at any vertex other than v, because the even degree of all vertices ensures that, when the trail enters another vertex w there must be an unused edge leaving w. The tour formed in this way is a closed tour, but may not cover all the vertices and edges of the initial graph.
  • As long as there exists a vertex u that belongs to the current tour but that has adjacent edges not part of the tour, start another trail from u, following unused edges until returning to u, and join the tour formed in this way to the previous tour.
https://leetcode.com/discuss/84659/short-ruby-python-java-c
Just Eulerian path. Greedy DFS, building the route backwards when retreating.
some observations:
  1. The nodes which have odd degrees (int and out) are the entrance or exit. In your example it's JFK and A.
  2. If there are no nodes have odd degrees, we could follow any path without stuck until hit the last exit node
  3. The reason we got stuck is because that we hit the exit
In your given example, nodes A is the exit node, we hit it and it's the exit. So we put it to the result as the last node.
First keep going forward until you get stuck. That's a good main path already. Remaining tickets form cycles which are found on the way back and get merged into that main path. By writing down the path backwards when retreating from recursion, merging the cycles into the main path is easy - the end part of the path has already been written, the start part of the path hasn't been written yet, so just write down the cycle now and then keep backwards-writing the path.
Example:
enter image description here
From JFK we first visit JFK -> A -> C -> D -> A. There we're stuck, so we write down A as the end of the route and retreat back to D. There we see the unused ticket to B and follow it: D -> B -> C -> JFK -> D. Then we're stuck again, retreat and write down the airports while doing so: Write down D before B, then JFK before D, etc. When we're back from our cycle at D, the written route is D -> B -> C -> JFK -> D -> A. Then we retreat further along the original path, prepending C, A and finally JFK to the route, ending up with the route JFK -> A -> C -> D -> B -> C -> JFK -> D -> A.
A->B, A-C, C->A.
Why A->B is the last trip if there is no way to go from B and the trips pool is not empty
Because I build the route backwards. From A the solution first visits B but didn't put anything into the route yet. Then when it's stuck at B, it puts B at the end of the route. The recursion retreats to A, where the A->C->A cycle will be found and inserted into the route before the B.
public List<String> findItinerary(String[][] tickets) {
    for (String[] ticket : tickets)
        targets.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]);
    visit("JFK");
    return route;
}

Map<String, PriorityQueue<String>> targets = new HashMap<>();
List<String> route = new LinkedList();

void visit(String airport) {
    while(targets.containsKey(airport) && !targets.get(airport).isEmpty())
        visit(targets.get(airport).poll());
    route.add(0, airport);
}
Iterative version:
public List<String> findItinerary(String[][] tickets) {
    Map<String, PriorityQueue<String>> targets = new HashMap<>();
    for (String[] ticket : tickets)
        targets.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]);
    List<String> route = new LinkedList();
    Stack<String> stack = new Stack<>();
    stack.push("JFK");
    while (!stack.empty()) {
        while (targets.containsKey(stack.peek()) && !targets.get(stack.peek()).isEmpty())
            stack.push(targets.get(stack.peek()).poll());
        route.add(0, stack.pop());
    }
    return route;
}
https://discuss.leetcode.com/topic/36385/share-solution-java-greedy-stack-15ms-with-explanation
Noticed some folks are using Hierholzer's algorithm to find a Eulerian path.
My solution is similar, considering this passenger has to be physically in one place before move to another airport, we are considering using up all tickets and choose lexicographically smaller solution if in tie as two constraints.
Thinking as that passenger, the passenger choose his/her flight greedy as the lexicographical order, once he/she figures out go to an airport without departure with more tickets at hand. the passenger will push current ticket in a stack and look at whether it is possible for him/her to travel to other places from the airport on his/her way.
https://discuss.leetcode.com/topic/36383/share-my-solution
All the airports are vertices and tickets are directed edges. Then all these tickets form a directed graph.
The graph must be Eulerian since we know that a Eulerian path exists.
Thus, start from "JFK", we can apply the Hierholzer's algorithm to find a Eulerian path in the graph which is a valid reconstruction.
Since the problem asks for lexical order smallest solution, we can put the neighbors in a min-heap. In this way, we always visit the smallest possible neighbor first in our trip.

From this link http://www.geeksforgeeks.org/euler-circuit-directed-graph/, I found the following definition of a Eulerian graph.
Eulerian Cycle
A directed graph has an eulerian cycle if following conditions are true (Source: Wiki)
  1. All vertices with nonzero degree belong to a single strongly connected component.
  2. In degree and out degree of every vertex is same.

    Map<String, PriorityQueue<String>> flights;
    LinkedList<String> path;

    public List<String> findItinerary(String[][] tickets) {
        flights = new HashMap<>();
        path = new LinkedList<>();
        for (String[] ticket : tickets) {
            flights.putIfAbsent(ticket[0], new PriorityQueue<>());
            flights.get(ticket[0]).add(ticket[1]);
        }
        dfs("JFK");
        return path;
    }

    public void dfs(String departure) {
        PriorityQueue<String> arrivals = flights.get(departure);
        while (arrivals != null && !arrivals.isEmpty())
            dfs(arrivals.poll());
        path.addFirst(departure);
    }
http://www.cnblogs.com/EdwardLiu/p/5184961.html
First keep going forward until you get stuck. Put the stuck element always at the front of the result list. Try if it is possible to travel to other places from the airport on the way.
From JFK we first visit JFK -> A -> C -> D -> A. There we're stuck, so we write down A as the end of the route and retreat back to D. There we see the unused ticket to B and follow it: D -> B -> C -> JFK -> D. Then we're stuck again, retreat and write down the airports while doing so: Write down D before A, then JFK before D, the c before JFK, etc. When we're back from our cycle at D, the written route is D -> B -> C -> JFK -> D -> A. Then we retreat further along the original path, prepending C, A and finally JFK to the route, ending up with the route JFK -> A -> C -> D -> B -> C -> JFK -> D -> A.
Since the problem asks for lexical order smallest solution, we can put the neighbors in a min-heap. In this way, we always visit the smallest possible neighbor first in our trip.
Use LinkedList as the result type because we always add at the front of the list

public List<String> findItinerary(String[][] tickets) { for (String[] ticket : tickets) targets.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]); visit("JFK"); return route; } Map<String, PriorityQueue<String>> targets = new HashMap<>(); List<String> route = new LinkedList(); void visit(String airport) { while(targets.containsKey(airport) && !targets.get(airport).isEmpty()) visit(targets.get(airport).poll()); route.add(0, airport); }

Iterative version:
public List<String> findItinerary(String[][] tickets) {
    Map<String, PriorityQueue<String>> targets = new HashMap<>();
    for (String[] ticket : tickets)
        targets.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]);
    List<String> route = new LinkedList();
    Stack<String> stack = new Stack<>();
    stack.push("JFK");
    while (!stack.empty()) {
        while (targets.containsKey(stack.peek()) && !targets.get(stack.peek()).isEmpty())
            stack.push(targets.get(stack.peek()).poll());
        route.add(0, stack.pop());
    }
    return route;
}
https://leetcode.com/discuss/84702/share-my-solution
Map<String, PriorityQueue<String>> flights; LinkedList<String> path; public List<String> findItinerary(String[][] tickets) { flights = new HashMap<>(); path = new LinkedList<>(); for (String[] ticket : tickets) { flights.putIfAbsent(ticket[0], new PriorityQueue<>());//create pq everytime,inefficient flights.get(ticket[0]).add(ticket[1]); } dfs("JFK"); return path; } public void dfs(String departure) { PriorityQueue<String> arrivals = flights.get(departure); while (arrivals != null && !arrivals.isEmpty()) dfs(arrivals.poll()); path.addFirst(departure); }

将机场视为顶点,机票看做有向边,可以构成一个有向图。
通过图(无向图或有向图)中所有边且每边仅通过一次的通路称为欧拉通路,相应的回路称为欧拉回路。具有欧拉回路的图称为欧拉图(Euler Graph),具有欧拉通路而无欧拉回路的图称为半欧拉图。
因此题目的实质就是从JFK顶点出发寻找欧拉通路,可以利用Hierholzer算法。
def findItinerary(self, tickets): targets = collections.defaultdict(list) for a, b in sorted(tickets)[::-1]: targets[a] += b, route = [] def visit(airport): while targets[airport]: visit(targets[airport].pop()) route.append(airport) visit('JFK') return route[::-1]

This is an application of Hierholzer’s algorithm to find a Eulerian path.
PriorityQueue should be used instead of TreeSet, because there are duplicate entries.
http://algobox.org/reconstruct-itinerary/
All the airports are vertices and tickets are directed edges. Then all these tickets form a directed graph.
The graph must be Eulerian since we know that a Eulerian path exists: the man’s real itinerary.
Thus, start from “JFK”, we can apply the Hierholzer’s algorithm to find a Eulerian path in the graph which is a valid reconstruction.
Since the problem asks for lexical order smallest solution, we can put the neighbors in a min-heap. In this way, we always visit the smallest possible neighbor first in our trip.
    Map<String, PriorityQueue<String>> flights;
    LinkedList<String> path;
    public List<String> findItinerary(String[][] tickets) {
        flights = new HashMap<>();
        path = new LinkedList<>();
        for (String[] ticket : tickets) {
            flights.putIfAbsent(ticket[0], new PriorityQueue<>());
            flights.get(ticket[0]).add(ticket[1]);
        }
        dfs("JFK");
        return path;
    }
    public void dfs(String departure) {
        PriorityQueue<String> arrivals = flights.get(departure);
        while (arrivals != null && !arrivals.isEmpty())
            dfs(arrivals.poll());
        path.addFirst(departure);
    }
https://leetcode.com/discuss/84706/share-solution-java-greedy-stack-15ms-with-explanation
https://asanchina.wordpress.com/2016/02/04/332-reconstruct-itinerary/
我刚开始以为建图后用拓扑排序来做,结果是错的,这道题并不是拓扑排序。以前做拓扑排序要求访问每个一次且仅一次,这道题是要求访问每条一次且仅一次,所以只能用DFS搜索。
本来就是普通的dfs,但是这道题各种要求使得题目复杂了不少:
  1. 输入是string,不是int
  2. 要求输出最小序列
所以针对上面两个要求,我首先将每个string转换成对应的int型,因为每个string只有3个letter,这些letter我们可以看成是26进制的letter,所以3个letter可以对应一个26进制的数字。假设strings = [‘AAA’, ‘BBB’, ‘CCC’, ‘DDD’, ‘ZZZ’], 对应的int型数值是[0, 703, 1406, 2109, 17575]。接着就是dfs这个邻接表了,由于要求访问每条边,所以不用设visited数组,只要访问的过程中标记边就够了。
1, 用hash表存储路径
上面谈到string需要转换成int型再存图,这样比较好处理,其实我们可以利用hash来存储路径(hash的本质就是用int型来代表某一个object):
2, 转换成int型(不进行离散化)
上面的代码运行的很慢,要368ms,究其原因是申请的空间太多,导致没必要的for循环。显而易见,上面26*26*26不一定都用到了,我们可以尝试离散化。
假设strings = [‘AAA’, ‘BBB’, ‘CCC’, ‘DDD’, ‘ZZZ’], 对应的int型数值是[0, 703, 1406, 2109, 17575],进行离散化后对应的label就是[0,1,2,3,4]。
我们用label值(即离散化后的值)建图,图用邻接表表示,接着就是和上面一样的做法了。
    vector<string> findItinerary(vector<pair<string, string> > tickets) {
        int size = tickets.size();
        
        int map[26*26*26];
        memset(map, 0xff, sizeof(map));
        int mini = 26*26*26, maxi = -1;
        for(int i = 0; i < size; ++i) 
        { 
            int num = getNumber(tickets[i].first); 
            mini = mini>num?num:mini;
            maxi = maxi<num?num:maxi; 
            map[num] = 0; 
            num = getNumber(tickets[i].second); 
            mini = mini>num?num:mini;
            maxi = maxi<num?num:maxi;
            map[num] = 0;
        }
        
        vector<int> label;
        int pos = 0;
        for(int i = mini; i <= maxi; ++i)
            if(map[i] == 0)
            {
                label.push_back(i);
                map[i] = pos++;
            }
            
        vector<vector<int> > adj(pos);
        for(int i = 0; i < size; ++i)
        {
            int from = getNumber(tickets[i].first);
            int to = getNumber(tickets[i].second);
            int fromLabel = map[from];
            int toLabel = map[to];
            
            adj[fromLabel].push_back(toLabel);
        }
        
        for(int i = 0; i < pos; ++i)
            sort(adj[i].begin(), adj[i].end());
        
        int start = map[getNumber("JFK")];
        vector<int> order(size+1);
        order[0] = start;
        bool flag = false;
        dfs(adj, order, start, 1, flag);
        
        return reconstruct(label, order);
    }
private:
    void dfs(vector<vector<int> > &adj, vector<int> &order, int label, int pos, bool &flag)
    {
        if(flag) return;
        int size = order.size();
        if(pos == size)
        {
            flag = true;
            return;
        }
        
        int neighborSize = adj[label].size();
        for(int i = 0; i < neighborSize; ++i)
            if(adj[label][i] != -1)
            {
                order[pos] = adj[label][i];
                int prev = adj[label][i];
                adj[label][i] = -1;
                dfs(adj, order, prev, pos+1, flag);
                if(flag) return;
                adj[label][i] = prev;
            }
    }
    
    vector<string> reconstruct(vector<int> &label, vector<int> &order)
    {
        int size = order.size();
        vector<string> result(size);
        for(int i = 0; i < size; ++i)
        {
            int num = label[order[i]];
            result[i] = getString(num);
        }
        return result;
    }
    
    
    int getNumber(string& s)
    {
        int sum = 0;
        for(int i = 0; i < 3; ++i) 
        { 
            sum *= 26; 
            sum += s[i]-'A'; 
        } 
        return sum; 
    } 
    string getString(int number) 
    { 
        string ret(3, ' '); 
        for(int i = 2; i >= 0; --i)
        {
            ret[i] = number%26+'A';
            number /= 26;
        }
        return ret;
    }
https://leetcode.com/discuss/85213/java-11ms-solution-hashmap-%26-sorted-list
https://leetcode.com/discuss/86611/java-14ms-dfs-backtrack
public List<String> findItinerary(String[][] tickets) { ArrayList<String> result = new ArrayList<String>(); if(tickets == null || tickets.length == 0){ return result; } int total = tickets.length + 1; HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>(); for(int i = 0; i < tickets.length; i++){ if(map.containsKey(tickets[i][0])){ ArrayList<String> tmp = map.get(tickets[i][0]); listAdd(tickets[i][1], tmp); } else{ ArrayList<String> tmp = new ArrayList<String>(); tmp.add(tickets[i][1]); map.put(tickets[i][0], tmp); } } result.add("JFK"); itineraryHelper("JFK", map, result, total, 1); return result; } public boolean itineraryHelper(String current, HashMap<String, ArrayList<String>> map, ArrayList<String> result, int total, int num){ if(num >= total){ return true; } if(!map.containsKey(current) || map.get(current).size() == 0){ return false; } ArrayList<String> curList = map.get(current); int i = 0; while(i < curList.size()){ String next = curList.remove(i); result.add(next); if(itineraryHelper(next, map, result, total, num + 1)){ return true; } result.remove(result.size() - 1); listAdd(next, curList); i++; } return false; } public void listAdd(String value, ArrayList<String> list){ if(list.size() == 0){ list.add(value); return; } else{ int i = 0; while(i < list.size()){ if(value.compareTo(list.get(i)) <= 0){ list.add(i, value); return; } i++; } list.add(value); return; } }


https://discuss.leetcode.com/topic/36332/ac-java-solution-dfs-with-treemap
https://discuss.leetcode.com/topic/36836/java-map-with-treeset-based-solution
public List<String> findItinerary(String[][] tickets) {
  Map<String,Set<String>> cityToDests = new HashMap<String,Set<String>>();
  Map<String, Integer> avlTickets = new HashMap<String, Integer>();
  for (String[] str: tickets){
   String ticket = str[0]+"_"+str[1];
            avlTickets.put(ticket,avlTickets.get(ticket)!=null?avlTickets.get(ticket)+1:1);
            cityToDests.put(str[0],cityToDests.get(str[0])!=null?
                    cityToDests.get(str[0]):new TreeSet<String>());
            Set<String> set = cityToDests.get(str[0]);
            set.add(str[1]);
        }
  List<String> itinerary = new ArrayList<String>();
  itinerary.add("JFK");
  return findItineraryHelper("JFK", avlTickets, cityToDests, itinerary);
 }
 private List<String> findItineraryHelper(String fromCity, Map<String,Integer> avlTickets,
       Map<String, Set<String>> cityToDests, List<String> itinerary){
  if (cityToDests.get(fromCity)!=null && !avlTickets.isEmpty()){
      for (String toCity:cityToDests.get(fromCity)){
       String ticket = fromCity+"_"+toCity;
       if (avlTickets.get(ticket) != null){
           int newCnt = avlTickets.get(ticket)-1;
           int dc=newCnt==0?avlTickets.remove(ticket):avlTickets.put(ticket,newCnt);
           itinerary.add(toCity);
           findItineraryHelper(toCity, avlTickets, cityToDests, itinerary);
              if (avlTickets.isEmpty()) 
            break;
           avlTickets.put(ticket, ++newCnt);
           itinerary.remove(itinerary.size()-1);
       }
      }
  }
  return itinerary;
 }

https://asanchina.wordpress.com/2016/02/04/332-reconstruct-itinerary/

题目其实可以增加难度的,比如,有的飞机票就是用不到啊[a,b ] [b,c] [f,g]最后一张用不到,让你求最多跑多少,多解输出最小序列。
https://discuss.leetcode.com/topic/36385/share-solution-java-greedy-stack-15ms-with-explanation

No comments:

Post a Comment

Labels

GeeksforGeeks (959) Algorithm (811) LeetCode (630) to-do (595) Classic Algorithm (334) Review (327) Classic Interview (299) Dynamic Programming (262) Google Interview (224) LeetCode - Review (224) Tree (146) POJ (137) Difficult Algorithm (136) EPI (127) Different Solutions (118) Bit Algorithms (110) Cracking Coding Interview (110) Smart Algorithm (109) Math (91) HackerRank (85) Lintcode (83) Binary Search (73) Graph Algorithm (73) Interview Corner (61) Greedy Algorithm (59) List (58) Binary Tree (56) DFS (54) Algorithm Interview (53) Codility (52) ComProGuide (52) Advanced Data Structure (51) LeetCode - Extended (47) USACO (46) Geometry Algorithm (44) BFS (43) Data Structure (42) Mathematical Algorithm (42) ACM-ICPC (41) Interval (38) Jobdu (38) Recursive Algorithm (38) Stack (38) String Algorithm (38) Binary Search Tree (37) Knapsack (37) Codeforces (36) Introduction to Algorithms (36) Matrix (36) Must Known (36) Beauty of Programming (35) Sort (35) Array (33) prismoskills (33) Segment Tree (32) Space Optimization (32) Trie (32) Union-Find (32) Backtracking (31) HDU (31) Google Code Jam (30) Permutation (30) Puzzles (30) Array O(N) (29) Data Structure Design (29) Company-Zenefits (28) Microsoft 100 - July (28) to-do-must (28) Random (27) Sliding Window (26) GeeksQuiz (25) Logic Thinking (25) hihocoder (25) High Frequency (23) Palindrome (23) Algorithm Game (22) Company - LinkedIn (22) Graph (22) Queue (22) DFS + Review (21) Hash (21) TopCoder (21) Binary Indexed Trees (20) Brain Teaser (20) CareerCup (20) Company - Twitter (20) Pre-Sort (20) Company-Facebook (19) UVA (19) Probabilities (18) Codercareer (16) Company-Uber (16) Game Theory (16) Heap (16) Shortest Path (16) String Search (16) Topological Sort (16) Tree Traversal (16) itint5 (16) Follow Up (15) Iterator (15) Merge Sort (15) O(N) (15) Difficult (14) Number (14) Number Theory (14) Post-Order Traverse (14) Priority Quieue (14) Amazon Interview (13) BST (13) Basic Algorithm (13) Bisection Method (13) Codechef (13) Majority (13) mitbbs (13) Combination (12) Computational Geometry (12) KMP (12) Long Increasing Sequence(LIS) (12) Modify Tree (12) Reconstruct Tree (12) Reservoir Sampling (12) 尺取法 (12) AOJ (11) DFS+Backtracking (11) Fast Power Algorithm (11) Graph DFS (11) LCA (11) LeetCode - DFS (11) Ordered Stack (11) Princeton (11) Tree DP (11) 挑战程序设计竞赛 (11) Binary Search - Bisection (10) Company - Microsoft (10) Company-Airbnb (10) Euclidean GCD (10) Facebook Hacker Cup (10) HackerRank Easy (10) Reverse Thinking (10) Rolling Hash (10) SPOJ (10) Theory (10) Tutorialhorizon (10) X Sum (10) Coin Change (9) Lintcode - Review (9) Mathblog (9) Max-Min Flow (9) Stack Overflow (9) Stock (9) Two Pointers (9) Book Notes (8) Bottom-Up (8) DP-Space Optimization (8) Divide and Conquer (8) Graph BFS (8) LeetCode - DP (8) LeetCode Hard (8) Prefix Sum (8) Prime (8) System Design (8) Tech-Queries (8) Use XOR (8) 穷竭搜索 (8) Algorithm Problem List (7) DFS+BFS (7) Facebook Interview (7) Fibonacci Numbers (7) Game Nim (7) HackerRank Difficult (7) Hackerearth (7) Interval Tree (7) Linked List (7) Longest Common Subsequence(LCS) (7) Math-Divisible (7) Miscs (7) O(1) Space (7) Probability DP (7) Radix Sort (7) Simulation (7) Suffix Tree (7) Xpost (7) n00tc0d3r (7) 蓝桥杯 (7) Bucket Sort (6) Catalan Number (6) Classic Data Structure Impl (6) DFS+DP (6) DP - Tree (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Level Order Traversal (6) Manacher (6) Minimum Spanning Tree (6) One Pass (6) Programming Pearls (6) Quick Select (6) Rabin-Karp (6) Randomized Algorithms (6) Sampling (6) Schedule (6) Suffix Array (6) Threaded (6) Time Complexity (6) reddit (6) AI (5) Art Of Programming-July (5) Big Data (5) Brute Force (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Crazyforcode (5) DFS+Cache (5) DP-Multiple Relation (5) DP-Print Solution (5) Dutch Flag (5) Fast Slow Pointers (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Inversion (5) Java (5) Kadane - Extended (5) Kadane’s Algorithm (5) Matrix Chain Multiplication (5) Microsoft Interview (5) Morris Traversal (5) Pruning (5) Quick Partition (5) Quora (5) SPFA(Shortest Path Faster Algorithm) (5) Subarray Sum (5) Traversal Once (5) TreeMap (5) jiuzhang (5) to-do-2 (5) 单调栈 (5) 树形DP (5) 1point3acres (4) Anagram (4) Approximate Algorithm (4) Backtracking-Include vs Exclude (4) Brute Force - Enumeration (4) Chess Game (4) Company-Amazon (4) Consistent Hash (4) Convex Hull (4) Cycle (4) DP-Include vs Exclude (4) Dijkstra (4) Distributed (4) Eulerian Cycle (4) Flood fill (4) Graph-Classic (4) HackerRank AI (4) Histogram (4) Kadane Max Sum (4) Knapsack - Mixed (4) Knapsack - Unbounded (4) Left and Right Array (4) MinMax (4) Multiple Data Structures (4) N Queens (4) Nerd Paradise (4) Parallel Algorithm (4) Practical Algorithm (4) Pre-Sum (4) Probability (4) Programcreek (4) Quadtrees (4) Quick Sort (4) Spell Checker (4) Stock Maximize (4) Subsets (4) Sudoku (4) Sweep Line (4) Symbol Table (4) TreeSet (4) Triangle (4) Water Jug (4) Word Ladder (4) algnotes (4) fgdsb (4) 最大化最小值 (4) A Star (3) Abbreviation (3) Algorithm - Brain Teaser (3) Algorithm Design (3) Anagrams (3) B Tree (3) Big Data Algorithm (3) Binary Search - Smart (3) Caterpillar Method (3) Coins (3) Company - Groupon (3) Company - Indeed (3) Cumulative Sum (3) DP-Fill by Length (3) DP-Two Variables (3) Dedup (3) Dequeue (3) Dropbox (3) Easy (3) Edit Distance (3) Expression (3) Finite Automata (3) Forward && Backward Scan (3) Github (3) GoLang (3) Include vs Exclude (3) Joseph (3) Jump Game (3) Knapsack-多重背包 (3) LeetCode - Bit (3) LeetCode - TODO (3) Linked List Merge Sort (3) LogN (3) Maze (3) Min Cost Flow (3) Minesweeper (3) Missing Numbers (3) NP Hard (3) Online Algorithm (3) Pascal's Triangle (3) Pattern Match (3) Project Euler (3) Rectangle (3) Scala (3) SegmentFault (3) Stack - Smart (3) State Machine (3) Streaming Algorithm (3) Subset Sum (3) Subtree (3) Transform Tree (3) Two Pointers Window (3) Warshall Floyd (3) With Random Pointer (3) Word Search (3) bookkeeping (3) codebytes (3) Activity Selection Problem (2) Advanced Algorithm (2) AnAlgorithmADay (2) Application of Algorithm (2) Array Merge (2) BOJ (2) BT - Path Sum (2) Balanced Binary Search Tree (2) Bellman Ford (2) Binomial Coefficient (2) Bit Mask (2) Bit-Difficult (2) Bloom Filter (2) Book Coding Interview (2) Branch and Bound Method (2) Clock (2) Codesays (2) Company - Baidu (2) Complete Binary Tree (2) DFS+BFS, Flood Fill (2) DP - DFS (2) DP-3D Table (2) DP-Classical (2) DP-Output Solution (2) DP-Slide Window Gap (2) DP-i-k-j (2) DP-树形 (2) Distributed Algorithms (2) Divide and Conqure (2) Doubly Linked List (2) GoHired (2) Graham Scan (2) Graph - Bipartite (2) Graph BFS+DFS (2) Graph Coloring (2) Graph-Cut Vertices (2) Hamiltonian Cycle (2) Huffman Tree (2) In-order Traverse (2) Include or Exclude Last Element (2) Information Retrieval (2) Interview - Linkedin (2) Invariant (2) Islands (2) Knuth Shuffle (2) LeetCode - Recursive (2) Linked Interview (2) Linked List Sort (2) Longest SubArray (2) Lucene-Solr (2) MST (2) MST-Kruskal (2) Master Theorem (2) Math-Remainder Queue (2) Matrix Power (2) Minimum Vertex Cover (2) Negative All Values (2) Number Each Digit (2) Numerical Method (2) Object Design (2) Order Statistic Tree (2) Palindromic (2) Parentheses (2) Parser (2) Peak (2) Programming (2) Range Minimum Query (2) Reuse Forward Backward (2) Robot (2) Rosettacode (2) Scan from right (2) Search (2) Shuffle (2) Sieve of Eratosthenes (2) SimHash (2) Simple Algorithm (2) Skyline (2) Spatial Index (2) Stream (2) Strongly Connected Components (2) Summary (2) TV (2) Tile (2) Traversal From End (2) Tree Sum (2) Tree Traversal Return Multiple Values (2) Word Break (2) Word Graph (2) Word Trie (2) Young Tableau (2) 剑指Offer (2) 数位DP (2) 1-X (1) 51Nod (1) Akka (1) Algorithm - How To (1) Algorithm - New (1) Algorithm Series (1) Algorithms Part I (1) Analysis of Algorithm (1) Array-Element Index Negative (1) Array-Rearrange (1) Auxiliary Array (1) Auxiliary Array: Inc&Dec (1) BACK (1) BK-Tree (1) BZOJ (1) Basic (1) Bayes (1) Beauty of Math (1) Big Integer (1) Big Number (1) Binary (1) Binary Tree Variant (1) Bipartite (1) Bit-Missing Number (1) BitMap (1) BitMap index (1) BitSet (1) Bug Free Code (1) BuildIt (1) C/C++ (1) CC Interview (1) Cache (1) Calculate Height at Same Recusrion (1) Cartesian tree (1) Check Tree Property (1) Chinese (1) Circular Buffer (1) Code Quality (1) Codesolutiony (1) Company - Alibaba (1) Company - Palantir (1) Company - WalmartLabs (1) Company-Apple (1) Company-Epic (1) Company-Salesforce (1) Company-Snapchat (1) Company-Yelp (1) Compression Algorithm (1) Concurrency (1) Convert BST to DLL (1) Convert DLL to BST (1) Custom Sort (1) Cyclic Replacement (1) DFS-Matrix (1) DP - Probability (1) DP Fill Diagonal First (1) DP-Difficult (1) DP-End with 0 or 1 (1) DP-Fill Diagonal First (1) DP-Graph (1) DP-Left and Right Array (1) DP-MaxMin (1) DP-Memoization (1) DP-Node All Possibilities (1) DP-Optimization (1) DP-Preserve Previous Value (1) DP-Print All Solution (1) Database (1) Detect Negative Cycle (1) Directed Graph (1) Do Two Things at Same Recusrion (1) Domino (1) Dr Dobb's (1) Duplicate (1) Equal probability (1) External Sort (1) FST (1) Failure Function (1) Fraction (1) Front End Pointers (1) Funny (1) Fuzzy String Search (1) Game (1) Generating Function (1) Generation (1) Genetic algorithm (1) GeoHash (1) Geometry - Orientation (1) Google APAC (1) Graph But No Graph (1) Graph Transpose (1) Graph Traversal (1) Graph-Coloring (1) Graph-Longest Path (1) Gray Code (1) HOJ (1) Hanoi (1) Hard Algorithm (1) How Hash (1) How to Test (1) Improve It (1) In Place (1) Inorder-Reverse Inorder Traverse Simultaneously (1) Interpolation search (1) Interview (1) Interview - Easy (1) Interview - Facebook (1) Isomorphic (1) JDK8 (1) K Dimensional Tree (1) Knapsack - Fractional (1) Knapsack - ZeroOnePack (1) Knight (1) Kosaraju’s algorithm (1) Kruskal (1) Kruskal MST (1) Kth Element (1) Least Common Ancestor (1) LeetCode - Binary Tree (1) LeetCode - Coding (1) LeetCode - Detail (1) LeetCode - Related (1) LeetCode Diffcult (1) Linked List Reverse (1) Linkedin (1) Linkedin Interview (1) Local MinMax (1) Logic Pattern (1) Longest Common Subsequence (1) Longest Common Substring (1) Longest Prefix Suffix(LPS) (1) Manhattan Distance (1) Map && Reverse Map (1) Math - Induction (1) Math-Multiply (1) Math-Sum Of Digits (1) Matrix - O(N+M) (1) Matrix BFS (1) Matrix Graph (1) Matrix Search (1) Matrix+DP (1) Matrix-Rotate (1) Max Min So Far (1) Median (1) Memory-Efficient (1) MinHash (1) MinMax Heap (1) Monotone Queue (1) Monto Carlo (1) Multi-Reverse (1) Multiple DFS (1) Multiple Tasks (1) Next Successor (1) Offline Algorithm (1) PAT (1) Partition (1) Path Finding (1) Patience Sort (1) Persistent (1) Pigeon Hole Principle (1) Power Set (1) Pratical Algorithm (1) Probabilistic Data Structure (1) Proof (1) Python (1) Queue & Stack (1) RSA (1) Ranking (1) Rddles (1) ReHash (1) Realtime (1) Recurrence Relation (1) Recursive DFS (1) Recursive to Iterative (1) Red-Black Tree (1) Region (1) Regular Expression (1) Resources (1) Reverse Inorder Traversal (1) Robin (1) Selection (1) Self Balancing BST (1) Similarity (1) Sort && Binary Search (1) String Algorithm. Symbol Table (1) String DP (1) String Distance (1) SubMatrix (1) Subsequence (1) System of Difference Constraints(差分约束系统) (1) TSP (1) Ternary Search Tree (1) Test (1) Thread (1) TimSort (1) Top-Down (1) Tournament (1) Tournament Tree (1) Transform Tree in Place (1) Tree Diameter (1) Tree Rotate (1) Trie + DFS (1) Trie and Heap (1) Trie vs Hash (1) Trie vs HashMap (1) Triplet (1) Two Data Structures (1) Two Stacks (1) USACO - Classical (1) USACO - Problems (1) UyHiP (1) Valid Tree (1) Vector (1) Wiggle Sort (1) Wikipedia (1) Yahoo Interview (1) ZOJ (1) baozitraining (1) codevs (1) cos126 (1) javabeat (1) jum (1) namic Programming (1) sqrt(N) (1) 两次dijkstra (1) 九度 (1) 二进制枚举 (1) 夹逼法 (1) 归一化 (1) 折半枚举 (1) 枚举 (1) 状态压缩DP (1) 男人八题 (1) 英雄会 (1) 逆向思维 (1)

Popular Posts