LeetCode 207 - Course Schedule I


https://leetcode.com/problems/course-schedule/
Related: LeetCode 210 - Course Schedule II
There are a total of n courses you have to take, labeled from 0 to n - 1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.

  • Topological sorting
  • Like all graph search algorithm: O(E+V)
  • 题目等价为:检测图中是否有环
X. Topological Sort
https://leetcode.com/discuss/34699/my-java-bfs-solution
Use Map<Integer, ArrayList<Integer>>
public boolean canFinish(int numCourses, int[][] prerequisites) { Map<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>(); int[] indegree = new int[numCourses]; Queue<Integer> queue = new LinkedList<Integer>(); int count = numCourses; for (int i = 0; i < numCourses; i++) { map.put(i, new ArrayList<Integer>()); } for (int i = 0; i < prerequisites.length; i++) { map.get(prerequisites[i][0]).add(prerequisites[i][1]); indegree[prerequisites[i][1]]++; } for (int i = 0; i < numCourses; i++) { if (indegree[i] == 0) { queue.offer(i); } } while (!queue.isEmpty()) { int current = queue.poll(); for (int i : map.get(current)) { if (--indegree[i] == 0) { queue.offer(i); } } count--; } return count == 0; }
https://leetcode.com/discuss/37134/java-ac-solution-with-top-sort
Use hashset - not really better
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        Set<Integer> zeroDegree = new HashSet<>();
        int[] degree = new int[numCourses];
        for (int row = 0; row < prerequisites.length; row++)
            degree[prerequisites[row][0]]++;
        for (int i = 0; i < degree.length; i++)
            if (degree[i] == 0) zeroDegree.add(i);
        if (zeroDegree.isEmpty()) return false;
        while (!zeroDegree.isEmpty()) {
            Iterator<Integer> it = zeroDegree.iterator();
            int course = it.next();
            zeroDegree.remove(course);
            for (int row = 0; row < prerequisites.length; row++) {
                int[] edge = prerequisites[row];
                if (edge[1] == course) {
                    degree[edge[0]]--;
                    if (degree[edge[0]] == 0) zeroDegree.add(edge[0]);
                }
            }
        }
        for (int i = 0; i < degree.length; i++)
            if (degree[i] != 0) return false;
        return true;
    }
not efficient
https://leetcode.com/discuss/35578/easy-bfs-topological-sort-java
http://www.programcreek.com/2014/05/leetcode-course-schedule-java/
https://leetcode.com/discuss/82347/java-easy-version-to-understand
public boolean canFinish(int numCourses, int[][] prerequisites) {
    if(prerequisites == null){
        throw new IllegalArgumentException("illegal prerequisites array");
    }
 
    int len = prerequisites.length;
 
    if(numCourses == 0 || len == 0){
        return true;
    }
 
    // counter for number of prerequisites
    int[] pCounter = new int[numCourses];
    for(int i=0; i<len; i++){
        pCounter[prerequisites[i][0]]++;
    }
 
    //store courses that have no prerequisites
    LinkedList<Integer> queue = new LinkedList<Integer>();
    for(int i=0; i<numCourses; i++){
        if(pCounter[i]==0){
            queue.add(i);
        }
    }
 
    // number of courses that have no prerequisites
    int numNoPre = queue.size();
 
    while(!queue.isEmpty()){
        int top = queue.remove();
        for(int i=0; i<len; i++){
            // if a course's prerequisite can be satisfied by a course in queue
            if(prerequisites[i][1]==top){//not efficient
                pCounter[prerequisites[i][0]]--;
                if(pCounter[prerequisites[i][0]]==0){
                    numNoPre++;
                    queue.add(prerequisites[i][0]);
                }
            }
        }
    }
 
    return numNoPre == numCourses;
}

