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 (1107) LeetCode (985) Algorithm (795) Review (759) to-do (631) LeetCode - Review (506) Classic Algorithm (324) Dynamic Programming (292) Classic Interview (288) Google Interview (242) Tree (145) POJ (139) Difficult Algorithm (132) LeetCode - Phone (127) EPI (125) Different Solutions (120) Bit Algorithms (118) Lintcode (113) Cracking Coding Interview (110) Smart Algorithm (109) Math (107) HackerRank (89) Binary Search (81) Binary Tree (80) Graph Algorithm (74) Greedy Algorithm (72) DFS (66) LeetCode - Extended (62) Interview Corner (61) Stack (60) List (58) Advanced Data Structure (56) Codility (54) BFS (53) ComProGuide (52) Algorithm Interview (50) Geometry Algorithm (48) Binary Search Tree (46) USACO (46) Trie (45) Mathematical Algorithm (42) ACM-ICPC (41) Interval (41) Data Structure (40) Knapsack (40) Space Optimization (40) Jobdu (39) Recursive Algorithm (39) LeetCode Hard (38) Matrix (38) String Algorithm (38) Backtracking (36) Codeforces (36) Introduction to Algorithms (36) Must Known (36) Beauty of Programming (35) Sort (35) Union-Find (34) Array (33) prismoskills (33) Segment Tree (32) Sliding Window (32) Data Structure Design (31) HDU (31) Google Code Jam (30) Permutation (30) Puzzles (30) Array O(N) (29) Company-Airbnb (29) Company-Zenefits (28) Microsoft 100 - July (28) Palindrome (28) to-do-must (28) Priority Queue (27) Random (27) Graph (26) Company - LinkedIn (25) GeeksQuiz (25) Logic Thinking (25) Pre-Sort (25) hihocoder (25) Queue (24) Company-Facebook (23) High Frequency (23) TopCoder (23) Algorithm Game (22) Hash (22) Post-Order Traverse (22) Binary Indexed Trees (21) Bisection Method (21) DFS + Review (21) Lintcode - Review (21) Brain Teaser (20) CareerCup (20) Company - Twitter (20) Merge Sort (20) Follow Up (19) O(N) (19) Time Complexity (19) Two Pointers (19) UVA (19) Ordered Stack (18) Probabilities (18) Company-Uber (17) Game Theory (17) Topological Sort (17) Codercareer (16) Heap (16) Shortest Path (16) String Search (16) Tree Traversal (16) itint5 (16) Difficult (15) Iterator (15) BST (14) Number (14) Number Theory (14) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Euclidean GCD (13) KMP (13) Long Increasing Sequence(LIS) (13) Majority (13) mitbbs (13) Combination (12) Computational Geometry (12) LeetCode - Classic (12) Modify Tree (12) Reconstruct Tree (12) Reservoir Sampling (12) Reverse Thinking (12) 尺取法 (12) AOJ (11) DFS+Backtracking (11) Fast Power Algorithm (11) Graph DFS (11) LCA (11) LeetCode - DFS (11) Miscs (11) Princeton (11) Proof (11) Tree DP (11) X Sum (11) 挑战程序设计竞赛 (11) Bisection (10) Bucket Sort (10) Coin Change (10) Company - Microsoft (10) DFS+Cache (10) Facebook Hacker Cup (10) HackerRank Easy (10) O(1) Space (10) Rolling Hash (10) SPOJ (10) Theory (10) Tutorialhorizon (10) DP-Multiple Relation (9) DP-Space Optimization (9) Divide and Conquer (9) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Prefix Sum (9) Quick Sort (9) Simulation (9) Stack Overflow (9) Stock (9) System Design (9) TreeMap (9) Use XOR (9) Book Notes (8) Bottom-Up (8) Company-Amazon (8) DFS+BFS (8) LeetCode - DP (8) Left and Right Array (8) Linked List (8) Longest Common Subsequence(LCS) (8) Prime (8) Suffix Tree (8) Tech-Queries (8) Traversal Once (8) 穷竭搜索 (8) Algorithm Problem List (7) Expression (7) Facebook Interview (7) Fibonacci Numbers (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Interval Tree (7) Inversion (7) Kadane’s Algorithm (7) Level Order Traversal (7) Math-Divisible (7) Probability DP (7) Quick Select (7) Radix Sort (7) n00tc0d3r (7) 蓝桥杯 (7) Catalan Number (6) Classic Data Structure Impl (6) DFS+DP (6) DP - Tree (6) DP-Print Solution (6) Dijkstra (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Manacher (6) Minimum Spanning Tree (6) Morris Traversal (6) Multiple Data Structures (6) One Pass (6) Programming Pearls (6) Pruning (6) Rabin-Karp (6) Randomized Algorithms (6) Sampling (6) Schedule (6) Stream (6) Suffix Array (6) Threaded (6) TreeSet (6) Xpost (6) reddit (6) AI (5) Algorithm - Brain Teaser (5) Art Of Programming-July (5) Big Data (5) Brute Force (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) Cycle (5) DP-Include vs Exclude (5) Fast Slow Pointers (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) Matrix Chain Multiplication (5) Maze (5) Microsoft Interview (5) Pre-Sum (5) Quadtrees (5) Quick Partition (5) Quora (5) SPFA(Shortest Path Faster Algorithm) (5) Subarray Sum (5) Sudoku (5) Sweep Line (5) Word Search (5) jiuzhang (5) 单调栈 (5) 树形DP (5) 1point3acres (4) Abbreviation (4) Anagram (4) Anagrams (4) Approximate Algorithm (4) Backtracking-Include vs Exclude (4) Brute Force - Enumeration (4) Chess Game (4) Consistent Hash (4) Distributed (4) Eulerian Cycle (4) Find Rule (4) Flood fill (4) Graph-Classic (4) HackerRank AI (4) Histogram (4) Kadane Max Sum (4) Knapsack - Mixed (4) Knapsack - Unbounded (4) LeetCode - Recursive (4) LeetCode - TODO (4) MST (4) MinMax (4) N Queens (4) Nerd Paradise (4) Parallel Algorithm (4) Practical Algorithm (4) Probability (4) Programcreek (4) Spell Checker (4) Stock Maximize (4) Subset Sum (4) Subsets (4) Symbol Table (4) Triangle (4) Water Jug (4) algnotes (4) fgdsb (4) to-do-2 (4) 最大化最小值 (4) A Star (3) Algorithm - How To (3) Algorithm Design (3) B Tree (3) Big Data Algorithm (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) Finite Automata (3) Github (3) GoLang (3) Graph - Bipartite (3) Include vs Exclude (3) Joseph (3) Jump Game (3) K (3) Knapsack-多重背包 (3) LeetCode - Bit (3) Linked List Merge Sort (3) LogN (3) Master Theorem (3) Min Cost Flow (3) Minesweeper (3) Missing Numbers (3) NP Hard (3) O(N) Hard (3) Online Algorithm (3) Pascal's Triangle (3) Pattern Match (3) Project Euler (3) Rectangle (3) Scala (3) SegmentFault (3) Shuffle (3) Sieve of Eratosthenes (3) Stack - Smart (3) State Machine (3) Subtree (3) Transform Tree (3) Trie + DFS (3) Two Pointers Window (3) Warshall Floyd (3) With Random Pointer (3) Word Ladder (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) Binary Search - Smart (2) Binomial Coefficient (2) Bit Counting (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) Company-Snapchat (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) Edit Distance (2) Factor (2) Forward && Backward Scan (2) GoHired (2) Graham Scan (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) Linked Interview (2) Linked List Sort (2) Longest SubArray (2) Lucene-Solr (2) Math-Remainder Queue (2) Matrix Power (2) Median (2) Minimum Vertex Cover (2) Negative All Values (2) Number Each Digit (2) Numerical Method (2) Object Design (2) Order Statistic Tree (2) Parent-Only Tree (2) Parentheses (2) Parser (2) Peak (2) Programming (2) Range Minimum Query (2) Regular Expression (2) Return Multiple Values (2) Reuse Forward Backward (2) Robot (2) Rosettacode (2) Scan from right (2) Search (2) SimHash (2) Simple Algorithm (2) Skyline (2) Spatial Index (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) Yahoo Interview (2) Young Tableau (2) 剑指Offer (2) 数位DP (2) 1-X (1) 51Nod (1) Akka (1) Algorithm - New (1) Algorithm Series (1) Algorithms Part I (1) Analysis of Algorithm (1) Array-Element Index Negative (1) Array-Rearrange (1) Augmented BST (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 Sarch Tree (1) Binary String (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) Cloest (1) Clone (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-Yelp (1) Compression Algorithm (1) Concurrency (1) Cont Improvement (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) Diagonal (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 - Facebook (1) Isomorphic (1) JDK8 (1) K Dimensional Tree (1) Knapsack - Fractional (1) Knapsack - ZeroOnePack (1) Knight (1) Knuth Shuffle (1) Kosaraju’s algorithm (1) Kruskal (1) Kth Element (1) Least Common Ancestor (1) LeetCode - Binary Tree (1) LeetCode - Coding (1) LeetCode - Detail (1) LeetCode - Related (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) Machine Learning (1) Maintain State (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) Memory-Efficient (1) MinHash (1) MinMax Heap (1) Monotone Queue (1) Monto Carlo (1) Multi-End BFS (1) Multi-Reverse (1) Multiple DFS (1) Multiple Tasks (1) Next Element (1) Next Successor (1) Offline Algorithm (1) PAT (1) Parenthesis (1) Partition (1) Path Finding (1) Patience Sort (1) Persistent (1) Pigeon Hole Principle (1) Power Set (1) Pratical Algorithm (1) PreProcess (1) Probabilistic Data Structure (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) Resources (1) Reverse Inorder Traversal (1) Robin (1) Selection (1) Self Balancing BST (1) Similarity (1) Sort && Binary Search (1) Square (1) Streaming Algorithm (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) Test Cases (1) Thread (1) TimSort (1) Top-Down (1) Tournament (1) Tournament Tree (1) Transform Tree in Place (1) Tree Diameter (1) Tree Rotate (1) Tree Without Tree Predefined (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) Virtual Matrix (1) Wiggle Sort (1) Wikipedia (1) ZOJ (1) ZigZag (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