https://leetcode.com/discuss/39456/java-dfs-and-bfs-solution
public boolean canFinish(int numCourses, int[][] prerequisites) { ArrayList[] graph = new ArrayList[numCourses]; int[] degree = new int[numCourses]; Queue queue = new LinkedList(); int count=0; for(int i=0;i<numCourses;i++) graph[i] = new ArrayList(); for(int i=0; i<prerequisites.length;i++){ degree[prerequisites[i][1]]++; graph[prerequisites[i][0]].add(prerequisites[i][1]); } for(int i=0; i<degree.length;i++){ if(degree[i] == 0){ queue.add(i); count++; } } while(queue.size() != 0){ int course = (int)queue.poll(); for(int i=0; i<graph[course].size();i++){ int pointer = (int)graph[course].get(i); degree[pointer]--; if(degree[pointer] == 0){ queue.add(pointer); count++; } } } if(count == numCourses) return true; else return false; }

X. Using
https://discuss.leetcode.com/topic/13854/easy-bfs-topological-sort-java

Could you provide the Time complexity for your solution using adjacent matrix?`
while (!queue.isEmpty()) {
        int course = queue.poll();
        count++;
        for (int i=0; i<numCourses; i++) {
            if (matrix[course][i] != 0) {
                if (--indegree[i] == 0)
                    queue.offer(i);
            }
        }
    }
For this part, I kind of guess it is not O(V^2) instead of O(V+E) because you always scan from i=0 to numCourses to check whether the matrix[course][i] is 0 or not.
Is this solution memory-efficient? The matrix seems to be a big overhead.

public boolean canFinish(int numCourses, int[][] prerequisites) {
    int[][] matrix = new int[numCourses][numCourses]; // i -> j
    int[] indegree = new int[numCourses];
    
    for (int i=0; i<prerequisites.length; i++) {
        int ready = prerequisites[i][0];
        int pre = prerequisites[i][1];
        if (matrix[pre][ready] == 0)
            indegree[ready]++; //duplicate case
        matrix[pre][ready] = 1;
    }
    
    int count = 0;
    Queue<Integer> queue = new LinkedList();
    for (int i=0; i<indegree.length; i++) {
        if (indegree[i] == 0) queue.offer(i);
    }
    while (!queue.isEmpty()) {
        int course = queue.poll();
        count++;
        for (int i=0; i<numCourses; i++) {
            if (matrix[course][i] != 0) {
                if (--indegree[i] == 0)
                    queue.offer(i);
            }
        }
    }
    return count == numCourses;
}
I rewrote the code, I think that would be O(V + E)
    // O(V + E)
    List<Integer>[] matrix = new List[numCourses];
    int[] indegree = new int[numCourses];

    // E part
    for (int[] pre : prerequisites) {
        int preCourse = pre[1];
        int readyCourse = pre[0];
        List<Integer> list = matrix[preCourse];
        if (list == null) {
         list = new LinkedList<>();   
         matrix[preCourse] = list;
        }
        list.add(readyCourse);
        indegree[readyCourse]++;
    }
    
    Queue<Integer> queue = new LinkedList<>();
    for (int i=0; i<numCourses; i++) {
        if (indegree[i] == 0) queue.offer(i);
    }
    int count = 0;
    // V part
    while (!queue.isEmpty()) {
        int vertex = queue.poll();
        count++;
        List<Integer> adjacent = matrix[vertex];
        if (adjacent == null) continue;
        for (int neighbor : adjacent) {
            indegree[neighbor]--;
            if (indegree[neighbor] == 0)
                queue.offer(neighbor);
        }
    }
    return count == numCourses;
https://leetcode.com/discuss/71444/explained-java-12ms-iterative-solution-based-algorithm-clrs
Not efficient to use ArrayList as a queue.
X. DFS
https://leetcode.com/discuss/65901/concise-java-solutions-based-on-bfs-and-dfs-with-explanation
To do memorization and pruning, a HashMap is used to save the previous results for the specific node.
HashMap<Integer, Boolean>memo = new HashMap<Integer, Boolean>();//Memorization HashMap for DFS pruning 
public boolean canFinish(int n, int[][] edges) {         
    if (edges.length != 0) { 
        HashMap<Integer, HashSet<Integer>> neighbors = new HashMap<Integer, HashSet<Integer>>(); // Neighbors of each node
        HashSet<Integer>curPath = new HashSet<Integer>(); // Nodes on the current path
        for (int i = 0; i < edges.length; i++) {// Convert graph presentation from edge list to adjacency list 
            if (!neighbors.containsKey(edges[i][1])) 
                neighbors.put(edges[i][1], new HashSet<Integer>());            
            neighbors.get(edges[i][1]).add(edges[i][0]);
        }

        for (int a[] : edges) // The graph is possibly not connected, so need to check every node.
            if (hasCycle(neighbors, a[0], -1, curPath))// Use DFS method to check if there's cycle in any curPath
                return false;
    } 
    return true;
}     

boolean hasCycle(HashMap<Integer, HashSet<Integer>> neighbors, int kid, int parent, HashSet<Integer>curPath) {
    if (memo.containsKey(kid)) return memo.get(kid);
    if (curPath.contains(kid)) return true;// The current node is already in the set of the current path        
    if (!neighbors.containsKey(kid)) return false;     

    curPath.add(kid);
    for (Integer neighbor : neighbors.get(kid)) {
        boolean hasCycle = hasCycle(neighbors, neighbor, kid, curPath);// DFS
        memo.put(kid, hasCycle);                
        if (hasCycle) return true;
    }
    curPath.remove(kid);        
    return false;
}
http://buttercola.blogspot.com/2015/08/leetcode-course-schedule.html
Use an array to mark if the node has been visited before. Here is a small trick to save some time. Instead of using a boolean array, we use an integer array int[] visited. 
visited = -1, means this node has been visited. 
visited = 1, means this node has been validated which does not include a circle. Thus if we saw that a node has been validated, we don't need to calculate again to find out the circle starting from this node. e.g. [0, 1] [1, 2] [2, 3] [3, 4]. For the node 0, we have already validated 2 3 and 4 do not have a circle. Thus we don't need to calculate for the node 2 3 4 again.
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        if (numCourses <= 0) {
            return true;
        }
         
        if (prerequisites == null || prerequisites.length == 0) {
            return true;
        }
         
        // First transform the edge list to adj. list
        Map<Integer, List<Integer>> adjList = new HashMap<>();
        for (int[] edge : prerequisites) {
            if (adjList.containsKey(edge[0])) {
                List<Integer> neighbors = adjList.get(edge[0]);
                neighbors.add(edge[1]);
                adjList.put(edge[0], neighbors);
            } else {
                List<Integer> neighbors = new ArrayList<Integer>();
                neighbors.add(edge[1]);
                adjList.put(edge[0], neighbors);
            }
        }
         
        int[] visited = new int[numCourses];
        // Check if the graph contains a circle, if yes, return false.
        for (int i = 0; i < numCourses; i++) {
            if (hasCircles(i, visited, adjList)) {
                return false;
            }
        }
         
        return true;
    }
     
    private boolean hasCircles(int vertexId, int[] visited, Map<Integer, List<Integer>> adjList) {
        if (visited[vertexId] == -1) {
            return true;
        }
         
        if (visited[vertexId] == 1) {
            return false;
        }
         
        visited[vertexId] = -1;// wrong
         
        List<Integer> neighbors = adjList.get(vertexId);
        if (neighbors != null) {
            for (int neighbor : neighbors) {
                if (hasCircles(neighbor, visited, adjList)) {
                    return true;
                }
            }
        }
         
        visited[vertexId] = 1;
         
        return false;
    }

public boolean canFinish(int numCourses, int[][] prerequisites) {
    if(prerequisites == null){
        throw new IllegalArgumentException("illegal prerequisites array");
    }
 
    int len = prerequisites.length;
 
    if(numCourses == 0 || len == 0){
        return true;
    }
 
    //track visited courses
    int[] visit = new int[numCourses];
 
    // use the map to store what courses depend on a course 
    HashMap<Integer,ArrayList<Integer>> map = new HashMap<Integer,ArrayList<Integer>>();
    for(int[] a: prerequisites){
        if(map.containsKey(a[1])){
            map.get(a[1]).add(a[0]);
        }else{
            ArrayList<Integer> l = new ArrayList<Integer>();
            l.add(a[0]);
            map.put(a[1], l);
        }
    }
 
    for(int i=0; i<numCourses; i++){
        if(!canFinishDFS(map, visit, i))
            return false;
    }
 
    return true;
}
 
private boolean canFinishDFS(HashMap<Integer,ArrayList<Integer>> map, int[] visit, int i){
    if(visit[i]==-1) 
        return false;
    if(visit[i]==1) 
        return true;
 
    visit[i]=-1;
    if(map.containsKey(i)){
        for(int j: map.get(i)){
            if(!canFinishDFS(map, visit, j)) 
                return false;
        }
    }
 
    visit[i]=1;
 
    return true;
}

http://happycoding2010.blogspot.com/2015/10/leetcode-207-course-schedule.html
 public class Solution {  
   public boolean canFinish(int numCourses, int[][] prerequisites) {  
     int V=numCourses;  
     List<Integer>[] adj=new List[V];  
     for (int v=0; v<V; v++) adj[v]=new LinkedList<>();  
     for (int i=0; i<prerequisites.length; i++) adj[prerequisites[i][1]].add(prerequisites[i][0]);  
     boolean[] marked=new boolean[V];  
     boolean[] onStack=new boolean[V];  
     boolean[] hasCycle=new boolean[1];  
     for (int v=0; v<V; v++)  
       if(!marked[v]) dfs(v,adj,V,marked,onStack,hasCycle);  
     return !hasCycle[0];  
   }  
   private void dfs(int v, List<Integer>[] adj, int V, boolean[] marked, boolean[] onStack, boolean[] hasCycle) {  
     marked[v]=true;  
     onStack[v]=true;  
     for (int w: adj[v]) {  
       if (hasCycle[0]) return;  
       else if (!marked[w]) dfs(w,adj,V,marked,onStack,hasCycle);  
       else if (onStack[w]) hasCycle[0]=true;  
     }  
     onStack[v]=false;  
   }  
 } 

http://sgq626.blogspot.com/2015/07/leetcode-207leetcode-210-course.html
这个题目很容易分析出来是check if a directed graph has a cycle.

但是给的graph是 a list of edges, 如果只给定一些edges我们是无法对graph进行遍历的,所以我们可以建立一个adjacent list, 并且带上一个state记录每个node的状态。

这个题目里面的adjacent list 可以用map来做, 然后对map做DFS遍历。
采用的是DFS + mark visitIII -> 3 states
但是需要注意的是,需要对graph里面的每个Node进行遍历,才能遍历到所有的可能。
 这个题目里面没有 sanity check !!! 面试的时候要跟面试官商量sanity check的问题。  
    bool dfs(map<int, vector<int>> &nmap, int start, vector<int> &M) {
        //base case
        if (M[start] == 1) return true;//has visited
        if (M[start] == -1) {
            return false;
        }
        M[start] = -1; //visiting node
        //expand 
        for (int i = 0; i < nmap[start].size();i++) {
           if(dfs(nmap, nmap[start][i], M) == false) return false;
        }
        M[start] = 1; //mark visit
        return true;
    }
    //to check if a directed graph has a cycle or not 
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        //map
        map<int, vector<int>> nmap;
        for (int i = 0; i < prerequisites.size(); i++) {
            nmap[prerequisites[i].second].push_back(prerequisites[i].first);//prere->course
        }
        //use map to do dfs + visit
        vector<int> M(numCourses, 0); //unvisited
        for (int i = 0; i < numCourses;i++) {
            if (dfs(nmap, i, M) == false) return false;
        }

        return true;
    }

http://felixzhang00.github.io/2015/05/07/2015-05-07-LeetCode%E7%AC%AC207%E9%A2%98--Course%20Schedule/
public boolean canFinish(int numCourses, int[][] prerequisites) {
      Digraph G = new Digraph(numCourses);
      for (int i = 0; i < prerequisites.length; i++) {
          for (int j = 0; j < prerequisites[i].length; j++) {
              G.addEdge(prerequisites[i][j], prerequisites[i][++j]);
          }
      }
      DirectedCycle dag = new DirectedCycle(G);
      return !dag.hasCycle();
}
判断有向图中是否有环

用一个数组boolean[] onStack保存递归调用期间栈上的所有顶点.

onStack[v]=true,记录顶点v出现在这次dfs中,在这次dfs结束后,是onStack[v]=false

在递归执行dfs的过程中,记录当前下当前顶点在递归调用栈中,这样以后的递归调用栈只要判断它的相连点是否在之前的递归调用栈中出现过,就能判断是否有环。
private class DirectedCycle {
    private boolean[] marked;        // marked[v] 顶点v是否被访问过
    private boolean[] onStack;       //保存递归调用期间栈上的所有顶点。 onStack[v] = ?顶点v是否在栈中
    private boolean hasCycle;       // 有向图中是否环
    public DirectedCycle(Digraph G) {
        marked = new boolean[G.V()];
        onStack = new boolean[G.V()];
        hasCycle = false;
        for (int v = 0; v < G.V(); v++)   //对图中每一个没有被访问过的点做深度优先遍历
            if (!marked[v]) dfs(G, v);
    }
    /**
     * 从v顶点开始做深度优先遍历
     */
    private void dfs(Digraph G, int v) {
        onStack[v] = true;
        marked[v] = true;
        for (int w : G.adj(v)) {        //遍历所有顶点v的相连点
            if (hasCycle) return;       //如果已经找到一个环就不再dfs
            else if (!marked[w]) {      //对每一个未访问过的点继续dfs
                dfs(G, w);
            } else if (onStack[w]) {    //顶点w在之前的递归调用栈中,并且已经被访问过,构成环
                hasCycle = true;
            }
        }
        onStack[v] = false;             //顶点v所有的相连点遍历结束,顶点v退出当前调用栈
    }
    public boolean hasCycle() {
        return hasCycle;
    }
}
private class Digraph {
    private final int V;
    private ArrayList<Integer>[] adj;
    public Digraph(int V) {
        this.V = V;
        adj = (ArrayList<Integer>[]) new ArrayList[V];
        for (int v = 0; v < V; v++) {
            adj[v] = new ArrayList<Integer>();
        }
    }
    public void addEdge(int v, int w) {
        adj[v].add(w);
    }
    public int V() {
        return V;
    }
    public Iterable<Integer> adj(int v) {
        return adj[v];
    }
}
X. Not efficient
https://leetcode.com/discuss/39456/java-dfs-and-bfs-solution
i second this. I may be wrong, but the worst case runtime could be n^2 since you are not checking if any nodes are visited in the main for loop (the one in the canFinish function). This means you may be doing repeated searches. Imagine 1->2->3->4->5, when checking node (1) in the main loop, you'll be go through 2 - 5, but when you r checking node(2) in the main loop, you'll go through 3 - 5 again.
The run time for this DFS solution is O(V + E^2). In the worst case described above by OBOBOB90 the algorithm needs to iterate over each course (which is O(V)), plus V^2 time to iterate over the course dependencies (O(E^2)).
It is possible though to implement DFS algorithm with O(E) runtime
public boolean canFinish(int numCourses, int[][] prerequisites) { ArrayList[] graph = new ArrayList[numCourses]; for(int i=0;i<numCourses;i++) graph[i] = new ArrayList(); boolean[] visited = new boolean[numCourses]; for(int i=0; i<prerequisites.length;i++){ graph[prerequisites[i][1]].add(prerequisites[i][0]); } for(int i=0; i<numCourses; i++){ if(!dfs(graph,visited,i)) return false; } return true; } private boolean dfs(ArrayList[] graph, boolean[] visited, int course){ if(visited[course]) return false; else visited[course] = true;; for(int i=0; i<graph[course].size();i++){ if(!dfs(graph,visited,(int)graph[course].get(i))) return false; } visited[course] = false; return true; }

OO:
https://leetcode.com/discuss/35035/oo-easy-to-read-java-solution

Build Order:
You are given a list of projects and a list of dependencies (which is a list of pairs of
projects, where the second project is dependent on the first project). All of a project's dependencies
must be built before the project is. Find a build order that will allow the projects to be built. If there
is no valid build order, return an error.
Project[] findBuildOrder(String[] projects, String[][] dependencies) {
        Graph graph= buildGraph(projects, dependencies);
        return orderProjects(graph.getNodes());
}

/* Build the graph, adding the edge (a, b) if b is dependent on a. Assumes a pair
 * is listed in "build order". The pair (a, b) in dependencies indicates that b
 * depends on a and a must be built before b. */
Graph buildGraph(String[] projects, String[][] dependencies) {
        Graph graph= new Graph();
        for (String project : projects) {
                graph.createNode(project);
        }

        for (String[] dependency : dependencies) {
                String first= dependency[0];
                String second= dependency[l];
                graph.addEdge(first, second);
        }

        return graph;
}

/* Return a list of the projects a correct build order.*/
Project[] orderProjects(Arraylist<Project> projects) {
        Project[] order = new Project[projects.size()];// if there are a lot of projects: use queue to remove already processed nodes

        /* Add "roots" to the build order first.*/
        int endOfList = addNonDependent(order, projects, 0);

        int toBeProcessed = 0;
        while (toBeProcessed < order.length) {
                Project current= order[toBeProcessed];

                /* We have a circular dependency since there are no remaining projects with
                 * zero dependencies. */
                if (current== null) {
                        return null;
                }

                /* Remove myself as a dependency. */
                Arraylist<Project> children = current.getChildren();
                for (Project child : children) {
                        child.decrementDependencies();
                }

                /* Add children that have no one depending on them. */
                endOfList = addNonDependent(order, children, endOfList);
                toBeProcessed++;
        }

        return order;
}

/* A helper function to insert projects with zero dependencies into the order
 * array, starting at index offset. */
int addNonDependent(Project[] order, Arraylist<Project> projects, int offset) {
        for (Project project: projects) {
                if (project.getNumberDependencies() == 0) {
                        order[offset] = project;
                        offset++;
                }
        }
        return offset;
}

public class Graph {
private Arraylist<Project> nodes= new Arraylist<Project>();
private HashMap<String, Project> map = new HashMap<String, Project>();

public Project getOrCreateNode(String name) {
        if (!map.containsKey(name)) {
                Project node = new Project(name);
                nodes.add(node);
                map.put(name, node);
        }

        return map.get(name);
}

public void addEdge(String startName, String endName) {
        Project start = getOrCreateNode(startName);
        Project end= getOrCreateNode(endName);
        start.addNeighbor(end);
}

public Arraylist<Project> getNodes() {
        return nodes;
}
}

public class Project {
private Arraylist<Project> children = new Arraylist<Project>();
private HashMap<String, Project> map= new HashMap<String, Project>();
private String name;
private int dependencies = 0;

public Project(String n) {
        name n;
}

public void addNeighbor(Project node) {
        if (!map.containsKey(node.getName())) {
                children.add(node);
                map.put(node.getName(), node);
                node.incrementDependencies();
        }
}

public void incrementDependencies() {
        dependencies++;
}
public void decrementDependencies() {
        dependencies--;
}

public String getName() {
        return name;
}
public Arraylist<Project> getChildren() {
        return children;
}
public int getNumberDependencies() {
        return dependencies;
}
}

Stack<Project> findBuildOrder(String[] projects, String[][] dependencies) {
        Graph graph= buildGraph(projects, dependencies);
        return orderProjects(graph.getNodes());
}

Stack<Project> orderProjects(ArrayList<Project> projects) {
        Stack<Project> stack = new Stack<Project>();
        for (Project project: projects) {
                if (project.getState() == Project.State.BLANK) {
                        if (!doDFS(project, stack)) {
                                return null;
                        }
                }
        }
        return stack;
}

boolean doDFS(Project project, Stack<Project> stack) {
        if (project.getState() == Project.State.PARTIAL) {
                return false; // Cycle
        }

        if (project.getState() == Project.State.BLANK) {
                project.setState(Project.State.PARTIAL);
                ArrayList<Project> children = project.getChildren();
                for (Project child : children) {
                        if (!doDFS(child, stack)) {

                        }
                        return false;
                }
                project.setState(Project.State.COMPLETE);
                stack.push(project);
        }
        return true;
}
/* Essentially equivalent to earlier solution, with state info added and
 * dependency count removed. */
public class Project {
public enum State {COMPLETE, PARTIAL, BLANK};
private State state = State.BLANK;
public State getState() {
        return state;
}
public void setState(State st) {
        state = st;
}
/* Duplicate code removed for brevity*/
}

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts