[
  {
    "path": ".gitignore",
    "content": "interview.iml\ninterview.ipr\ninterview.iws\nbuild/\n.gradle/\n.classpath\n.project\n.settings/\n/bin/\n/out\n.DS_Store\npython/graph/__pycache__/\npython/.idea\ntarget/\n"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_9\" default=\"false\" project-jdk-name=\"1.8\" project-jdk-type=\"JavaSDK\" />\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "C++/Arrays/Trapping the rain water.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nint trapped_water(int array[],int size){\n    int amount = 0;\n    int left[size],right[size];\n    left[0] = array[0]; right[size-1] = array[size-1];\n    for(int i = 1; i < size; i++){\n        left[i] = max(left[i-1],array[i]);\n    }\n    for(int i = size-2; i >=0; i--){\n        right[i] = max(right[i+1],array[i]);\n    }\n    for(int i = 0  ; i < size;i++){\n        amount += min(left[i],right[i]) - array[i];\n    }\n    return  amount;\n}\n\nint main(){\n    int array[] = {1,0,3,4,5,0,5,7,7,8,9,0};\n    int size = sizeof(array) / sizeof(int);\n    cout << trapped_water(array,size);\n    return  0;\n}\n"
  },
  {
    "path": "C++/Bit Manipulation/Checking Whether K-th Bit is Set or Not.cpp",
    "content": "#include<iostream>\nusing namespace std;\nint main(){\n    int n,k;\n    cout << \"Enter the number and the value of K : \";\n    cin >> n >> k;\n    int mask = 1 << (k-1);\n    if(n & mask){\n        cout << \"Yes K-th bit is set\" << endl;\n    }\n    else{\n        cout << \"No K-th bit is not set\" << endl;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "C++/Bit Manipulation/Clearing the K-th bit of a number.cpp",
    "content": "#include<iostream>\nusing namespace std;\nint main(){\n    int n,k,mask;\n    cout << \"Enter the number and the value of K : \";\n    cin >> n >> k;\n    mask = ~(1 << (k-1));\n    n = n&mask;\n    cout << \"The number after clearing the K-th bit is : \" << n << endl;\n    return 0;\n}\n"
  },
  {
    "path": "C++/Bit Manipulation/Setting the K-th bit of a number.cpp",
    "content": "#include<iostream>\nusing namespace std;\nint main(){\n    int n,k;\n    cout << \"Enter the number and the value of K :\";\n    cin >> n >> k;\n    int mask = 1 << (k - 1);\n    n = n | mask;\n    cout << \"The number after setting the K-th bit is:\" << n;\n    return 0;\n}\n"
  },
  {
    "path": "C++/Bit Manipulation/Toggling Rightmost Set Bit of a number.cpp",
    "content": "#include<iostream>\nusing namespace std;\nint main(){\n    int n;\n    cout << \"Enter the number : \";\n    cin >> n ;\n    n = n & (n-1);\n    cout << \"The number after toggling right most set bit : \" << n << endl;\n    return 0;\n}\n"
  },
  {
    "path": "C++/Bit Manipulation/Toggling the K-th bit of a number.cpp",
    "content": "#include<iostream>\nusing namespace std;\nint main(){\n    int n,k,mask;\n    cout << \"Enter the number and the value of K : \";\n    cin >> n >> k;\n    mask = 1 << (k-1);\n    n = n ^ mask;\n    cout << \"The number after toggling the K-th bit is : \" << n << endl;\n    return 0;\n}\n"
  },
  {
    "path": "C++/Dynamic Programming/Edit Distance.cpp",
    "content": "int editDistance(string s1, string s2){\n    int m = s1.length();\n    int n = s2.length();\n    int dp[m+1][n+1];\n    for (int i = 0; i <= m; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 0; j <= n; j++) {\n        dp[0][j] = j;\n    }\n\n    for (int i = 1; i <= m; i++) {\n        for (int j = 1; j <= n; j++) {\n        if (s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1];\n            else dp[i][j] = 1 + min(min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1]);\n        }\n    }\n    return dp[m][n];\n}\n"
  },
  {
    "path": "C++/Dynamic Programming/Longest Common Subsequence.cpp",
    "content": "int lcs(string x,string y){\n    int m = x.size(),n = y.size();\n    int dp[m+1][n+1];\n    for(int i=0;i<=m;i++){\n        dp[i][0] = 0;\n    }\n    for(int j=0;j<=m;j++){\n        dp[0][j] = 0;\n    }\n    for(int i=1;i<=m;i++){\n        for(int j=1;j<=n;j++){\n            if(x[i-1] == y[j-1]){\n                dp[i][j] = dp[i-1][j-1]+1;\n            }\n            else{\n                dp[i][j] = max(dp[i][j-1],dp[i-1][j]);\n            }\n        }\n    }\n    return dp[m][n];\n}\n"
  },
  {
    "path": "C++/Dynamic Programming/Longest Common Substring.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nint longest_common_substring(string x,string y){\n    int m =  x.size();\n    int n =  y.size();\n    int lcs[m+1][n+1];\n    for(int i = 0 ; i < m; i++){\n        lcs[i][0] = 0;\n    }\n    for(int j = 0; j < n; j++){\n        lcs[0][j] = 0;\n    }\n    for(int i = 1; i <= m; i++){\n        for(int j = 1; j <=n; j++){\n            if(x[i-1] == y[j-1]){\n                lcs[i][j] = 1 + lcs[i-1][j-1];\n            }\n            else{\n                lcs[i][j] = 0;\n            }\n        }\n    }\n    return lcs[m][n];\n}\nint main(){\n    string x,y;\n    cin >> x >> y;\n    cout << longest_common_substring(x,y);\n    return 0;\n}"
  },
  {
    "path": "C++/Dynamic Programming/Longest Increasing Subsequence.cpp",
    "content": "int lis(int array[],int n){\n    int dp[n],lis_value = -1;\n    for(int i=0;i<n;i++){\n        dp[i] = 1;\n    }\n    for(int i=1;i<n;i++){\n        for(int j=0;j<i;j++){\n            if(array[i] > array[j] and dp[i] < dp[j]+1){\n                dp[i] = dp[j] + 1;\n            }\n        }\n    }\n    for(int i=0;i<n;i++){\n        if(lis_value < dp[i]){\n            lis_value = dp[i];\n        }\n    }\n    return lis_value;\n}\n"
  },
  {
    "path": "C++/Dynamic Programming/Longest palindromic Subsequence.cpp",
    "content": "#include <iostream>\nusing namespace std;\nint longest_palindromic_subsequence(string str){\n    int table[str.size()][str.size()];\n    for(int i = 0 ; i < str.size(); i++){\n        table[i][i] = 1;\n    }\n    for(int l = 1 ; l < str.size() ; l++){\n        int i = 0, j = l;\n        while(j != str.size()){\n            if(str[i] == str[j]){\n                table[i][j] = 2 + table[i+1][j-1];\n            }\n            else{\n                table[i][j] = max(table[i+1][j],table[i][j-1]);\n            }\n            i++;j++;\n        }\n    }\n    return table[0][str.size()-1];\n}\nint main(){\n    string str;\n    cin >> str;\n    cout << longest_palindromic_subsequence(str);\n    return  0;\n}"
  },
  {
    "path": "C++/Dynamic Programming/Matrix Chain Multiplication.cpp",
    "content": "int mcm(int p[], int n){\n    int m[n][n];\n    int i, j, k, L, q;\n    for (i = 1; i < n; i++)\n        m[i][i] = 0;\n    for (L=2; L<n; L++)   {\n        for (i=1; i<=n-L+1; i++){\n            j = i+L-1;\n            m[i][j] = INT_MAX;\n            for (k=i; k<=j-1; k++){\n                q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];\n                if (q < m[i][j])\n                    m[i][j] = q;\n            }\n        }\n    }\n    return m[1][n-1];\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/All Pair Shortest Path Problem.cpp",
    "content": "#include<iostream>\n#include<vector>\nusing namespace std;\n\nvoid floydWarshall(vector<vector<int>> &graph){\n    for (int k=0; k<graph.size(); ++k){\n        for (int i=0; i<graph.size(); ++i){\n            for (int j=0; j<graph.size(); ++j){\n                graph[i][j] = min (graph[i][j], graph[i][k] + graph[k][j]);\n            }\n        }\n    }\n}\n\nint main(){\n    vector<vector<int>> graph;\n    int v,e,src,des,weight;\n    cin >> v >> e;\n    graph.resize(v,vector<int>(v,0));\n    while(e--){\n        cin >> src >> des >> weight;\n        graph[src][des] = weight;\n    }\n    floydWarshall(graph);\n    for(int i=0;i<v;i++){\n        for(int j=0;j<v;j++){\n            cout << graph[i][j] << \" \";\n        }\n        cout << endl;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/Breadth First Search.cpp",
    "content": "#include<iostream>\n#include<vector>\n#include<list>\n#include<queue>\nusing namespace std;\nvoid breadth_first_search(vector<list<int>> graph,int src){\n    vector<bool>visited(graph.size(),false);\n    queue<int>Q;\n    Q.push(src);\n    visited[src] = true;\n    while(!Q.empty()){\n        int vertex = Q.front(); Q.pop();\n        cout << vertex << \" \";\n        for(list<int>::iterator itr = graph[vertex].begin();itr!=graph[vertex].end();itr++){\n            if(!visited[*itr])\n                Q.push(*itr);\n            visited[*itr] = true;\n        }\n    }\n}\nint main(){\n    vector<list<int>> graph;\n    int v,e,src,des;\n    cin >> v >> e;\n    graph.resize(v);\n    while(e--){\n        cin >> src >> des;\n        graph[src].push_back(des);\n        graph[des].push_back(src);\n    }\n    cin >> src;\n    breadth_first_search(graph,src);\n    return 0;\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/Connected Components Algorithm DFS.cpp",
    "content": "#include<iostream>\n#include<vector>\n#include<list>\nusing namespace std;\n\nvoid connectedComponentsDFS(vector<list<int>> graph,int src,vector<bool> &visited){\n    if(!visited[src]){\n        visited[src] = true;\n        for(list<int>::iterator itr = graph[src].begin();itr != graph[src].end();itr++){\n            connectedComponentsDFS(graph,*itr,visited);\n        }\n    }\n}\n\nint connectedComponents(vector<list<int>> graph){\n    int components = 0;\n    vector<bool> visited(graph.size(),false);\n    for(int src = 0; src < graph.size();src++){\n        if(!visited[src]){\n            components++;\n            connectedComponentsDFS(graph,src,visited);\n        }\n    }\n    return components;\n}\n\nint main(){\n    vector<list<int>> graph;\n    int v,e,src,des;\n    cin >> v >> e;\n    graph.resize(v);\n    while(e--){\n        cin >> src >> des;\n        graph[src].push_back(des);\n    }\n    cout << connectedComponents(graph);\n    return 0;\n}\n\n"
  },
  {
    "path": "C++/Graph Algorithms/Depth First Search.cpp",
    "content": "#include<iostream>\n#include<vector>\n#include<list>\n#include<stack>\nusing namespace std;\nvoid depth_first_search(vector<list<int>> graph,int src){\n    vector<bool>visited(graph.size(),false);\n    stack<int>S;\n    S.push(src);\n    visited[src] = true;\n    while(!S.empty()){\n        int vertex = S.top(); S.pop();\n        cout << vertex << \" \";\n        for(list<int>::iterator itr = graph[vertex].begin();itr!=graph[vertex].end();itr++){\n            if(!visited[*itr])\n                S.push(*itr);\n            visited[*itr] = true;\n        }\n    }\n}\nint main(){\n    vector<list<int>> graph;\n    int v,e,src,des;\n    cin >> v >> e;\n    graph.resize(v);\n    while(e--){\n        cin >> src >> des;\n        graph[src].push_back(des);\n        graph[des].push_back(src);\n    }\n    cin >> src;\n    depth_first_search(graph,src);\n    return 0;\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/Kruskal's Minimum Spanning Tree Algorithm.cpp",
    "content": "#include<iostream>\n#include<algorithm>\n#include<vector>\nusing namespace std;\n\nstruct edge{int src,des,weight;};\n\nclass UnionFind {\n    int *parent, *ranks, _size;\npublic:\n    UnionFind(){\n    }\n    UnionFind(int size){\n        parent = new int[size]; ranks = new int[size];\n        for(int element = 0 ; element < size ; element++){\n            parent[element] = element , ranks[element] = 0 ;\n        }\n        _size = size;\n    }\n    void resize(int size){\n        parent = new int[size]; ranks = new int[size];\n        for(int element = 0 ; element < size ; element++){\n            parent[element] = element , ranks[element] = 0 ;\n        }\n        _size = size;\n    }\n    int find(int element){\n        if(parent[element] == element){\n            return element;\n        }\n        else{\n            return parent[element] = find(parent[element]);          // Path Compression algorithm\n        }\n    }\n    bool connected(int x,int y){\n        if(find(x) == find(y)){\n            return true;\n        }\n        else{\n            return false;\n        }\n    }\n    void merge(int x,int y){\n        x = find(x);\n        y = find(y);\n        if(x != y){                                                   // Union by Rank algorithm\n            if(ranks[x] > ranks[y]){\n                parent[y] = x;\n            }\n            else if(ranks[x] < ranks[y]){\n                parent[x] = y;\n            }\n            else{\n                parent[x] = y; ranks[y] ++ ;\n            }\n            _size--;\n        }\n    }\n    void clear(){\n        delete [] parent; delete [] ranks;\n    }\n    int size(){\n        return _size;\n    }\n};\nbool comparator(const edge &a,const edge &b){\n    return a.weight < b.weight;\n}\n\nvector<edge> kruskalsAlgorithm(vector<edge>graph,int vertices){\n    UnionFind uf(vertices);\n    vector<edge>spanningTree;\n    sort(graph.begin(),graph.end(),comparator);\n    spanningTree.push_back(graph[0]);\n    uf.merge(graph[0].src,graph[0].des);\n    for(int i=1;i<graph.size();i++){\n        if(!uf.connected(graph[i].src,graph[i].des)){\n            uf.merge(graph[i].src,graph[i].des);\n            spanningTree.push_back(graph[i]);\n        }\n    }\n    return spanningTree;\n}\nint main(){\n    vector<edge>graph;\n    int e,v;\n    cin >> e >> v;\n    graph.resize(e);\n    for(int i=0;i<e;i++){\n        cin >> graph[i].src >> graph[i].des >> graph[i].weight;\n    }\n    vector<edge> spanningTree = kruskalsAlgorithm(graph,v);\n    for(edge x : spanningTree){\n        cout << x.src << \" \" << x.des << \" \" << x.weight << endl;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/Prims Minimum Spanning Tree Algorithm.cpp",
    "content": "#include<iostream>\n#include<climits>\n#include<vector>\n#include<queue>\n#include<list>\nusing namespace std;\n\nconst int INF = INT_MAX;\n\nclass edge{ public: int src,des,weight; edge(){}edge(int s,int d,int w): src(s),des(d),weight(w){}};\nclass compare { public: bool operator()(const edge &a,const edge &b){ return a.weight < b.weight; }};\n\nvector<edge> primsAlgorithm(vector<list<pair<int,int>>> graph,edge minEdge){\n    vector<edge>spanningTree;\n    priority_queue<edge,vector<edge>,compare> Q;\n    while(spanningTree.size() == graph.size()-1){\n        spanningTree.push_back(minEdge);\n        for(list<pair<int,int>>::iterator it = graph[minEdge.src].begin();it!=graph[minEdge.src].end();it++){\n            Q.push(edge(minEdge.src,it->first,it->second));\n        }\n        for(list<pair<int,int>>::iterator it = graph[minEdge.des].begin();it!=graph[minEdge.des].end();it++){\n            Q.push(edge(minEdge.des,it->first,it->second));\n        }\n        minEdge = Q.top(); Q.pop();\n    }\n    return spanningTree;\n}\n\nint main(){\n    vector<list<pair<int,int>>>graph;\n    int v,e,src,des,weight;\n    cin >> v >> e;\n    graph.resize(v);\n    edge minEdge;\n    minEdge.weight = INF;\n    while(e--){\n        cin >> src >> des >> weight;\n        graph[src].push_back(make_pair(des,weight));\n        graph[des].push_back(make_pair(src,weight));\n        if(weight < minEdge.weight){\n            minEdge.src = src, minEdge.des = des, minEdge.weight = weight;\n        }\n    }\n    vector<edge> spanningTree = primsAlgorithm(graph,minEdge);\n    for(edge x : spanningTree){\n        cout << x.src << \" \" << x.des << \" \" << x.weight << endl;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/Recursive Depth First Search.cpp",
    "content": "#include<iostream>\n#include<vector>\n#include<list>\nusing namespace std;\nvoid depth_first_search(vector<list<int>> graph,int src,vector<bool> &visited){\n    if(!visited[src]){\n        cout << src << \" \";\n        visited[src] = true;\n        for(list<int>::iterator itr = graph[src].begin();itr != graph[src].end();itr++){\n            depth_first_search(graph,*itr,visited);\n        }\n    }\n}\nint main(){\n    vector<list<int>> graph;\n    vector<bool> visited;\n    int v,e,src,des;\n    cin >> v >> e;\n    graph.resize(v);\n    visited.resize(v,false);\n    while(e--){\n        cin >> src >> des;\n        graph[src].push_back(des);\n    }\n    cin >> src;\n    depth_first_search(graph,src,visited);\n    return 0;\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/Single Shortest Path Bellman Ford Algorithm.cpp",
    "content": "#include<iostream>\n#include<vector>\n#include<climits>\nusing namespace std;\n\nstruct edge {int src, des, weight;};\n\npair<bool,vector<int>> bellmanFord(vector<edge> graph,int vertex,int source){\n    vector<int> distances(vertex,INT_MAX);\n    distances[source] = 0;\n    for(int i=0;i<vertex-1;i++){\n        for(int j=0;j<graph.size();j++){\n            if(distances[graph[j].des] > distances[graph[j].src] + graph[j].weight){\n                distances[graph[j].des] = distances[graph[j].src] + graph[j].weight;\n            }\n        }\n    }\n    for(int j=0;j<graph.size();j++){\n        if(distances[graph[j].des] > distances[graph[j].src] + graph[j].weight){\n            return make_pair(false,vector<int>());\n        }\n    }\n    return make_pair(true,distances);\n}\n\nint main(){\n    int edges,source,vertex;\n    vector<edge> graph;\n    cin >> edges >> vertex;\n    for(int i = 0; i < edges; i++){\n        cin >> graph[i].src >> graph[i].des >> graph[i].weight;\n    }\n    cin >> source;\n    pair<bool,vector<int>> result = bellmanFord(graph,vertex,source);\n    if(result.first == true){\n        cout << \"No Cycle Exist ! \" << endl;\n        for(vector<int>::iterator itr = (result.second).begin();itr!=(result.second).end();itr++){\n            cout << *itr << \" \";\n        }\n    }\n    else{\n        cout << \"Graph Has Negative Weight Cycle\" << endl;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/Single Source Shortest Path Dijkstra Algorithm.cpp",
    "content": "#include<iostream>\n#include<queue>\n#include<vector>\n#include<list>\n#include<climits>\nusing namespace std;\nstruct compare{\n    bool operator()(const pair<int,int> &a,const pair<int,int> &b){\n        return a.second > b.second;\n    }\n};\nvector<int> dijkshtra(vector<list<pair<int,int>>> graph,int src){\n    priority_queue<pair<int,int>,vector<pair<int,int>>,compare> Q;\n    vector<int> distances(graph.size(),INT_MAX);\n    vector<bool> visited(graph.size(),false);\n    distances[src] = 0;\n    Q.push(make_pair(src,0));\n    while(!Q.empty()){\n        pair<int,int> current = Q.top(); Q.pop();\n        cout << \"Currently at\" << current.first << endl;\n        if(!visited[current.first]){\n            visited[current.first] = true;\n            for(list<pair<int,int>> :: iterator vertex = graph[current.first].begin();vertex != graph[current.first].end();vertex++){\n                if(current.second + vertex->second < distances[vertex->first]){\n                    distances[vertex->first] = current.second + vertex->second;\n                    Q.push(make_pair(vertex->first,distances[vertex->first]));\n                }\n            }\n        }\n    }\n    return distances;\n}\nint main(){\n    vector<list<pair<int,int>>> graph;\n    int v,e,src,des,weight;\n    cin >> v >> e;\n    graph.resize(v);\n    while(e--){\n        cin >> src >> des >> weight;\n        graph[src].push_back(make_pair(des,weight));\n    }\n    cin >> src;\n    vector<int> distances = dijkshtra(graph,src);\n    for(vector<int> :: iterator itr = distances.begin();itr != distances.end();itr++){\n        cout << *itr << \" \";\n    }\n    return 0;\n}\n"
  },
  {
    "path": "C++/Graph Algorithms/Topological Sorting.cpp",
    "content": "#include<iostream>\n#include<vector>\n#include<list>\nusing namespace std;\n\nvoid topologicalSortDFS(vector<list<int>> graph,int src,vector<bool> &visited,list<int> &topologicalSortedList){\n    if(!visited[src]){\n        visited[src] = true;\n        for(list<int>::iterator itr = graph[src].begin();itr != graph[src].end();itr++){\n            topologicalSortDFS(graph,*itr,visited,topologicalSortedList);\n        }\n        topologicalSortedList.push_front(src);\n    }\n}\n\nlist<int> topologicalSort(vector<list<int>> graph){\n    list<int> topologicalSortedList;\n    vector<bool> visited(graph.size(),false);\n    for(int src = 0; src < graph.size();src++){\n        topologicalSortDFS(graph,src,visited,topologicalSortedList);\n    }\n    return topologicalSortedList;\n}\n\nint main(){\n    vector<list<int>> graph;\n    int v,e,src,des;\n    cin >> v >> e;\n    graph.resize(v);\n    while(e--){\n        cin >> src >> des;\n        graph[src].push_back(des);\n    }\n    list<int> topologicalSortedList = topologicalSort(graph);\n    for(list<int>::iterator itr = topologicalSortedList.begin();itr!=topologicalSortedList.end();itr++){\n        cout << *itr << \" \";\n    }\n    return 0;\n}\n"
  },
  {
    "path": "C++/Heaps - Priority Queues/K-th Largest element of the stream.cpp",
    "content": "#include <iostream>\n#include <queue>\nusing namespace std;\n\nint main(){\n    int n,k;\n    priority_queue<int,vector<int>,greater<int>>Q;\n    cout << \"Enter the the value of K : \";\n    cin >> k;\n    while(cin >> n){\n        cout << k << \"-th largest element of the stream : \";\n        if(Q.size() < k){\n            Q.push(n);\n            if(Q.size() == k){\n                cout  << Q.top() 3<< endl;\n            }\n            else{\n                cout << \"NULL\" << endl;\n            }\n        }\n        else{\n            if(Q.top() < n){\n                Q.pop();\n                Q.push(n);\n            }\n            cout << Q.top() << endl;\n        }\n        cout << \"Enter next element of the stream : \";\n    }\n    return  0;\n}\n"
  },
  {
    "path": "C++/Linked List/Reverse a linked list recursively.cpp",
    "content": "void reverse_list(list_node *head){\n    list_node *\n}\n"
  },
  {
    "path": "C++/Number Theory Algorithms/Divisors.cpp",
    "content": "#include<iostream>\n#include<set>\nusing namespace std;\nset<int> generateDivisors(long long int num){\n    set<int> divisors;\n    for(int i = 1 ; i*i <= num; i++ ){\n        if(num % i == 0){\n            divisors.insert(i);\n            if( i != num/i ){\n                    divisors.insert(num/i);\n            }\n        }\n    }\n    return divisors;\n}\nint main(){\n    set<int> d = generateDivisors(23);\n    for(int x : d){\n        cout << x << \" \";\n    }\n    return 0;\n}\n"
  },
  {
    "path": "C++/Number Theory Algorithms/Sieve of Eratosthenes.cpp",
    "content": "#include<iostream>\n#include<vector>\n#include<algorithm>\nusing namespace std;\n\nconst int MAX = 1000*1000;\nconst int LMT = 1000;\n\nvector<bool> prime(MAX+1,true);\n\nint seiveEratosthenes(){\n    prime[0] = prime[1] = false;\n    for(int i = 2; i <= LMT; i++){\n        if(prime[i]){\n            for(int j = i + i; j <= MAX ; j += i){\n                prime[j] = false;\n            }\n        }\n    }\n    return count_if(prime.begin(),prime.end(),[](bool p){ return p == true;});\n}\nint main(){\n    cout << seiveEratosthenes();\n    return 0;\n}\n"
  },
  {
    "path": "C++/Recursion/Partition of array on the pivot.cpp",
    "content": "#include<iostream>\nusing namespace std;\nvoid partition(int array[],int low,int high){\n    int i = low-1, pivot = array[high-1];\n    for(int j = low ; j < high ; j++){\n        if(array[j] <= pivot){\n            i++;\n            swap(array[i],array[j]);\n        }\n    }\n    swap(array[i+1],array[high-1]);\n}\nint main(){\n    int n;\n    cin >> n;\n    int array[n];\n    partition(array,0,n);\n    return 0;\n}\n"
  },
  {
    "path": "C++/Recursion/Permutation of a string.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nvoid permutation(char str[],int k,int n){\n    if(k == n){\n        for(int j = 0; j < n; j++){\n            cout << str[j];\n        }\n        cout << endl;\n    }\n    else{\n        for(int i = k ; i < n; i++){\n            swap(str[i],str[k]);\n            permutation(str,k+1,n);\n            swap(str[i],str[k]);\n        }\n    }\n}\nint main(){\n    char str[] = {'A','B','C','D'};\n    permutation(str,0,4);\n    return  0;\n}\n"
  },
  {
    "path": "C++/Segment Tree/Segment Tree.cpp",
    "content": "void buildTree (int tree[],int array[], int index, int low, int high) {\n\tif (low == high)\n\t\ttree[index] = array[low];\n\telse {\n\t\tint mid = (low + high) >>  1;\n\t\tbuildTree (tree,array, index*2, low, mid);\n\t\tbuildTree (tree,array, index*2+1, mid+1, high);\n\t\ttree[index] = tree[index*2] + tree[index*2+1];\n\t}\n}\nint rangeQuery (int tree[],int index, int low, int high, int l, int r) {\n\tif (l > r)\n\t\treturn 0;\n\tif (l == low && r == high)\n\t\treturn tree[index];\n\tint mid = (low + high) >>  1;\n\treturn rangeQuery (tree,index*2, low, mid, l, min(r,mid))\n\t\t+ rangeQuery (tree,index*2+1, mid+1, high, max(l,mid+1), r);\n}\nvoid updateQuery (int tree[],int index, int low, int high, int pos, int delta) {\n\tif (low == high)\n\t\ttree[index] = delta;\n\telse {\n\t\tint mid = (low + high) >> 1;\n\t\tif (pos <= mid)\n\t\t\tupdateQuery (tree,index*2, low, mid, pos, delta);\n\t\telse\n\t\t\tupdateQuery (tree,index*2+1, mid+1, high, pos, delta);\n\t\ttree[index] = tree[index*2] + tree[index*2+1];\n\t}\n}\n"
  },
  {
    "path": "C++/Stacks - Queue/CircularQueue.cpp",
    "content": "#include <iostream>\nusing namespace std;\nclass circular_queue\n{\n\tprivate :\n\t\tint *array ;\n\t\tint front, back ;\n\t\tint MAX;\n\tpublic :\n\t\tcircular_queue( int maxsize = 10 ) ;\n\t\tvoid enqueue ( int item ) ;\n\t\tint dequeue( ) ;\n\t\tvoid display( ) ;\n} ;\ncircular_queue :: circular_queue( int maxsize )\n{\n\tMAX = maxsize ;\n\tarray = new int [ MAX ];\n\tfront = back = -1 ;\n\tfor ( int i = 0 ; i < MAX ; i++ )\n\t\tarray[i] = 0 ;\n}\nvoid circular_queue :: enqueue(int item){\n\tif((back+1)%MAX == front){\n\t\tcout << \"Queue is full\" << endl;\n\t\treturn ;\n\t}\n\tback = ( back + 1 ) % MAX;\n\tarray[back] = item ;\n\tif ( front == -1 )\n\t\tfront = 0 ;\n}\nint circular_queue :: dequeue(){\n\tint data ;\n\tif ( front == -1 )\n\t{\n\t\tcout << \"\\nQueue is empty\" ;\n\t\treturn NULL ;\n\t}\n\n\tdata = array[front] ;\n\tarray[front] = 0 ;\n\tif ( front == back )\n\t{\n\t\tfront = -1 ;\n\t\tback = -1 ;\n\t}\n\telse\n\t\tfront = ( front + 1 ) % MAX;\n\treturn data ;\n}\nvoid circular_queue :: display()\n{\n\tcout << endl ;\n\tfor ( int i = 0 ; i < MAX ; i++ )\n\t\tcout << array[i] << \"  \" ;\n\tcout << endl ;\n}\nint main(){\n\tcircular_queue cq(10) ;\n\tcq.enqueue(14);\n\tcq.enqueue(22);\n\tcq.enqueue(13);\n\tcq.enqueue(-6);\n\tcq.enqueue(25);\n\tcout << \"\\nElements in the circular queue: \" ;\n\tcq.display();\n\tint i = cq.dequeue() ;\n\tcout << \"Item deleted: \" << i ;\n\ti = cq.dequeue();\n\tcout << \"\\nItem deleted: \" << i ;\n\tcout << \"\\nElements in the circular queue after deletion: \" ;\n\tcq.display();\n\tcq.enqueue(21);\n\tcq.enqueue(17);\n\tcq.enqueue(18);\n\tcq.enqueue(9);\n\tcq.enqueue(20);\n\tcout << \"Elements in the circular queue after addition: \" ;\n\tcq.display();\n\tcq.enqueue(32);\n\tcout << \"Elements in the circular queue after addition: \" ;\n\tcq.display();\n\treturn 0;\n}\n\n"
  },
  {
    "path": "C++/String Algorithms/KMP.cpp",
    "content": "vector<int> computePrefix(string pat){\n    int m = pat.size();\n    vector<int> longestPrefix(m);\n    for(int i = 1, k = 0; i < m; i++){\n        while(k > 0 && pat[k] != pat[i]){\n            k = longestPrefix[k - 1];\n        }\n        if(pat[i] == pat[k]){\n            longestPrefix[i] = ++k;\n        }\n        else{\n            longestPrefix[i] = k;\n        }\n    }\n    return longestPrefix;\n}\nvoid KMP(string str,string pat){\n    int n = str.size();\n    int m = pat.size();\n    vector<int> longestPrefix = computePrefix(pat);\n    for(int i = 0, k = 0; i < n; i++){\n        while(k > 0 && pat[k] != str[i]){\n            k = longestPrefix[k - 1];\n        }\n        if(str[i] == pat[k]){\n            k++;\n        }\n        if(k == m){\n            cout << i - m + 1 << \"\\n\";\n            k = longestPrefix[k - 1];\n        }\n    }\n}\n"
  },
  {
    "path": "C++/String Algorithms/Trie.cpp",
    "content": "struct Trie {\n\tTrie* child[26];\n\tbool isLeaf;\n\n\tTrie() {\n\t\tmemset(child, 0, sizeof(child));\n\t\tisLeaf = 0;\n\t}\n\n\tvoid pushWord(char *str) {\n\t\tif(*str == '\\0')\n\t\t\tisLeaf = 1;\n\t\telse {\n\t\t\tint cur = *str - 'a';\n\t\t\tif(child[cur] == 0 )\n\t\t\t\tchild[cur] = new Trie();\n\t\t\tchild[cur]->pushWord(str+1);\n\t\t}\n\t}\n\n\tbool wordExist(char* str) {\n\t\tif(*str == '\\0')\n\t\t\treturn isLeaf;\n\n\t\tint cur = *str - 'a';\n\t\tif(child[cur] == 0 )\n\t\t\treturn false;\n\n\t\treturn child[cur]->wordExist(str+1);\n\t}\n\n\tbool prefixExist(char* str) {\n\t\tif(*str == '\\0')\n\t\t\treturn true;\n\n\t\tint cur = *str - 'a';\n\t\tif(child[cur] == 0 )\n\t\t\treturn false;\n\n\t\treturn child[cur]->prefixExist(str+1);\n\t}\n};\n"
  },
  {
    "path": "C++/Union Find/Union Find.cpp",
    "content": "#include<iostream>\nusing namespace std;\n\nclass UnionFind {\n    int *parent, *ranks, _size;\npublic:\n    UnionFind(){\n    }\n    UnionFind(int size){\n        parent = new int[size]; ranks = new int[size];\n        for(int element = 0 ; element < size ; element++){\n            parent[element] = element , ranks[element] = 0 ;\n        }\n        _size = size;\n    }\n    void resize(int size){\n        parent = new int[size]; ranks = new int[size];\n        for(int element = 0 ; element < size ; element++){\n            parent[element] = element , ranks[element] = 0 ;\n        }\n        _size = size;\n    }\n    int find(int element){\n        if(parent[element] == element){\n            return element;\n        }\n        else{\n            return parent[element] = find(parent[element]);          // Path Compression algorithm\n        }\n    }\n    bool connected(int x,int y){\n        if(find(x) == find(y)){\n            return true;\n        }\n        else{\n            return false;\n        }\n    }\n    void merge(int x,int y){\n        x = find(x);\n        y = find(y);\n        if(x != y){                                                   // Union by Rank algorithm\n            if(ranks[x] > ranks[y]){\n                parent[y] = x;\n            }\n            else if(ranks[x] < ranks[y]){\n                parent[x] = y;\n            }\n            else{\n                parent[x] = y; ranks[y] ++ ;\n            }\n            _size--;\n        }\n    }\n    void clear(){\n        delete [] parent; delete [] ranks;\n    }\n    int size(){\n        return _size;\n    }\n};\n\n\nint main(){\n    UnionFind uf(5);\n    cout << uf.size() << endl;        // 5 disjoint sets are there\n    uf.merge(0,1);\n    cout << uf.size() << endl;        // 4 disjoint sets are there\n    uf.merge(0,2);\n    cout << uf.size() << endl;        // 3 disjoint sets are there\n    uf.merge(1,2);\n    cout << uf.size() << endl;        // 3 disjoint sets are there\n    uf.clear();\n    return 0;\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "README.md",
    "content": "\n<h2>Please visit my wiki link for full list of questions</h2>\n<h3>https://github.com/mission-peace/interview/wiki</h3>\n\n<h2> Like my facebook page for latest updates on my youtube channel</h2>\n<h3>https://www.facebook.com/tusharroy25</h3>\n\n<h2> Contribution </h2>\nPlease contribute to this repository to help it make better. Any change like new question, code improvement, doc improvement etc. is very welcome. Just send me a pull request and I will review the request and approve it if it looks good. \n\n<h2> How to use this repository </h2>\n\n<h3> Softwares to install </h3>\n* Install JDK8 https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html\n* Install Git https://git-scm.com/book/en/v2/Getting-Started-Installing-Git\n* Install either Intellij https://www.jetbrains.com/idea/download/\n* If you like eclipse instead of intellij install eclipse https://eclipse.org/downloads/\n\n<h3> Set up your desktop </h3>\n* Pull the git repository. Go to command line and type git clone https://github.com/mission-peace/interview.git\n* Go to root directory of checked out project.\n* Run ./gradlew idea to generate idea related classes\n* Fire up intellij. Go to Open. Go to git repo folder and open interview.ipr . On file menu go to project structure. Update language level support to 8\n* If you use eclipse, do ./gradlew eclipse . This will generate eclipse related files. Go to eclipse and open up folder containing this repo.\n* Go to any program and run that program\n* Go to any test and run the junit test.\n* Run ./gradlew build to create classes, run tests and create jar.\n"
  },
  {
    "path": "build.gradle",
    "content": "apply plugin: 'java'\napply plugin: 'idea'\napply plugin: 'eclipse'\napply plugin: \"jacoco\"\n\nsourceCompatibility = '1.8'\ntargetCompatibility = '1.8'\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    testCompile 'junit:junit:4.12'\n}\n\nsourceSets {\n    main {\n        java {\n            srcDir 'src'\n        }\n   }\n\n    test {\n        java {\n            srcDir 'test'\n        }\n    }\n}\n\njacocoTestReport {\n    reports {\n        xml.enabled false\n        csv.enabled false\n        html.destination \"${buildDir}/jacocoHtml\"\n    }\n}"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Sat Apr 02 16:59:09 PDT 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-2.11-bin.zip\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "python/array/arrayaddition.py",
    "content": "def add(arr1, arr2):\n\n    l = max(len(arr1), len(arr2))\n    result = [0 for j in range(l)]\n    c = 0\n    i = len(arr1) - 1\n    j = len(arr2) - 1\n    r = 0\n    l -= 1\n    \n    while i >= 0 and j >= 0:\n        r = arr1[i] + arr2[j] + c\n        i -= 1\n        j -= 1\n        c = r // 10\n        result[l] = r % 10\n        l -= 1\n\n    while i >= 0:\n        r = arr1[i] + c\n        i -= 1\n        c = r // 10\n        result[l] = r % 10\n        l -= 1\n\n    while j >= 0:\n        r = arr1[j] + c\n        j -= 1\n        c = r // 10\n        result[l] = r % 10\n        l -= 1\n\n    if c != 0:\n        new_result = [0 for j in range(len(result) + 1)]\n        t = len(new_result) - 1\n        while t > 0:\n            new_result[t] = result[t - 1]\n            t -= 1\n        new_result[0] = c\n        return new_result\n    return result\n\narr1 = [9, 9, 9, 9, 9, 9, 9]\narr2 = [1, 6, 8, 2, 6, 7]\nresult = add(arr1, arr2)\nprint(result)\n"
  },
  {
    "path": "python/array/commonthreesortedarray.py",
    "content": "# http://www.geeksforgeeks.org/find-common-elements-three-sorted-arrays/\n\ndef common_elements(input1, input2, input3):\n    result = []\n    i = 0\n    j = 0\n    k = 0\n    while i < len(input1) and j < len(input2) and k < len(input3):\n        if input1[i] == input2[j] and input2[j] == input3[k]:\n            result.append(input1[i])\n            i = i + 1\n            j = j + 1\n            k = k + 1\n        elif input1[i] < input2[j]:\n            i = i + 1\n        elif input2[j] < input3[k]:\n            j = j + 1\n        else:\n            k = k + 1\n    return result\n\nif __name__ == '__main__':\n    input1 = [1, 5, 10, 20, 40, 80]\n    input2 = [6, 7, 20, 80, 100]\n    input3 = [3, 4, 15, 20, 30, 70, 80, 120]\n\n    print(common_elements(input1, input2, input3))\n"
  },
  {
    "path": "python/array/countinversionofsize3.py",
    "content": "# http://www.geeksforgeeks.org/count-inversions-of-size-three-in-a-give-array/\n\ndef find_inversions(input):\n    inversion = 0\n    for i in range(1, len(input) - 1):\n        larger = 0\n        for k in range(0, i):\n            if input[k] > input[i]:\n                larger = larger + 1\n        smaller = 0\n        for k in range(i+1, len(input)):\n            if input[k] < input[i]:\n                smaller = smaller + 1\n\n        inversion += larger*smaller\n    return inversion\n\nif __name__ == '__main__':\n    input = [9, 6, 4, 5, 8]\n    print(find_inversions(input))\n    \n"
  },
  {
    "path": "python/array/flip0smaximum1s.py",
    "content": "# http://www.geeksforgeeks.org/find-zeroes-to-be-flipped-so-that-number-of-consecutive-1s-is-maximized/\n\ndef flip_0s_to_maximize_consecutive_1s(input, flips_allowed):\n    window_start = 0\n    count_zero = 0\n    result = 0\n    for i in range(len(input)):\n        if input[i] == 1:\n            result = max(result, i - window_start + 1)\n        else:\n            if count_zero < flips_allowed:\n                count_zero = count_zero + 1\n                result = max(result, i - window_start + 1)\n            else:\n                while True:\n                    if input[window_start] == 0:\n                        window_start = window_start + 1\n                        break\n                    window_start = window_start + 1\n    return result\n    \nif __name__ == '__main__':\n    input = [0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1]\n    print(flip_0s_to_maximize_consecutive_1s(input, 1))\n"
  },
  {
    "path": "python/array/longestsamesumspan.py",
    "content": "# http://www.geeksforgeeks.org/longest-span-sum-two-binary-arrays/\n# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/array/LongestSameSumSpan.java\n\ndef longest_span(input1, input2):\n    if len(input1) != len(input2):\n        raise ValueError;\n\n    diff = {}\n    prefix1 = 0\n    prefix2 = 0\n    max_span = 0\n    diff[0] = -1\n    for i in range(len(input1)):\n        prefix1 += input1[i]\n        prefix2 += input2[i]\n        curr_diff = prefix1 - prefix2\n        if curr_diff in diff:\n            max_span = max(max_span, i - diff[curr_diff])\n        else:\n            diff[curr_diff] = i\n    return max_span\n\nif __name__ == '__main__':\n    input1 = [1, 0, 0, 1, 1, 0]\n    input2 = [0, 1, 1, 0, 1, 1]\n\n    print(longest_span(input1, input2))\n    \n    \n"
  },
  {
    "path": "python/array/maximumsumpathtwoarrays.py",
    "content": "# http://www.geeksforgeeks.org/maximum-sum-path-across-two-arrays/\n\ndef max_sum(input1, input2):\n    max_sum = 0\n    i = 0\n    j = 0\n    sum1 = 0\n    sum2 = 0\n    while i < len(input1) and j < len(input2):\n        if input1[i] == input2[j]:\n            if sum1 > sum2:\n                max_sum += sum1 + input1[i]\n            else:\n                max_sum += sum2 + input2[j]\n            i = i + 1\n            j = j + 1\n            sum1 = 0\n            sum2 = 0\n        elif input1[i] < input2[j]:\n            sum1 += input1[i]\n            i = i + 1\n        else:\n            sum2 += input2[j]\n            j = j + 1\n\n    while i < len(input1):\n        sum1 += input1[i]\n        i = i + 1\n\n    while j < len(input2):\n        sum2 += input2[j]\n        j = j + 1\n\n    if sum1 > sum2:\n        max_sum += sum1\n    else:\n        max_sum += sum2\n\n    return max_sum\n\nif __name__ == '__main__':\n    input1 = [2, 3, 7, 10, 12, 15, 30, 34]\n    input2 = [1, 5, 7, 8, 10, 15, 16, 19]\n\n    print(max_sum(input1, input2))\n        \n"
  },
  {
    "path": "python/array/maxproductsubarray.py",
    "content": "#  http://www.geeksforgeeks.org/maximum-product-subarray/\n\ndef max_product(input):\n    max_ending = 1\n    min_ending = 1\n    max_so_far = 1\n    for i in input:\n        if i > 0:\n            max_ending = max_ending * i\n            min_ending = min(min_ending*i, 1)\n        elif i == 0:\n            max_ending = 1\n            min_ending = 1\n        else:\n            t = max_ending\n            max_ending = max(min_ending*i, 1)\n            min_ending = t * i\n        if max_so_far < max_ending:\n            max_so_far = max_ending\n    return max_so_far\n\nif __name__ == '__main__':\n    input = [-6,-3,8,-9,-1,-1,3,6,9,0,3,-1]\n    print(max_product(input))\n"
  },
  {
    "path": "python/array/numberoftrianglesunsortedarray.py",
    "content": "# http://www.geeksforgeeks.org/find-number-of-triangles-possible/\n\ndef number_of_triangles(input):\n    input.sort()\n    count = 0\n    for i in range(len(input)-2):\n        k = i + 2\n        for j in range(i+1, len(input)):\n            while k < len(input) and input[i] + input[j] > input[k]:\n                k = k + 1\n            count += k - j - 1\n    return count\n\nif __name__ == '__main__':\n    input = [15, 9, 8, 3, 4, 5, 6]\n    print(number_of_triangles(input))\n    \n    \n            \n \n"
  },
  {
    "path": "python/array/positiveandnegativealternativelymaintainingorder.py",
    "content": "# http://www.geeksforgeeks.org/rearrange-array-alternating-positive-negative-items-o1-extra-space/\n\ndef rearrange(input):\n    for i in range (len(input)):\n        if i%2 == 0 and input[i] >= 0:\n            index_of_next_negative = find_next(input, i+1, False)\n            if index_of_next_negative == -1:\n                return\n            else:\n                right_rotate(input, i, index_of_next_negative)\n        elif i % 2 != 0 and input[i] < 0:\n            index_of_next_positive = find_next(input, i+1, True)\n            if index_of_next_positive == -1:\n                return\n            else:\n                right_rotate(input, i, index_of_next_positive)\n\ndef find_next(input, start, isPositive):\n    for i in range(start, len(input)):\n        if (isPositive and input[i] >= 0) or (not isPositive and input[i] < 0):\n            return i;\n    return -1\n\ndef right_rotate(input, start, end):\n    t = input[end]\n    for i in range(end, start -1, -1):\n        input[i] = input[i-1]\n    input[start] = t\n\nif __name__ == '__main__':\n    input = [-5, -2, 5, 2, 4, 7, 1, 8, 0, -8];\n    rearrange(input)\n    print(input)\n    \n"
  },
  {
    "path": "python/array/rearrangearrayperindex.py",
    "content": "# http://www.geeksforgeeks.org/rearrange-array-arrj-becomes-arri-j/\n\ndef rearrange(input):\n    for i in range(len(input)):\n        input[i] += 1\n\n    for i in range(len(input)):\n        if input[i] > 0:\n            rearrange_util(input, i)\n\n    for i in range(len(input)):\n        input[i] = -input[i] - 1\n\ndef rearrange_util(input, start):\n    i = start + 1\n    v = input[start]\n    while v > 0:\n        t = input[v-1]\n        input[v-1] = -i\n        i = v\n        v = t\n\nif __name__ == '__main__':\n    input = [1, 2, 0, 5, 3, 4];\n    rearrange(input)\n    print(input)\n"
  },
  {
    "path": "python/array/reorderarraybyindex.py",
    "content": "# http://www.geeksforgeeks.org/reorder-a-array-according-to-given-indexes/\n\ndef reorder(input, index):\n    if len(input) != len(index):\n        raise ValueError\n    for i in range(len(index)):\n        while index[i] != i:\n            s_index = index[index[i]]\n            s_val = input[index[i]]\n\n            index[index[i]] = index[i]\n            input[index[i]] = input[i]\n\n            index[i] = s_index\n            input[i] = s_val\n\nif __name__ == '__main__':\n    input = [50, 40, 70, 60, 90]\n    index = [3, 0, 4, 1, 2]\n\n    reorder(input, index)\n    print(input)\n    print(index)\n\n            \n"
  },
  {
    "path": "python/array/rotationwithmaxsum.py",
    "content": "# http://www.geeksforgeeks.org/find-maximum-value-of-sum-iarri-with-only-rotations-on-given-array-allowed/\n\ndef max_sum(input):\n    arr_sum = 0\n    rotation_sum = 0\n    for i in range(len(input)):\n        arr_sum += input[i]\n        rotation_sum += i*input[i]\n\n    max_rotation_sum = rotation_sum\n\n    for i in range(1, len(input)):\n         rotation_sum += len(input)*input[i-1] - arr_sum\n         max_rotation_sum = max(max_rotation_sum, rotation_sum)\n\n    return max_rotation_sum\n\nif __name__ == '__main__':\n    input = [10, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n    print(max_sum(input))\n"
  },
  {
    "path": "python/array/smallestintegernotrepresentedbysubsetsum.py",
    "content": "# http://www.geeksforgeeks.org/find-smallest-value-represented-sum-subset-given-array/\n\ndef find_smallest_integer(input):\n    result = 1\n    for i in range(len(input)):\n        if input[i] <= result:\n            result += input[i]\n        else:\n            break\n    return result\n\nif __name__ == '__main__':\n    input = [1, 2, 3, 8]\n    print(find_smallest_integer(input))\n"
  },
  {
    "path": "python/array/tripletsumlessthantotal.py",
    "content": "# http://www.geeksforgeeks.org/count-triplets-with-sum-smaller-that-a-given-value/\n\ndef find_all_triplet(input, total):\n    input.sort()\n    result = 0\n    for i in range(len(input) - 2):\n        j = i + 1\n        k = len(input) - 1\n        while j < k:\n            if input[i] + input[j] + input[k] >= total:\n                k = k - 1\n            else:\n                result += k - j\n                j = j + 1\n    return result\n\n\nif __name__ == '__main__':\n    input = [5, 1, 3, 4, 7]\n    print(find_all_triplet(input, 12))\n    \n"
  },
  {
    "path": "python/array/zigzagarrangement.py",
    "content": "# http://www.geeksforgeeks.org/convert-array-into-zig-zag-fashion/\n\ndef rearrange(input):\n    is_less = True\n    for i in range(len(input)-1):\n        if is_less:\n            if input[i] > input[i+1]:\n                swap(input, i, i+1)\n        else:\n            if input[i] < input[i+1]:\n                swap(input, i, i+1)\n        is_less = not is_less\n\ndef swap(input, i, j):\n    t = input[i]\n    input[i] = input[j]\n    input[j] = t\n\nif __name__ == '__main__':\n    input = [4, 3, 2, 6, 7, 1, 9]\n    rearrange(input)\n    print(input)\n            \n"
  },
  {
    "path": "python/dynamic/bitonicsequence.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nFind the length of the longest Bitonic Sequence in a given sequence of numbers. A Bitonic sequence is a sequence of\nnumbers which are increasing and then decreasing.\n\nVideo\n-----\n* https://youtu.be/TWHytKnOPaQ\n\nAnalysis\n--------\n* Runtime O(n)\n\nReference\n---------\n* http://www.geeksforgeeks.org/dynamic-programming-set-15-longest-bitonic-subsequence/\n\"\"\"\n\n\ndef longest_bitonic(sequence):\n    length_of_input = len(sequence)\n    increasing_sequence = [1] * length_of_input\n    decreasing_sequence = [1] * length_of_input\n\n    for i in range(1, length_of_input):\n        for j in range(0, i):\n            if sequence[i] > sequence[j]:\n                increasing_sequence[i] = max(increasing_sequence[i], increasing_sequence[j] + 1)\n\n    for i in range(length_of_input - 2, -1, -1):\n        for j in range(length_of_input - 1, i, -1):\n            if sequence[i] > sequence[j]:\n                decreasing_sequence[i] = max(decreasing_sequence[i], decreasing_sequence[j] + 1)\n\n    max_value = 0\n\n    for i in range(len(sequence)):\n        bitonic_sequence_length = increasing_sequence[i] + decreasing_sequence[i] - 1\n        max_value = max(max_value, bitonic_sequence_length)\n\n    return max_value\n\n\nif __name__ == '__main__':\n    max_value = longest_bitonic([1, 4, 3, 7, 2, 1, 8, 11, 13, 0])\n    assert 7 == max_value  # 1, 4, 7, 8, 11, 13, 0\n"
  },
  {
    "path": "python/dynamic/boxstacking.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven different dimensions and unlimited supply of boxes for each dimension, stack boxes on top of each other such that\nit has maximum height but with caveat that length and width of box on top should be strictly less than length and width\nof box under it. You can rotate boxes as you like.\n\n1) Create all rotations of boxes such that length is always greater or equal to width\n2) Sort boxes by base area in non increasing order (length * width). This is because box\n   with more area will never ever go on top of box with less area.\n3) Take T[] and result[] array of same size as total boxes after all rotations are done\n4) Apply longest increasing subsequence type of algorithm to get max height.\n\nAnalysis\n--------\nIf n number of dimensions are given total boxes after rotation will be 3n.\n* Space complexity is O(n)\n* Time complexity - O(nlogn) to sort boxes. O(n^2) to apply DP on it So really O(n^2)\n\nVideo\n-----\n* https://youtu.be/9mod_xRB-O0\n\nReferences\n----------\n* http://www.geeksforgeeks.org/dynamic-programming-set-21-box-stacking-problem/\n* http://people.cs.clemson.edu/~bcdean/dp_practice/\n\"\"\"\n\nfrom collections import namedtuple\nfrom itertools import permutations\n\ndimension = namedtuple(\"Dimension\", \"height length width\")\n\n\ndef create_rotation(given_dimensions):\n    \"\"\"\n    A rotation is an order wherein length is greater than or equal to width. Having this constraint avoids the\n    repetition of same order, but with width and length switched.\n\n    For e.g (height=3, width=2, length=1) is same the same box for stacking as (height=3, width=1, length=2).\n\n    :param given_dimensions: Original box dimensions\n    :return: All the possible rotations of the boxes with the condition that length >= height.\n    \"\"\"\n    for current_dim in given_dimensions:\n        for (height, length, width) in permutations((current_dim.height, current_dim.length, current_dim.width)):\n            if length >= width:\n                yield dimension(height, length, width)\n\n\ndef sort_by_decreasing_area(rotations):\n    return sorted(rotations, key=lambda dim: dim.length * dim.width, reverse=True)\n\n\ndef can_stack(box1, box2):\n    return box1.length < box2.length and box1.width < box2.width\n\n\ndef box_stack_max_height(dimensions):\n    boxes = sort_by_decreasing_area([rotation for rotation in create_rotation(dimensions)])\n    num_boxes = len(boxes)\n    T = [rotation.height for rotation in boxes]\n    R = [idx for idx in range(num_boxes)]\n\n    for i in range(1, num_boxes):\n        for j in range(0, i):\n            if can_stack(boxes[i], boxes[j]):\n                stacked_height = T[j] + boxes[i].height\n                if stacked_height > T[i]:\n                    T[i] = stacked_height\n                    R[i] = j\n\n    max_height = max(T)\n    start_index = T.index(max_height)\n\n    # Prints the dimensions which were stored in R list.\n    while True:\n        print boxes[start_index]\n        next_index = R[start_index]\n        if next_index == start_index:\n            break\n        start_index = next_index\n\n    return max_height\n\n\nif __name__ == '__main__':\n\n    d1 = dimension(3, 2, 5)\n    d2 = dimension(1, 2, 4)\n\n    assert 11 == box_stack_max_height([d1, d2])\n"
  },
  {
    "path": "python/dynamic/breakword.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven a string and a dictionary, split the string in to multiple words so that each word belongs to the dictionary.\n\nVideo\n-----\n\n* https://youtu.be/WepWFGxiwRs\n\nAnalysis\n--------\n\n* word_break_recursive: Exponential\n* word_break_dp : O(n^3)\n\nSolution\n--------\n\nif input[i..j] belongs in a dictionary:\n    DP[i][j] = True\nelse:\n    DP[i][j] = True if DP[i][k-1] and DP[k][j] for any k between i to j.\n\nMultiple different implementations are given below.\n\"\"\"\n\n\ndef word_break_recursive(given_string, dictionary):\n    \"\"\"\"Returns None if the given string cannot be broken into words, otherwise returns space separate words.\"\"\"\n\n    given_string_length = len(given_string)\n    if given_string_length == 0:\n        return \"\"\n    string = \"\"\n    for i in range(given_string_length):\n        string += given_string[i]\n        if string in dictionary:\n            r = word_break_recursive(given_string[i + 1:], dictionary)\n            if r is not None:\n                string += \" \" + r\n                return string\n    return None\n\n\ndef word_break_dp(given_string, dictionary):\n    \"\"\"Returns None if the given string cannot be broken into words, otherwise returns space separated words.\"\"\"\n\n    given_string_length = len(given_string)\n\n    # -1 indicates the word cannot be split.\n    DP = [[-1 for _ in range(given_string_length)] for _ in range(given_string_length)]\n\n    for substring_length in range(1, given_string_length + 1):\n        for start in range(0, given_string_length - substring_length + 1):\n            end = start + substring_length - 1\n            substring = given_string[start: end + 1]\n            if substring in dictionary:\n                DP[start][end] = start\n                continue\n\n            for split in range(start + 1, end + 1):\n                if DP[start][split - 1] != -1 and DP[split][end] != -1:\n                    DP[start][end] = split\n                    break\n\n    if DP[0][-1] == -1:\n        return None\n\n    words = []\n    start_index = 0\n    end_index = given_string_length - 1\n    while start_index < given_string_length:\n        split_index = DP[start_index][end_index]\n        if start_index == split_index:\n            words.append(given_string[start_index: end_index + 1])\n            break\n        else:\n            words.append(given_string[start_index: split_index])\n        start_index = split_index\n\n    return \" \".join(words)\n\n\ndef is_word_break_possible(given_string, dictionary):\n    \"\"\"Returns if any word break is possible amongst the multiple word breaks in the sentence.\"\"\"\n\n    DP = dict()\n    max_word_length = len(max(dictionary, key=len))\n    return is_word_break_possible_recursive_helper(given_string, dictionary, 0, max_word_length, DP)\n\n\ndef is_word_break_possible_recursive_helper(given_string, dictionary, start, max_word_length, DP):\n    if start == len(given_string):\n        return True\n\n    if start in DP:\n        return DP[start]\n\n    for i in range(start, start + max_word_length):\n        if i < len(given_string):\n            new_word = given_string[start: i + 1]\n            if new_word in dictionary:\n                continue\n            if is_word_break_possible_recursive_helper(given_string, dictionary, i + 1, max_word_length, DP):\n                DP[start] = True\n                return True\n\n    DP[start] = False\n    return False\n\n\ndef all_possible_word_break_helper(given_string, dictionary, start, max_word_length, DP):\n    \"\"\"\"Returns all possible word breaks in a given sentence.\"\"\"\n    if start == len(given_string):\n        return [\"\"]\n\n    if start in DP:\n        return DP[start]\n\n    words = []\n    for i in range(start, start + max_word_length):\n        if i < len(given_string):\n            new_word = given_string[start: i + 1]\n            if new_word not in dictionary:\n                continue\n            sub_words = all_possible_word_break_helper(given_string, dictionary, i + 1, max_word_length, DP)\n            for word in sub_words:\n                extra_space = \"\" if len(word) == 0 else \" \"\n                words.append(new_word + extra_space + word)\n\n    DP[start] = words\n    return words\n\n\ndef all_possible_word_breaks(given_string, dictionary):\n    DP = dict()\n    max_word_length = len(max(dictionary, key=len))\n    return all_possible_word_break_helper(given_string, dictionary, 0, max_word_length, DP)\n\n\nif __name__ == '__main__':\n    dictionary = {\"joy\", \"likes\", \"to\", \"play\"}\n    given_string = \"joylikestoplay\"\n\n    assert True == is_word_break_possible(given_string, dictionary)\n    assert \"joy likes to play \" == word_break_recursive(given_string, dictionary)\n    assert \"joy likes to play\" == word_break_dp(given_string, dictionary)\n\n    dictionary = {\"pea\", \"nut\", \"peanut\", \"butter\"}\n    given_string = \"peanutbutter\"\n    assert ['pea nut butter', 'peanut butter'] == all_possible_word_breaks(given_string, dictionary)\n"
  },
  {
    "path": "python/dynamic/coin_change_num_ways.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven a total and coins of certain denominations find number of ways total can be formed from coins assuming infinity\nsupply of coins.\n\nAnalysis\n--------\n* Runtime : O(num_of_coins * total)\n\nVideo\n-----\n* https://youtu.be/_fgjrs570YE\n\nReference\n---------\n* http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/\n\"\"\"\n\n\ndef coin_changing_num_ways(coins, total):\n    cols = total + 1   # 1 for value 0 in total\n    rows = len(coins)\n    T = [[1 if col == 0 else 0 for col in range(cols)] for _ in range(rows)]\n\n    for i in range(rows):\n        for j in range(cols):\n            if (i - 1) < 0:\n                continue\n            if j < coins[i]:\n                T[i][j] = T[i - 1][j]\n            else:\n                T[i][j] = T[i - 1][j] + T[i][j - coins[i]]\n\n    return T[rows - 1][cols - 1]\n\n\ndef coin_changing_num_ways2(coins, total):\n    cols = total + 1\n    num_coins = len(coins)\n\n    # Using 1-D Array instead of 2-D Array. Approach is same as coin_changing_num_ways.\n    T = [1 if col == 0 else 0 for col in range(cols)]\n\n    for i in range(num_coins):\n        for col in range(1, cols):\n            if col >= coins[i]:\n                T[col] += T[col - coins[i]]\n\n    return T[cols - 1]\n\n\ndef print_coin_changes_recursive(coins, total, results_stack, pos):\n    if total == 0:\n        for coin in results_stack:\n            print \"%d \" % coin,\n        print\n\n    for idx in range(pos, len(coins)):\n        if total >= coins[idx]:\n            results_stack.append(coins[idx])\n            print_coin_changes_recursive(coins, total - coins[idx], results_stack, idx)\n            results_stack.pop()        # Remove last inserted coin from stack to use new coin with different index.\n\n\ndef print_coin_changes(coins, total):\n    print_coin_changes_recursive(coins, total, list(), 0)\n\n\nif __name__ == '__main__':\n    coins = [1, 2, 3]\n    total = 5\n    expected = 5\n    assert expected == coin_changing_num_ways(coins, total)\n    assert expected == coin_changing_num_ways2(coins, total)\n    print_coin_changes(coins, total)\n"
  },
  {
    "path": "python/dynamic/coinchangingmincoins.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven coins of certain denominations with infinite supply find minimum number of coins it takes to form given total\n\nVideo\n-----\n\n* Topdown DP - https://youtu.be/Kf_M7RdHr1M\n* Bottom Up DP - https://youtu.be/Y0ZqKpToTic (Approach 1. 2D array.)\n* Bottom up DP - https://youtu.be/NJuKJ8sasGk (Same as Approach 1. Uses 1D array since 2D array is not required.)\n\nAnalysis\n--------\n\n* Time complexity - O(len(coins) * total)\n* Space complexity - O(len(coins) * total)\n\"\"\"\n\n\ndef min_coins(coins, total):\n    cols = total + 1\n    rows = len(coins)\n    T = [[0 if col == 0 else float(\"inf\") for col in range(cols)] for _ in range(rows)]\n\n    for i in range(rows):\n        for j in range(1, cols):\n            if j < coins[i]:\n                T[i][j] = T[i - 1][j]\n            else:\n                T[i][j] = min(T[i - 1][j], 1 + T[i][j - coins[i]])\n\n    return T[rows - 1][cols - 1]\n\n\ndef print_coins(R, coins):\n    start = len(R) - 1\n\n    if R[start] == -1:\n        print \"No Solution Possible.\"\n        return\n\n    print \"Coins:\",\n    while start != 0:\n        coin = coins[R[start]]\n        print \"%d \" % coin,\n        start = start - coin\n\n\ndef min_coins2(coins, total):\n    cols = total + 1\n    T =[0 if idx == 0 else float(\"inf\") for idx in range(cols)]\n    R = [-1 for _ in range(total + 1)]\n\n    for j in range(len(coins)):\n        for i in range(1, cols):\n            coin = coins[j]\n            if i >= coins[j]:\n                if T[i] > 1 + T[i - coin]:\n                    T[i] = 1 + T[i - coin]\n                    R[i] = j\n\n    print_coins(R, coins)\n    return T[cols - 1]\n\n\ndef min_coins_top_down(coins, total, memo):\n    if total == 0:\n        return 0\n\n    if total in memo:\n        return memo[total]\n\n    min_value = float(\"inf\")\n    for i in range(len(coins)):\n        coin = coins[i]\n        if coin > total:\n            continue\n        val = min_coins_top_down(coins, total - coin, memo)\n        min_value = min(min_value, val)\n\n    min_value += 1\n\n    memo[total] = min_value\n    return min_value\n\n\nif __name__ == '__main__':\n    coins = [1, 5, 6, 8]\n    total = 11\n    expected = 2\n    assert expected == min_coins(coins, total)\n    assert expected == min_coins2(coins, total)\n    assert expected == min_coins_top_down(coins, total, dict())\n"
  },
  {
    "path": "python/dynamic/count_num_A.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nImagine you have a special keyboard with the following keys:\n\nKey 1:  Prints 'A' on screen\nKey 2: (Ctrl-A): Select screen\nKey 3: (Ctrl-C): Copy selection to buffer\nKey 4: (Ctrl-V): Print buffer on screen appending it\n                 after what has already been printed.\n\nIf you can only press the keyboard for N times (with the above four\nkeys), write a program to produce maximum numbers of A's. That is to\nsay, the input parameter is N (No. of keys that you can press), the\noutput is M (No. of As that you can produce).\n\nComplexity\n----------\n\n* Recursive Solution : Exponential > O(2^n)\n* Dynamic Programming: Quadratic O(n^2)\n\nReference\n---------\n* http://www.geeksforgeeks.org/how-to-print-maximum-number-of-a-using-given-four-keys/\n\"\"\"\n\n\ndef count_a_recursive(n_times):\n    if n_times < 7:\n        return n_times\n\n    result = float(\"-inf\")\n\n    for sub_prob in range(n_times - 3, 0, -1):\n        result = max(result, (n_times - sub_prob - 1) * count_a_recursive(sub_prob))\n\n    return result\n\n\ndef count_a(n_times):\n    if n_times < 7:\n        return n_times\n\n    T = [0 for _ in range(n_times + 1)]\n\n    for num in range(7):\n        T[num] = num\n\n    for n in range(7, n_times + 1):\n        for sub_prob in range(n - 3, 0, -1):\n            T[n] = max(T[n], T[sub_prob] * (n - sub_prob - 1))\n\n    return T[n_times]\n\n\nif __name__ == '__main__':\n    expected = 9\n    assert expected == count_a_recursive(7)\n    assert expected == count_a(7)\n"
  },
  {
    "path": "python/dynamic/count_num_binary_without_consec_1.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven a positive integer N, count all the numbers from 1 to 2^N, whose binary representation does not have consecutive\n1s.\n\nThis is a simple application of fibonacci series.\n\nVideo\n-----\n\n* https://www.youtube.com/watch?v=a9-NtLIs1Kk\n\nComplexity\n----------\n\n* Runtime Complexity: O(n)\n\n\nReference\n---------\n\n* http://www.geeksforgeeks.org/count-number-binary-strings-without-consecutive-1s/\n\"\"\"\n\n\ndef consec_one(num_n):\n    f1 = f2 = 1\n\n    for _ in range(num_n):\n        f1, f2 = f1 + f2, f1\n\n    return f1\n\nif __name__ == '__main__':\n    assert 13 == consec_one(5)\n"
  },
  {
    "path": "python/dynamic/cutting_rod.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven a rod of length n inches and an array of prices that contains prices of all pieces of size smaller than n.\nDetermine the maximum value obtainable by cutting up the rod and selling the pieces.\n\nVideo\n-----\n\n* https://youtu.be/IRwVmTmN6go\n\n\nTime Complexity\n---------------\n\n1. Recursive Solution = O(2^n)\n2. Dynamic Programming Solution = O(n^2)\n\nReference\n---------\nhttp://www.geeksforgeeks.org/dynamic-programming-set-13-cutting-a-rod/\n\"\"\"\n\n\ndef max_profit_dp(prices, rod_length):\n    rod_length_values = [0 for _ in range(rod_length + 1)]\n\n    for length in range(1, rod_length + 1):\n\n        max_value = float(\"-inf\")\n\n        for cut_length in range(1, length + 1):\n            max_value = max(max_value, prices[cut_length - 1] + rod_length_values[length - cut_length])\n\n        rod_length_values[length] = max_value\n\n    return rod_length_values[rod_length]\n\n\ndef max_profit_recursive(prices, rod_length):\n    if rod_length == 0:\n        return 0\n\n    max_price = float('-inf')\n\n    for length in range(1, rod_length + 1):\n        max_price = max(max_price, prices[length - 1] + max_profit_recursive(prices, rod_length - length))\n\n    return max_price\n\n\nif __name__ == '__main__':\n    prices = [3,5,8,9,10,20,22,25]\n    rod_length = 8\n    expected_max_profit = 26\n    assert expected_max_profit == max_profit_recursive(prices, rod_length)\n    assert expected_max_profit == max_profit_dp(prices, rod_length)\n"
  },
  {
    "path": "python/dynamic/dice_throw_ways.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven n dice each with m faces, numbered from 1 to m, find the number of ways to get sum X. X is the summation of values\non each face when all the dice are thrown.\n\nComplexity\n----------\n\n* Run time complexity: O(m * n * x) where m is number of faces, n is number of dice and x is given sum.\n\n\nReferences\n----------\n\n* http://www.geeksforgeeks.org/dice-throw-problem/\n\"\"\"\n\n\ndef num_ways(faces, dices, sumX):\n\n    T = [[0 for _ in range(sumX + 1)] for _ in range(dices + 1)]\n\n    # For a single dice\n    for face_value in range(1, faces + 1):\n        if face_value <= sumX:\n            T[1][face_value] = 1\n\n    for dice in range(2, dices + 1):\n        for partial_sum in range(1, sumX + 1):\n            for face_value in range(1, faces + 1):\n                if face_value < partial_sum:\n                    T[dice][partial_sum] += T[dice - 1][partial_sum - face_value]\n\n    return T[dices][sumX]\n\n\nif __name__ == '__main__':\n    assert 7 == num_ways(3, 3, 6)\n"
  },
  {
    "path": "python/dynamic/editdistance.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven two strings str1 and str2, find the minimum number of edits (edit one character to another, delete char from str1\nor delete char from str2) to change str1 to str2.\n\nVideo\n-----\n* https://youtu.be/We3YDTzNXEk\n\nAnalysis\n--------\n* DP Runtime : O(len(str1) * len(str2))\n* Recursive Solution: Exponential (O(3^(m+n-1)))\n\nReference\n---------\n* https://www.clear.rice.edu/comp130/12spring/editdist/\n\"\"\"\n\n\ndef print_edits(T, str1, str2):\n    i = len(T) - 1\n    j = len(T[0]) - 1\n    while True:\n        if i == 0 or j == 0:\n            break\n        if str2[i - 1] == str1[j - 1]:\n            i -= 1\n            j -= 1\n        elif T[i][j] == T[i - 1][j - 1] + 1:\n            print \"Edit %s in string1 to %s in string2.\" % (str1[j - 1], str2[i - 1])\n            i -= 1\n            j -= 1\n        elif T[i][j] == T[i - 1][j] + 1:\n            print \"Delete %s in string2.\" % str2[i - 1]\n            i -= 1\n        elif T[i][j] == T[i][j - 1] + 1:\n            print \"Delete %s in string1.\" % str1[j - 1]\n            j -= 1\n\n\ndef min_edit_distance(str1, str2):\n    rows = len(str2) + 1\n    cols = len(str1) + 1\n    T = [[0 for _ in range(cols)] for _ in range(rows)]\n\n    for j in range(cols):\n        T[0][j] = j\n\n    for i in range(rows):\n        T[i][0] = i\n\n    for i in range(1, rows):\n        for j in range(1, cols):\n            if str2[i - 1] == str1[j - 1]:\n                T[i][j] = T[i - 1][j - 1]\n            else:\n                T[i][j] = 1 + min(T[i - 1][j - 1], T[i - 1][j], T[i][j - 1])\n\n    print_edits(T, str1, str2)\n    return T[rows - 1][cols - 1]\n\ndef min_edit_distance_recursive(str1, str2):\n    i = len(str1)\n    j = len(str2)\n\n    if i == 0: return j\n    if j == 0: return i\n\n    return min(min_edit_distance_recursive(str1[:i - 1], str2) + 1,\n               min_edit_distance_recursive(str1, str2[:j - 1]) + 1,\n               min_edit_distance_recursive(str1[:i - 1], str2[:j - 1]) + (1 if str1[i - 1] != str2[j - 1] else 0))\n\nif __name__ == '__main__':\n    str1 = \"azced\"\n    str2 = \"abcdef\"\n    expected = 3\n    assert expected == min_edit_distance(str1, str2)\n    assert expected == min_edit_distance(str2, str1)\n    assert expected == min_edit_distance_recursive(str1, str2)\n"
  },
  {
    "path": "python/dynamic/egg_drop.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven a certain number of eggs and a certain number of floors, determine the minimum number of attempts required to find\nthe egg breaking floor.\n\nAnalysis\n--------\n\n* Dynamic Programming Time Complexity: O(eggs * num_floors^2)\n* Recursive Solution: Exponential\n\nVideo\n-----\n\n* https://youtu.be/3hcaVyX00_4\n\nReference\n---------\n\n* http://www.geeksforgeeks.org/dynamic-programming-set-11-egg-dropping-puzzle/\n\n\"\"\"\n\n\ndef min_attempts_egg_drop(eggs, floors):\n    num_eggs = eggs + 1\n    num_floors = floors + 1\n\n    T = [[floor if egg == 1 else 0 for floor in range(num_floors)] for egg in range(num_eggs)]\n\n    for egg in range(2, num_eggs):\n        for floor in range(1, num_floors):\n            T[egg][floor] = min(1 + max(T[egg - 1][k - 1], T[egg][floor - k]) for k in range(1, floor + 1))\n\n    return T[num_eggs - 1][num_floors - 1]\n\n\ndef min_attempts_egg_drop_recursive(eggs, floors):\n    if eggs == 1 or floors == 0:\n        return floors\n\n    min_value = float(\"inf\")\n\n    for floor in range(1, floors + 1):\n        min_value = min(min_value,\n                        1 + max(min_attempts_egg_drop_recursive(eggs - 1, floor - 1),\n                                min_attempts_egg_drop_recursive(eggs, floors - floor)))\n\n    return min_value\n\n\nif __name__ == '__main__':\n    eggs = 3\n    floors = 100\n    expected_attempts = 9\n\n    assert expected_attempts == min_attempts_egg_drop(eggs, floors)\n\n    eggs = 2\n    floors = 6\n    expected_attempts = 3\n    assert expected_attempts == min_attempts_egg_drop_recursive(eggs, floors)\n"
  },
  {
    "path": "python/dynamic/knapsack_01.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\n0/1 Knapsack Problem - Given items of certain weights/values and maximum allowed weight how to pick items to pick items\nfrom this set to maximize sum of value of items such that sum of weights is less than or equal to maximum allowed\nweight.\n\nRuntime Analysis\n----------------\nTime complexity - O(W*total items)\n\nVideo\n-----\n* Topdown DP - https://youtu.be/149WSzQ4E1g\n* Bottomup DP - https://youtu.be/8LusJS5-AGo\n\nReferences\n----------\n* http://www.geeksforgeeks.org/dynamic-programming-set-10-0-1-knapsack-problem/\n* https://en.wikipedia.org/wiki/Knapsack_problem\n\"\"\"\n\n\ndef knapsack_01(values, weights, total):\n    total_items = len(weights)\n\n    rows = total_items + 1\n    cols = total + 1\n\n    T = [[0 for _ in range(cols)] for _ in range(rows)]\n\n    for i in range(1, rows):\n        for j in range(1, cols):\n            if j < weights[i - 1]:\n                T[i][j] = T[i - 1][j]\n            else:\n                T[i][j] = max(T[i - 1][j], values[i - 1] + T[i - 1][j - weights[i - 1]])\n\n    return T[rows - 1][cols -1]\n\n\ndef knapsack_01_recursive_util(values, weights, remaining_weight, total_items, current_item, memo):\n    if current_item >= total_items or remaining_weight <= 0:\n        return 0\n\n    key = (total_items - current_item - 1, remaining_weight)\n\n    if key in memo:\n        return memo[key]\n\n    if remaining_weight < weights[current_item]:\n        max_value = knapsack_01_recursive_util(values, weights, remaining_weight, total_items, current_item + 1, memo)\n    else:\n        max_value = max(values[current_item] + knapsack_01_recursive_util(values, weights, remaining_weight - weights[current_item], total_items, current_item + 1, memo),\n                        knapsack_01_recursive_util(values, weights, remaining_weight, total_items, current_item + 1, memo))\n\n    memo[key] = max_value\n    return max_value\n\n\ndef knapsack_01_recursive(values, weights, total_weight):\n    memo = dict()\n    return knapsack_01_recursive_util(values, weights, total_weight, len(values), 0, memo)\n\n\nif __name__ == '__main__':\n    total_weight = 7\n    weights = [1, 3, 4, 5]\n    values = [1, 4, 5, 7]\n    expected = 9\n    assert expected == knapsack_01(values, weights, total_weight)\n    assert expected == knapsack_01_recursive(values, weights, total_weight)\n    total_weight = 8\n    weights = [2, 2, 4, 5]\n    values = [2, 4, 6, 9]\n    expected = 13\n    assert expected == knapsack_01(values, weights, total_weight)\n    assert expected == knapsack_01_recursive(values, weights, total_weight)\n"
  },
  {
    "path": "python/dynamic/kth_ugly_number.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nUgly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15,\nshows the first 11 ugly numbers. By convention, 1 is included.\n\nWrite a program to find the kth ugly number.\n\nComplexity\n----------\n\n* Time Complexity O(n)\n* Space Complexity O(n)\n\nReference\n---------\n* http://www.geeksforgeeks.org/ugly-numbers/\n\"\"\"\n\n\ndef ugly_number(kth):\n    ugly_factors = [1]      # By convention 1 is included.\n\n    factor_index = {\n        2: 0,\n        3: 0,\n        5: 0}\n\n    for num in range(1, kth):\n        minimal_factor = min(min(ugly_factors[factor_index[2]] * 2, ugly_factors[factor_index[3]] * 3),\n                             ugly_factors[factor_index[5]] * 5)\n\n        ugly_factors.append(minimal_factor)\n\n        for factor in [2, 3, 5]:\n            if minimal_factor % factor == 0:\n                factor_index[factor] += 1\n\n    return ugly_factors[kth - 1]\n\nif __name__ == '__main__':\n    assert 5832 == ugly_number(150)\n"
  },
  {
    "path": "python/dynamic/longest_common_subsequence.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven two sequences A = [A1, A2, A3,..., An] and B = [B1, B2, B3,..., Bm], find the length of the longest common\nsubsequence.\n\nVideo\n-----\n\n* https://youtu.be/NnD96abizww\n\nComplexity\n----------\n\n* Recursive Solution: O(2^n) (or O(2^m) whichever of n and m is larger).\n* Dynamic Programming Solution: O(n * m)\n\nReference\n---------\n\n* https://en.wikipedia.org/wiki/Longest_common_subsequence_problem\n* http://www.geeksforgeeks.org/dynamic-programming-set-4-longest-common-subsequence/\n\"\"\"\n\n\ndef lcs_recursive_helper(sequence1, sequence2, index1, index2):\n    if (index1 == len(sequence1)) or (index2 == len(sequence2)):\n        return 0\n\n    if sequence1[index1] == sequence2[index2]:\n        return 1 + lcs_recursive_helper(sequence1, sequence2, index1 + 1, index2 + 1)\n\n    return max(lcs_recursive_helper(sequence1, sequence2, index1 + 1, index2),\n               lcs_recursive_helper(sequence1, sequence2, index1, index2 + 1))\n\n\ndef longest_common_subsequence_recursive(sequence1, sequence2):\n    return lcs_recursive_helper(sequence1, sequence2, 0, 0)\n\n\ndef longest_common_subsequence(sequence1, sequence2):\n    cols = len(sequence1) + 1   # Add 1 to represent 0 valued column for DP\n    rows = len(sequence2) + 1   # Add 1 to represent 0 valued row for DP\n\n    T = [[0 for _ in range(cols)] for _ in range(rows)]\n\n    max_length = 0\n\n    for i in range(1, rows):\n        for j in range(1, cols):\n            if sequence2[i - 1] == sequence1[j - 1]:\n                T[i][j] = 1 + T[i - 1][j - 1]\n            else:\n                T[i][j] = max(T[i - 1][j], T[i][j - 1])\n\n            max_length = max(max_length, T[i][j])\n\n    return max_length\n\n\nif __name__ == '__main__':\n    sequence1 = \"ABCDGHLQR\"\n    sequence2 = \"AEDPHR\"\n    expected_length = 4\n    assert expected_length == longest_common_subsequence_recursive(sequence1, sequence2)\n    assert expected_length == longest_common_subsequence_recursive(sequence2, sequence1)\n    assert expected_length == longest_common_subsequence(sequence1, sequence2)\n    assert expected_length == longest_common_subsequence(sequence2, sequence1)\n"
  },
  {
    "path": "python/dynamic/longest_common_substring.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven two sequences A = [A1, A2, A3,..., An] and B = [B1, B2, B3,..., Bm], find the length of the longest common\nsubstring.\n\nVideo\n-----\n\n* https://youtu.be/BysNXJHzCEs\n\nComplexity\n----------\n\n* Recursive Solution: O(2^n) (or O(2^m) whichever of n and m is larger).\n* Dynamic Programming Solution: O(n * m)\n\nReference\n---------\n\n* http://en.wikipedia.org/wiki/Longest_common_substring_problem\n\"\"\"\n\n\ndef longest_common_string_recursive_helper(str1, str2, pos1, pos2, check_equal):\n    if pos1 == -1 or pos2 == -1:\n        return 0\n\n    if check_equal:\n        if str1[pos1] == str2[pos2]:\n            return 1 + longest_common_string_recursive_helper(str1, str2, pos1 - 1, pos2 - 1, True)\n        else:\n            return 0\n\n    longest = 0     # start (again) to find the longest from the current positions\n    if str1[pos1] == str2[pos2]:\n        longest = 1 + longest_common_string_recursive_helper(str1, str2, pos1 - 1, pos2 - 1, True)\n\n    return max(longest,\n               longest_common_string_recursive_helper(str1, str2, pos1, pos2 - 1, False),\n               longest_common_string_recursive_helper(str1, str2, pos1 - 1, pos2, False))\n\n\ndef longest_common_substring_recursive(str1, str2):\n    return longest_common_string_recursive_helper(str1, str2, len(str1) - 1, len(str2) - 1, False)\n\n\ndef longest_common_substring(str1, str2):\n    cols = len(str1) + 1     # Add 1 to represent 0 valued col for DP\n    rows = len(str2) + 1     # Add 1 to represent 0 valued row for DP\n\n    T = [[0 for _ in range(cols)] for _ in range(rows)]\n\n    max_length = 0\n\n    for i in range(1, rows):\n        for j in range(1, cols):\n            if str2[i - 1] == str1[j - 1]:\n                T[i][j] = T[i - 1][j - 1] + 1\n                max_length = max(max_length, T[i][j])\n\n    return max_length\n\n\nif __name__ == '__main__':\n    str1 = \"abcdef\"\n    str2 = \"zcdemf\"\n    expected = 3\n    assert expected == longest_common_substring(str1, str2)\n    assert expected == longest_common_substring_recursive(str1, str2)\n    str1 = \"abcdef\"\n    str2 = \"cde\"\n    expected = 3\n    assert expected == longest_common_substring(str1, str2)\n    str1 = \"cde\"\n    str2 = \"zcdemf\"\n    expected = 3\n    assert expected == longest_common_substring(str1, str2)\n\n"
  },
  {
    "path": "python/dynamic/longest_increasing_subsequence.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nFind a subsequence in given array in which the subsequence's elements are in sorted order, lowest to highest, and in\nwhich the subsequence is as long as possible.\n\nVideo\n-----\n* https://youtu.be/CE2b_-XfVDk\n\nSolution\n--------\n\nDynamic Programming is used to solve this question. DP equation is.::\n\n        if(arr[i] > arr[j]) { T[i] = max(T[i], T[j] + 1) }\n\n* Time complexity is O(n^2).\n* Space complexity is O(n)\n\nReference\n---------\n\n* http://en.wikipedia.org/wiki/Longest_increasing_subsequence\n* http://www.geeksforgeeks.org/dynamic-programming-set-3-longest-increasing-subsequence/\n\"\"\"\n\n\ndef longest_increasing_subsequence(sequence):\n    sequence_length = len(sequence)\n\n    T = [1 for _ in range(sequence_length)]\n    solution_indices = [i for i in range(sequence_length)]\n\n    for index_i in range(1, sequence_length):\n        for index_j in range(0, index_i):\n            if (sequence[index_i] > sequence[index_j]) and (T[index_i] < T[index_j] + 1):\n                T[index_i] = T[index_j] + 1\n                solution_indices[index_i] = index_j\n\n    # find the index of the max number in T\n    max_value = max(T)\n    max_index = T.index(max_value)\n\n    # Print solution using linked values in solution_indices\n\n    next_index = max_index\n\n    while True:\n        print sequence[next_index],\n\n        old_index = next_index\n        next_index = solution_indices[next_index]\n        if next_index == old_index:\n            break\n\n    return T[max_index]\n\n\ndef longest_increasing_subsequence_recursive(sequence):\n    sequence_length = len(sequence)\n    longest = 0\n\n    for index in range(sequence_length - 1):\n        longest_so_far = longest_subsequence_recursive_helper(sequence, index + 1, sequence[index])\n        if longest_so_far > longest:\n            longest = longest_so_far\n\n    return longest + 1\n\n\ndef longest_subsequence_recursive_helper(sequence, next_position, current_position_value):\n    if next_position == len(sequence):\n        return 0\n\n    temp1 = 0\n    if sequence[next_position] > current_position_value:\n        temp1 = 1 + longest_subsequence_recursive_helper(sequence, next_position + 1, sequence[next_position])\n\n    temp2 = longest_subsequence_recursive_helper(sequence, next_position + 1, current_position_value)\n\n    return max(temp1, temp2)\n\n\nif __name__ == '__main__':\n    sequence = [23, 10, 22, 5, 33, 8, 9, 21, 50, 41, 60, 80, 99, 22, 23, 24, 25, 26, 27]\n    assert 10 == longest_increasing_subsequence(sequence)\n    assert 10 == longest_increasing_subsequence_recursive(sequence)\n"
  },
  {
    "path": "python/dynamic/longest_palindromic_subsequence.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven a string find longest palindromic subsequence in this string.\n\nComplexity\n----------\n\n* Dynamic Programming Time Complexity: O(n^2)\n* Recursive Solution Time Complexity: O(2^n)\n\nVideo\n-----\n* https://youtu.be/_nCsPn7_OgI\n\nReferences\n----------\n* http://www.geeksforgeeks.org/dynamic-programming-set-12-longest-palindromic-subsequence/\n\"\"\"\n\n\ndef longest_palindromic_subsequence(given_string):\n    rows = cols = string_length = len(given_string)\n    T = [[0 for _ in range(cols)] for _ in range(rows)]\n\n    for row in range(rows):\n        T[row][row] = 1\n\n    for substring_length in range(2, string_length + 1):\n        for row in range(0, string_length - substring_length + 1):\n            col = row + substring_length - 1\n\n            if given_string[row] == given_string[col]:\n                if string_length == 2:\n                    T[row][col] = 2\n                else:\n                    T[row][col] = 2 + T[row + 1][col - 1]\n            else:\n                T[row][col] = max(T[row + 1][col], T[row][col - 1])\n\n    return T[0][-1]\n\n\ndef palindromic_subsequence_recursive_helper(given_string, start_index, length):\n    if length == 0 or length == 1:\n        return length\n\n    if given_string[start_index] == given_string[length - start_index - 1]:\n        return 2 + palindromic_subsequence_recursive_helper(given_string, start_index + 1, length - 2)\n    else:\n        return max(palindromic_subsequence_recursive_helper(given_string, start_index, length - 1),\n                   palindromic_subsequence_recursive_helper(given_string, start_index + 1, length - 1))\n\n\ndef longest_palindromic_subsequence_recursive(given_string):\n    return palindromic_subsequence_recursive_helper(given_string, 0, len(given_string))\n\n\nif __name__ == '__main__':\n    given_string = \"agbdba\"\n    expected_result = 5\n    assert expected_result == longest_palindromic_subsequence(given_string)\n    assert expected_result == longest_palindromic_subsequence_recursive(given_string)\n"
  },
  {
    "path": "python/dynamic/matrix_chain_order.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven an array p[] which represents the chain of matrices such that the ith matrix Ai is of dimension p[i-1] x p[i]. We\nneed to write a function matrix_chain_order() that should return the minimum number of multiplications needed to\nmultiply the chain.\n\nVideo\n-----\n* https://youtu.be/vgLJZMUfnsU\n\nNote\n----\n\nIn the code below we give matrices length as an array and each matrix takes 2 indices from the array.\nFor e.g. {2, 3, 4} represents two matrices (2, 3) and (3, 4) in (row, col) format.\n\n\nComplexity\n----------\n\nTime Complexity: O(n^3)\n\nReference\n---------\n\n* http://www.geeksforgeeks.org/dynamic-programming-set-8-matrix-chain-multiplication/\n\"\"\"\n\n\ndef matrix_chain_order(matrices):\n    matrices_length = len(matrices)\n\n    T = [[0 for _ in range(matrices_length)] for _ in range(matrices_length)]\n\n    for gap in range(2, matrices_length):\n        for index_i in range(0, matrices_length - gap):\n            index_j = index_i + gap\n            T[index_i][index_j] = 10000\n            for index_k in range(index_i + 1, index_j):\n                temp = T[index_i][index_k] + T[index_k][index_j] + matrices[index_i] * matrices[index_k] * matrices[index_j]\n                if temp < T[index_i][index_j]:\n                    T[index_i][index_j] = temp\n\n    return T[0][-1]\n\n\nif __name__ == '__main__':\n    matrices = [4, 2, 3, 5, 3]\n    assert 84 == matrix_chain_order(matrices)\n"
  },
  {
    "path": "python/dynamic/maximum_increasing_subsequence.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven an array of n positive integers. Write a program to find the sum of maximum sum subsequence of the given array\nsuch that the integers in the subsequence are in increasing order.\n\nComplexity\n----------\n\n* Time Complexity: O(n^2)\n* Space Complexity: O(n)\n\nVideo\n-----\n\n* https://youtu.be/99ssGWhLPUE\n\nReference\n---------\n* http://www.geeksforgeeks.org/dynamic-programming-set-14-maximum-sum-increasing-subsequence/\n\"\"\"\n\n\ndef maximum_sum_subsequence(sequence):\n    sequence_length = len(sequence)\n    T = [sequence[i] for i in range(sequence_length)]\n\n    for index_i in range(1, sequence_length):\n        for index_j in range(0, index_i):\n            if sequence[index_j] < sequence[index_i]:\n                T[index_i] = max(T[index_i], T[index_j] + sequence[index_i])\n\n    return max(T)\n\nif __name__ == '__main__':\n    sequence = [1, 101, 10, 2, 3, 100, 4]\n    assert 111 == maximum_sum_subsequence(sequence)\n"
  },
  {
    "path": "python/dynamic/nth_fibonacci.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven the number n, find the nth fibanacci number.\n\nThe fibonacci series is 0, 1, 1, 2, 3 ...\n\nAnd follows the formula Fn = Fn-1 + Fn-2\n\nComplexity\n----------\n\n* Recursive Solution: O(2^n)\n* Dynamic Programming: O(n)\n\n\"\"\"\n\n\ndef fibonacci_recursive(n):\n    if n == 0 or n == 1:\n        return n\n\n    return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)\n\n\ndef fibonacci(n):\n    n1, n2 = 0, 1\n\n    if n == n1 or n == n2:\n        return n\n\n    for i in range(2, n + 1):\n        n1, n2 = n2, n1 + n2\n\n    return n2\n\nif __name__ == '__main__':\n    assert 610 == fibonacci_recursive(15)\n    assert 610 == fibonacci(15)\n"
  },
  {
    "path": "python/dynamic/num_bst.py",
    "content": "\"\"\"\nProblem Statement\n=================\nCount number of binary search trees created for array of size n. The solution is the nth catalan number.\n\n\nComplexity\n----------\n* Dynamic Programming: O(n^2)\n* Recursive Solution: O(2^n)\n\nVideo\n-----\n\n* https://youtu.be/YDf982Lb84o\n\nReference\n---------\n* http://www.geeksforgeeks.org/program-nth-catalan-number/\n\"\"\"\n\n\ndef num_bst(num_nodes):\n    T = [0 for _ in range(num_nodes + 1)]\n    T[0] = 1\n    T[1] = 1\n\n    for node in range(2, num_nodes+1):\n        for sub in range(0, node):\n            T[node] += T[sub] * T[node - sub - 1]\n\n    return T[num_nodes]\n\n\ndef num_bst_recursive(num_nodes):\n    if num_nodes == 0 or num_nodes == 1:\n        return 1\n\n    result = 0\n\n    for root in range(1, num_nodes + 1):\n        result += num_bst_recursive(root - 1) * num_bst_recursive(num_nodes - root)\n\n    return result\n\n\nif __name__ == '__main__':\n    assert 5 == num_bst(3)\n    assert 5 == num_bst_recursive(3)\n"
  },
  {
    "path": "python/dynamic/num_paths_nm_matrix.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nCount the number of Paths from 1,1 to N,M in an NxM matrix.\n\nAnalysis\n--------\n\n* Dynamic Programing Solution: O(rows * cols)\n* Recursive: O(2^rows) if rows > cols else O(2^cols)\n\n\nReferences\n----------\n* http://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/\n\n\"\"\"\n\n\ndef num_paths_matrix(rows, cols):\n    T = [[1 if row == 0 or col == 0 else 0 for row in range(cols)] for col in range(rows)]\n    for row in range(1, rows):\n        for col in range(1, cols):\n            T[row][col] = T[row - 1][col] + T[row][col - 1]\n    return T[rows - 1][cols - 1]\n\n\ndef num_paths_matrix_recursive(rows, cols):\n    if rows == 1 or cols == 1:\n        return 1\n    return num_paths_matrix(rows-1, cols) + num_paths_matrix(rows, cols - 1)\n\n\nif __name__ == '__main__':\n    rows = 3\n    cols = 3\n    expected = 6\n    assert expected == num_paths_matrix(rows, cols)\n    assert expected == num_paths_matrix_recursive(rows, cols)\n"
  },
  {
    "path": "python/dynamic/num_trees_preorder.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven the number of nodes N, in a pre-order sequence how many unique trees can be created? Number of tree is exactly\nsame as number of unique BST create with array of size n. The solution is a catalan number.\n\nComplexity\n----------\n* Dynamic Programming: O(n^2)\n* Recursive Solution: O(2^n)\n\nVideo\n-----\n* https://youtu.be/RUB5ZPfKcnY\n\"\"\"\n\n\ndef num_trees(num_nodes):\n    T = [0 for _ in range(num_nodes + 1)]\n    T[0] = 1\n    T[1] = 1\n    for n in range(2, num_nodes + 1):\n        for j in range(0, n):\n            T[n] += T[j] * T[n - j - 1]\n    return T[num_nodes]\n\n\ndef num_trees_recursive(num_nodes):\n    if num_nodes == 0 or num_nodes == 1:\n        return 1\n\n    result = 0\n\n    for n in range(1, num_nodes + 1):\n        result += num_trees_recursive(n - 1) * num_trees_recursive(num_nodes - n)\n\n    return result\n\n\n\n\nif __name__ == '__main__':\n    assert 5 == num_trees(3)\n    assert 14 == num_trees(4)\n    assert 42 == num_trees(5)\n    assert 5 == num_trees_recursive(3)\n    assert 14 == num_trees_recursive(4)\n    assert 42 == num_trees_recursive(5)\n"
  },
  {
    "path": "python/dynamic/optimal_bst.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven a sorted array keys[0.. n-1] of search keys and an array freq[0.. n-1] of frequency counts, where freq[i] is the\nnumber of searches to keys[i]. Construct a binary search tree of all keys such that the total cost of all the searches\nis as small as possible.\n\nVideo\n-----\n* https://youtu.be/hgA4xxlVvfQ\n\nAnalysis\n--------\n* Recursive: Exponential O(n^n)\n* Dynamic Programming: O(n^3)\n\nReference\n---------\n* http://www.geeksforgeeks.org/dynamic-programming-set-24-optimal-binary-search-tree/\n\"\"\"\n\n\ndef min_cost_bst(input_array, freq):\n    size = rows = cols = len(input_array)\n    T = [[0 for _ in range(cols)] for _ in range(rows)]\n\n    for idx in range(rows):\n        T[idx][idx] = freq[idx]\n\n    for sub_tree_size in range(2, size + 1):\n        for start in range(size + 1 - sub_tree_size):\n            end = start + sub_tree_size - 1\n            T[start][end] = float(\"inf\")\n            total = sum(freq[start:end + 1])\n            for k in range(start, end + 1):\n                val = total + (0 if k - 1 < 0 else T[start][k - 1]) + (0 if k + 1 > end else T[k + 1][end])\n                T[start][end] = min(val, T[start][end])\n\n    return T[0][-1]\n\n\ndef min_cost_bst_recursive_helper(input_array, freq, low_index, high_index, level):\n    if low_index > high_index:\n        return 0\n    min_value = float(\"inf\")\n\n    for index in range(low_index, high_index + 1):\n        val = (min_cost_bst_recursive_helper(input_array, freq, low_index, index - 1, level + 1)        # left tree\n               + level * freq[index]                                                                    # value at level\n               + min_cost_bst_recursive_helper(input_array, freq, index + 1, high_index, level + 1))    # right tree\n        min_value = min(val, min_value)\n\n    return min_value\n\n\ndef min_cost_bst_recursive(input_array, freq):\n    return min_cost_bst_recursive_helper(input_array, freq, 0, len(input_array) - 1, 1)\n\n\nif __name__ == '__main__':\n    input_array = [10, 12, 16, 21]\n    freq = [4, 2, 6, 3]\n    expected = 26\n    assert expected == min_cost_bst(input_array, freq)\n    assert expected == min_cost_bst_recursive(input_array, freq)\n    input_array = [10, 12, 20, 35, 46]\n    freq = [34, 8, 50, 21, 16]\n    expected = 232\n    assert expected == min_cost_bst(input_array, freq)\n    assert expected == min_cost_bst_recursive(input_array, freq)\n"
  },
  {
    "path": "python/dynamic/stockbuysellktransactions.py",
    "content": "\"\"\"\"\nProblem Statement\n=================\n\nGiven certain stock values over a period of days (d days) and a number K, the number of transactions allowed, find the\nmaximum profit that be obtained with at most K transactions.\n\nVideo\n-----\n* https://youtu.be/oDhu5uGq_ic\n\nComplexity\n----------\n\n* Space Complexity O(days * transctions)\n* Time Complexity: Slow Solution O (days^2 * transactions), Faster Solution O(days * transaction)\n\"\"\"\n\n\ndef max_profit(prices, K):\n    if K == 0 or prices == []:\n        return 0\n\n    days = len(prices)\n    num_transactions = K + 1  # 0th transaction up to and including kth transaction is considered.\n\n    T = [[0 for _ in range(days)] for _ in range(num_transactions)]\n\n    for transaction in range(1, num_transactions):\n        max_diff = - prices[0]\n        for day in range(1, days):\n            T[transaction][day] = max(T[transaction][day - 1],  # No transaction\n                                      prices[day] + max_diff)  # price on that day with max diff\n            max_diff = max(max_diff,\n                           T[transaction - 1][day] - prices[day])  # update max_diff\n\n    print_actual_solution(T, prices)\n\n    return T[-1][-1]\n\n\ndef max_profit_slow_solution(prices, K):\n    if K == 0 or prices == []:\n        return 0\n\n    days = len(prices)\n    num_transactions = K + 1\n\n    T = [[0 for _ in range(len(prices))] for _ in range(num_transactions)]\n\n    for transaction in range(1, num_transactions):\n        for day in range(1, days):\n            # This maximum value of either\n            # a) No Transaction on the day. We pick the value from day - 1\n            # b) Max profit made by selling on the day plus the cost of the previous transaction, considered over m days\n            T[transaction][day] = max(T[transaction][day - 1],\n                                      max([(prices[day] - prices[m] + T[transaction - 1][m]) for m in range(day)]))\n\n    print_actual_solution(T, prices)\n    return T[-1][-1]\n\n\ndef print_actual_solution(T, prices):\n    transaction = len(T) - 1\n    day = len(T[0]) - 1\n    stack = []\n\n    while True:\n        if transaction == 0 or day == 0:\n            break\n\n        if T[transaction][day] == T[transaction][day - 1]:  # Didn't sell\n            day -= 1\n        else:\n            stack.append(day)          # sold\n            max_diff = T[transaction][day] - prices[day]\n            for k in range(day - 1, -1, -1):\n                if T[transaction - 1][k] - prices[k] == max_diff:\n                    stack.append(k)  # bought\n                    transaction -= 1\n                    break\n\n    for entry in range(len(stack) - 1, -1, -2):\n        print(\"Buy on day {day} at price {price}\".format(day=stack[entry], price=prices[stack[transaction]]))\n        print(\"Sell on day {day} at price {price}\".format(day=stack[entry], price=prices[stack[transaction - 1]]))\n\n\nif __name__ == '__main__':\n    prices = [2, 5, 7, 1, 4, 3, 1, 3]\n    assert 10 == max_profit(prices, 3)\n    assert 10 == max_profit_slow_solution(prices, 3)\n"
  },
  {
    "path": "python/dynamic/string_interleaving.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven three strings A, B and C. Write a function that checks whether C is an interleaving of A and B. C is said to be\ninterleaving A and B, if it contains all characters of A and B and order of all characters in individual strings is\npreserved.\n\nhttp://www.geeksforgeeks.org/check-whether-a-given-string-is-an-interleaving-of-two-other-given-strings-set-2/\n\nVideo: https://www.youtube.com/watch?v=ih2OZ9-M3OM\n\"\"\"\n\ndef is_interleaved_recursive(str1, str2, str3, pos1, pos2, pos3):\n    if pos1 == len(str1) and pos2 == len(str2) and pos3 == len(str3):\n        return True\n\n    if pos3 == len(str3):\n        return False\n\n    return (((pos1 < len(str1) and str1[pos1] == str3[pos3]) and is_interleaved_recursive(str1, str2, str3, pos1 + 1, pos2, pos3 + 1)) or\n            (pos2 < len(str2) and str2[pos2] == str3[pos3]) and is_interleaved_recursive(str1, str2, str3, pos1, pos2 + 1, pos3 + 1))\n\n\ndef is_interleaved(str1, str2, str3):\n    if len(str3) != (len(str1) + len(str2)):\n        return False\n\n    cols = len(str1) + 1\n    rows = len(str2) + 1\n\n    T = [[False for _ in range(cols)] for _ in range(rows)]\n\n    for row in range(rows):\n        for col in range(cols):\n            index = row + col - 1\n            if row == 0 and col == 0:\n                T[row][col] = True\n            elif row == 0:\n                if str3[index] == str1[col - 1]:\n                    T[row][col] = True and T[row][col - 1]\n            elif col == 0:\n                if str3[index] == str2[row - 1]:\n                    T[row][col] = True and T[row - 1][col]\n            else:\n                T[row][col] = ((T[row][col - 1] if str3[index] == str1[col - 1] else False) or\n                               (T[row - 1][col] if str3[index] == str2[row - 1] else False))\n\n    return T[rows - 1][cols - 1]\n\n\nif __name__ == '__main__':\n    str1 = \"XXYM\"\n    str2 = \"XXZT\"\n    str3 = \"XXXZXYTM\"\n\n    assert True == is_interleaved(str1, str2, str3)\n    assert True == is_interleaved_recursive(str1, str2, str3, 0, 0, 0)\n"
  },
  {
    "path": "python/dynamic/sub_rectangular_maximum_sum.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nWrite a program to find maximum sum rectangle in give 2D matrix. Assume there is at least one positive number in the 2D\nmatrix.\n\nSolution:\n--------\n\n* Keep temp array with size as number of rows. Start left and right from 0 and keep adding values for each row and\n  maintain them in this temp array.\n* Run Kadane's algorithm to find max sum subarray in temp. Now increment right by 1.\n* When right reaches last column reset right to 1 and left to 1.\n\nAnalysis\n--------\n* Space complexity of this algorithm is O(row)\n* Time complexity of this algorithm is O(row*col*col)\n\nVideo\n-----\n* https://youtu.be/yCQN096CwWM\n\nReferences\n----------\n* http://www.geeksforgeeks.org/dynamic-programming-set-27-max-sum-rectangle-in-a-2d-matrix/\n\"\"\"\n\nfrom collections import namedtuple\n\nResult = namedtuple(\"Result\",\"maxSum leftBound rightBound upBound lowBound\")\n\nKadanesResult = namedtuple(\"KadanesResult\",\"maxSum start end\")\n\n\ndef kadanes(temp):\n    max = 0\n    maxStart = -1\n    maxEnd = -1\n    currentStart = 0\n    maxSoFar = 0\n\n    for i in range(0, len(temp)):\n        maxSoFar += temp[i]\n\n        if maxSoFar < 0:\n            maxSoFar = 0\n            currentStart = i + 1\n\n        if maxSoFar > max:\n            maxStart = currentStart\n            maxEnd = i\n            max = maxSoFar\n\n    return KadanesResult(max, maxStart, maxEnd)\n\n\ndef max_sub_sub_rectangle(rectangle):\n\n    rows = len(rectangle)\n    cols = len(rectangle[0])\n\n    result = Result(float(\"-inf\"), -1, -1, -1, -1)\n\n    for left in range(cols):\n        temp = [0 for _ in range(rows)]\n        for right in range(left, cols):\n            for i in range(rows):\n                temp[i] += rectangle[i][right]\n\n            kadanes_result = kadanes(temp)\n            if kadanes_result.maxSum > result.maxSum:\n                result = Result(kadanes_result.maxSum, left, right, kadanes_result.start, kadanes_result.end)\n\n    return result\n\nif __name__ == '__main__':\n    rectangle = [[2,  1, -3, -4,  5],\n                 [0,  6,  3,  4,  1],\n                 [2, -2, -1,  4, -5],\n                 [-3,  3,  1,  0,  3]]\n\n    result = max_sub_sub_rectangle(rectangle)\n    assert 18 == result.maxSum\n    print result\n"
  },
  {
    "path": "python/dynamic/subset_sum.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven an array of non negative numbers and a total, is there subset of numbers in this array which adds up to given\ntotal. Another variation is given an array is it possible to split it up into 2 equal sum partitions. Partition need not\nbe equal sized. Just equal sum.\n\nVideo\n-----\n\n* https://youtu.be/s6FhG--P7z0\n\nSolution\n--------\n\n* Time complexity is O(input.size * total_sum)\n* Space complexity is O(input.size*total_sum)\n\nReference\n---------\n\n* https://en.wikipedia.org/wiki/Subset_sum_problem\n\"\"\"\n\n\ndef subset_sum(sequence, sum_value):\n    cols = sum_value + 1         # Plus 1 for 0 valued col.\n    rows = len(sequence) + 1     # Plus 1 for 0 valued row.\n    T = [[False for _ in range(cols)] for _ in range(rows)]\n\n    for row in range(rows):\n        T[row][0] = True\n\n    for index_i in range(1, rows):\n        for index_j in range(1, cols):\n            if index_j >= sequence[index_i - 1]:\n                T[index_i][index_j] = T[index_i - 1][index_j] or T[index_i - 1][index_j - sequence[index_i - 1]]\n            else:\n                T[index_i][index_j] = T[index_i - 1][index_j]\n\n    return T[rows - 1][cols - 1]\n\n\ndef partition(sequence):\n    sequence_sum = sum(sequence)\n    if sequence_sum % 2 != 0:\n        return False\n\n    expected = sequence_sum / 2\n\n    return subset_sum(sequence, expected)\n\n\nif __name__ == '__main__':\n    sequence = [2, 3, 7, 8]\n    assert True == subset_sum(sequence, 11)\n\n    sequence = [1, 3, 5, 5, 2, 1, 1, 6]\n    assert True == partition(sequence)\n"
  },
  {
    "path": "python/dynamic/symbolexpressionevaluation.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nLet there be a binary operation for 3 symbols a, b, c and result of these binary operation given in a table.\nGiven an expression of these 3 symbols and a final result, tell if this expression can be parenthesize in certain\nway to produce the final result.\n\nComplexity\n----------\n\n* Run time Complexity: O(n^3)\n* SpaceL O(n^2)\n\nWhere n is the length of the expression.\n\"\"\"\n\n\ndef evaluate_expression(expression_map, expression, result):\n    expression_length = len(expression)\n    T = [[set() for _ in range(expression_length)] for _ in range(len(expression))]\n\n    for idx, expr in enumerate(expression):\n        T[idx][idx].add(expr)\n\n    # We take a sub expression of length 2 until the total expression length\n    for sub_length in range(2, expression_length + 1):\n        for left_index in range(0, expression_length - sub_length + 1):\n            right_index = left_index + sub_length - 1\n            # we split the expression at different k indices for the total sub-expression length and store the result.\n            # at T[left_index][right_index]\n            # Like bbc, will be treated for (b(bc) and ((bb) c) and the final result is stored in a set at T[0][2]\n            for k in range(left_index, right_index):\n                for expr1 in T[left_index][k]:\n                    for expr2 in T[k+1][right_index]:\n                        T[left_index][right_index].add(expression_map[(expr1, expr2)])\n\n    for expr in T[0][-1]:\n        if result in expr:\n            return True\n\n    return False\n\nif __name__ == '__main__':\n    expressions = ['a', 'b', 'c']\n    # expression table denotes the binary operation between two expression and its result.\n    expression_table = [\n        ['b', 'b', 'a'],\n        ['c', 'b', 'a'],\n        ['a', 'a', 'c']\n    ]\n\n    # For convenience, we can modify it to be more explicit and use the expression table\n\n    expression_map = {\n        ('a', 'a'): 'b',\n        ('a', 'b'): 'b',\n        ('a', 'c'): 'a',\n        ('b', 'a'): 'c',\n        ('b', 'b'): 'b',\n        ('b', 'c'): 'a',\n        ('c', 'a'): 'a',\n        ('c', 'b'): 'a',\n        ('c', 'c'): 'c'\n    }\n\n    assert True == evaluate_expression(expression_map, 'bbbbac', 'a')\n"
  },
  {
    "path": "python/dynamic/weighted_job_scheduling_max_profit.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven set of jobs with start and end interval and profit, how to maximize profit such that jobs in subset do not\noverlap.\n\nVideo\n-----\n* https://youtu.be/cr6Ip0J9izc\n\nComplexity\n----------\n\n* Runtime Complexity: O(n^2)\n* Space Complexity: O(n)\n\nReference Link\n--------------\n* http://www.cs.princeton.edu/courses/archive/spr05/cos423/lectures/06dynamic-programming.pdf\n\"\"\"\n\n\ndef can_sequence(job1, job2):\n    _, job1_finish_time = job1\n    job2_start_time, _ = job2\n    return job1_finish_time <= job2_start_time\n\n\ndef find_max_profit(jobs):\n    sequenced_jobs = sorted(jobs.keys(), key=lambda x: x[1])\n    T = [jobs[job_key] for job_key in sequenced_jobs]\n    num_jobs = len(sequenced_jobs)\n\n    for j in range(1, num_jobs):\n        for i in range(0, j):\n            if can_sequence(sequenced_jobs[i], sequenced_jobs[j]):\n                T[j] = max(T[j], T[i] + jobs[sequenced_jobs[j]])\n\n    return max(T)\n\n\nif __name__ == '__main__':\n    jobs = {\n        (1, 3): 5,      # (start_time, end_time, total_cost)\n        (2, 5): 6,\n        (4, 6): 5,\n        (6, 7): 4,\n        (5, 8): 11,\n        (7, 9): 2\n    }\n\n    assert 17 == find_max_profit(jobs)\n"
  },
  {
    "path": "python/geometry/skylinedrawing.py",
    "content": "# https://leetcode.com/problems/the-skyline-problem/\n\nclass BuildingPoint(object):\n\n    def __init__(self, point, is_start, height):\n        self.point = point;\n        self.is_start = is_start\n        self.height = height\n        \n    def __lt__(self, other):\n        if self.point != other.point:\n            return self.point < other.point\n        else:\n            if self.is_start:\n                h1 = -self.height\n            else:\n                h1 = self.height\n\n            if other.is_start:\n                h2 = -other.height;\n            else:\n                h2 = other.height\n\n            return h1 < h2\n    \ndef get_skyline(buildings):\n\n    building_points = []\n    for building in buildings:\n        building_points.append(BuildingPoint(building[0], True, building[2]))\n        building_points.append(BuildingPoint(building[1], False, building[2]))\n\n    building_points = sorted(building_points)\n\n    queue = {}\n    queue[0] = 1\n    prev_max_height = 0\n    result = []\n    for building_point in building_points:\n        if building_point.is_start:\n            if building_point.height in queue:\n                queue[building_point.height] = queue[building_point.height] + 1\n            else:\n                queue[building_point.height] = 1\n    \n        else:\n            if queue[building_point.height] == 1:\n                del queue[building_point.height]\n            else:\n                queue[building_point.height] = queue[building_point.height] - 1\n\n        current_max_height = max(queue.keys())\n\n        if prev_max_height != current_max_height:\n            result.append([building_point.point, current_max_height])\n            prev_max_height = current_max_height\n    return result\n\nif __name__ == '__main__':\n    buildings = [[1, 3, 4], [3, 4, 4], [2, 6, 2], [8, 11, 4], [7, 9, 3], [10, 11, 2]]\n    print(get_skyline(buildings))\n    \n"
  },
  {
    "path": "python/graph/cycledirectedgraph.py",
    "content": "# detect cycle in directed graph\n# https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/CycleInDirectedGraph.java\n\nfrom graph import *\n\ndef has_cycle(graph):\n    white = set()\n    gray = set()\n    black = set()\n\n    for vertex in graph.all_vertex.values():\n        white.add(vertex)\n\n    while len(white) > 0:\n        current = next(iter(white))       \n        if dfs(current, white, gray, black) == True:\n            return True\n\n    return False        \n\ndef dfs(current, white, gray, black):\n    move_vertex(current, white, gray)\n    for neighbor in current.adjacent_vertices:\n        if neighbor in black:\n            continue\n        if neighbor in gray:\n            return True\n        if dfs(neighbor, white, gray, black) == True:\n            return True\n        \n    move_vertex(current, gray, black)\n    return False\n\ndef move_vertex(vertex, source_set, destination_set):\n    source_set.remove(vertex)\n    destination_set.add(vertex)\n        \nif __name__ == '__main__':\n    graph = Graph(True)\n    graph.add_edge(1,2)\n    graph.add_edge(1,3)\n    graph.add_edge(2,3)\n    graph.add_edge(4,1)\n    graph.add_edge(4,5)\n    graph.add_edge(5,6)\n    graph.add_edge(6,4)\n\n    print(has_cycle(graph));\n     \n"
  },
  {
    "path": "python/graph/cycleundirectedgraph.py",
    "content": "# detect cycle in undirected graph\n# https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/CycleUndirectedGraph.java\n\nfrom graph import *\nfrom disjointset import *\n\ndef has_cycle_dfs(graph):\n    visited = set()\n    for vertex in graph.all_vertex.values():\n        if vertex in visited:\n            continue\n        flag = has_cycle_dfs_util(vertex, visited, None)\n        if flag:\n            return True\n    return False        \n\ndef has_cycle_dfs_util(vertex, visited, parent):\n    visited.add(vertex)\n    for adjacent in vertex.adjacent_vertices:\n        if parent is not None and adjacent == parent:\n            continue\n        if adjacent in visited:\n            return True\n        has_cycle = has_cycle_dfs_util(adjacent, visited, vertex)\n        if has_cycle:\n            return True\n    return False\n\ndef has_cycle_using_disjoint_set(graph):\n    disjoint_set = DisjointSet()\n\n    for vertex in graph.all_vertex.values():\n        disjoint_set.make_set(vertex.id)\n\n    for edge in graph.all_edges:\n        parent1 = disjoint_set.find_set(edge.vertex1.id)\n        parent2 = disjoint_set.find_set(edge.vertex2.id)\n        if parent1 == parent2:\n            return True\n        disjoint_set.union(edge.vertex1.id, edge.vertex2.id)\n\n    return False\n\n\nif __name__ == '__main__':\n    graph = Graph(False)\n    graph.add_edge(0,1)\n    graph.add_edge(1,2)\n    graph.add_edge(0,3)\n    graph.add_edge(3,4)\n    graph.add_edge(4,5)\n    graph.add_edge(5,1)\n\n    has_cycle1 = has_cycle_dfs(graph)\n    has_cycle2 = has_cycle_using_disjoint_set(graph)\n    print(str(has_cycle1) + \" \" + str(has_cycle2))\n        \n"
  },
  {
    "path": "python/graph/dijkstrashortestpath.py",
    "content": "#dijkstra's algorithm\n\n# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/DijkstraShortestPath.java\n\nfrom priorityqueue import PriorityQueue\nfrom graph import Graph\nimport sys\n\n\ndef shortest_path(graph, sourceVertex):\n\n    min_heap = PriorityQueue(True)\n    distance = {}\n    parent = {}\n\n    for vertex in graph.all_vertex.values():\n        min_heap.add_task(sys.maxsize, vertex)\n\n    min_heap.change_task_priority(0, sourceVertex)\n    distance[sourceVertex] = 0\n    parent[sourceVertex] = None\n\n    while min_heap.is_empty() is False:\n        task = min_heap.peek_task()\n        weight = min_heap.get_task_priority(task)               \n        current =  min_heap.pop_task()\n        distance[current] = weight\n\n        for edge in current.edges:\n            adjacent = get_other_vertex_for_edge(current, edge)\n            if min_heap.contains_task(adjacent) is False:\n                continue\n\n            new_distance = distance[current] + edge.weight;\n            if min_heap.get_task_priority(adjacent) > new_distance:\n                min_heap.change_task_priority(new_distance, adjacent)\n                parent[adjacent] = current\n                \n\n    return distance\n\n\ndef get_other_vertex_for_edge(vertex, edge):\n    if edge.vertex1.id == vertex.id:\n        return edge.vertex2\n    else:\n        return edge.vertex1\n\n\nif __name__ == '__main__':\n    graph = Graph(False)\n    graph.add_edge(1,2,5)\n    graph.add_edge(2,3,2)\n    graph.add_edge(1,4,9)\n    graph.add_edge(1,5,3)\n    graph.add_edge(5,6,2)\n    graph.add_edge(6,4,2)\n    graph.add_edge(3,4,3)\n    \n    distance = shortest_path(graph, graph.all_vertex[1])\n    print(distance)\n"
  },
  {
    "path": "python/graph/disjointset.py",
    "content": "# disjoint sets\n# https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/DisjointSet.java\n\nclass Node(object):\n\n    def __init__(self, data, parent = None, rank = 0):\n        self.data = data\n        self.parent = parent\n        self.rank = rank\n\n    def __str__(self):\n        return str(self.data)\n\n    def __repr__(self):\n        return self.__str__()\n\n\nclass DisjointSet(object):\n\n    def __init__(self):\n        self.map = {}\n\n    def make_set(self, data):\n       node = Node(data)\n       node.parent = node\n       self.map[data] = node\n\n    def union(self, data1, data2):\n        node1 = self.map[data1]\n        node2 = self.map[data2]\n\n        parent1 = self.find_set_util(node1)\n        parent2 = self.find_set_util(node2)\n\n        if parent1.data == parent2.data:\n            return\n\n        if parent1.rank >= parent2.rank:\n            if parent1.rank == parent2.rank:\n                parent1.rank = parent1.rank + 1\n            parent2.parent = parent1\n        else:\n            parent1.parent = parent2\n\n    def find_set(self, data):\n        return self.find_set_util(self.map[data])\n\n    def find_set_util(self, node):\n        parent = node.parent\n        if parent == node:\n            return parent\n        node.parent = self.find_set_util(node.parent)\n        return node.parent\n\nif __name__ == '__main__':\n    ds = DisjointSet()\n    ds.make_set(1)\n    ds.make_set(2)\n    ds.make_set(3)\n    ds.make_set(4)\n    ds.make_set(5)\n    ds.make_set(6)\n    ds.make_set(7)\n\n    ds.union(1,2)\n    ds.union(2,3)\n    ds.union(4,5)\n    ds.union(6,7)\n    ds.union(5,6)\n    ds.union(3,7)\n\n    for i in range(1,8):\n        print(ds.find_set(i))\n    \n    \n        \n         \n"
  },
  {
    "path": "python/graph/floydwarshall.py",
    "content": "# floyd warshall all pair shortest path\n# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/FloydWarshallAllPairShortestPath.java\nimport sys\n\nINF = 1000000\n\nclass NegativeWeightCycleException(Exception):\n    def __init__(self):\n        pass\n\ndef all_pair_shortest_path(distance_matrix):\n\n    size = len(distance_matrix)\n    distance = [[0 for x in range(size)]\n                for x in range (size)]\n    \n    path = [[0 for x in range(size)]\n                for x in range (size)]\n\n    for i in range(size):\n        for j in range(size):\n            distance[i][j] = distance_matrix[i][j]\n            if distance_matrix[i][j] != INF and i != j:\n                path[i][j] = i\n            else:\n                path[i][j] = -1\n\n\n    for k in range(size):\n        for i in range(size):\n            for j in range(size):\n                if distance[i][k] == INF or distance[k][j] == INF:\n                    continue\n                if distance[i][j] > distance[i][k] + distance[k][j]:\n                    distance[i][j] = distance[i][k] + distance[k][j]\n                    path[i][j] = path[k][j]\n\n    for i in range(size):\n        if distance[i][i] < 0:\n            raise NegativeWeightCycleException()\n\n    print_path(path, 3, 2)\n    return (distance, path)\n\ndef print_path(path, start, end):\n    stack = []\n    stack.append(end)\n    while True:\n        end = path[start][end]\n        if end == -1:\n            return\n        stack.append(end)\n        if end == start:\n            break\n\n    print(stack[::-1])\n\nif __name__ == '__main__':\n    \n    distance_matrix = [[0, 3, 6, 15],\n             [INF, 0, -2, INF],\n             [INF, INF, 0, 2],\n             [1, INF, INF, 0]]\n\n    distance, path = all_pair_shortest_path(distance_matrix)\n\n    print(distance)\n    #print(path)\n    \n    \n    \n    \n"
  },
  {
    "path": "python/graph/fordfulkerson.py",
    "content": "#ford fulkerson method Edomonds Karp algorithm for finding max flow\n# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/FordFulkerson.java\nfrom queue import Queue\nimport sys\n\ndef max_flow(capacity, source, sink):\n    residual_capacity = [x[:] for x in capacity]\n    augmented_paths = []\n    max_flow = 0\n    while True:\n        found_augmented_path, parent = bfs(residual_capacity, source, sink)\n        if not found_augmented_path:\n            break\n        augmented_path = []\n        v = sink\n        flow = sys.maxsize\n        while not v == source:\n            augmented_path.append(v)\n            u = parent[v]\n            if flow > residual_capacity[u][v]:\n                flow = residual_capacity[u][v]\n            v = u\n        augmented_path.append(source)\n        augmented_paths.append(augmented_path[::-1])\n        max_flow += flow\n\n        v = sink\n        while not v == source:\n             u = parent[v]\n             residual_capacity[u][v] -= flow\n             residual_capacity[v][u] += flow\n             v = u\n\n    print(\"Augmented path\")\n    print(augmented_paths)\n    return max_flow\n\ndef bfs(residual_capacity, source, sink):\n    visited = set()\n    queue = Queue()\n    parent = {}\n    queue.put(source)\n    visited.add(source)\n    found_augmented_path = False\n    while not queue.empty():\n        u = queue.get()\n        for v in range(len(residual_capacity)):\n            if v not in visited and residual_capacity[u][v] > 0:\n                parent[v] = u\n                visited.add(v)\n                queue.put(v)\n                if v == sink:\n                    found_augmented_path = True\n                    break;\n    return found_augmented_path, parent                               \n\nif __name__ == '__main__':\n    capacity = [[0, 3, 0, 3, 0, 0, 0],\n                [0, 0, 4, 0, 0, 0, 0],\n                [3, 0, 0, 1, 2, 0, 0],\n                [0, 0, 0, 0, 2, 6, 0],\n                [0, 1, 0, 0, 0, 0, 1],\n                [0, 0, 0, 0, 0, 0, 9],\n                [0, 0, 0, 0, 0, 0, 0]]\n\n    max_val = max_flow(capacity, 0, 6)\n    print(max_val)\n"
  },
  {
    "path": "python/graph/graph.py",
    "content": "#Graph class\n# Java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/Graph.java\n\nclass Graph(object):\n\n    def __init__(self, is_directed):\n        self.all_edges = []\n        self.all_vertex = {}\n        self.is_directed = is_directed\n\n    def add_edge(self, id1, id2, weight=0):\n        if id1 in self.all_vertex:\n            vertex1 = self.all_vertex[id1]\n        else:\n            vertex1 = Vertex(id1)\n            self.all_vertex[id1] = vertex1\n\n        if id2 in self.all_vertex:\n            vertex2 = self.all_vertex[id2]\n        else:\n            vertex2 = Vertex(id2)\n            self.all_vertex[id2] = vertex2\n\n        edge = Edge(vertex1, vertex2, self.is_directed, weight)\n        self.all_edges.append(edge)\n        vertex1.add_adjacent_vertex(edge, vertex2)\n        if self.is_directed is not True:\n            vertex2.add_adjacent_vertex(edge,vertex1)\n\n \nclass Edge(object):\n    \n    def __init__(self, vertex1, vertex2, is_directed, weight):\n        self.vertex1 = vertex1\n        self.vertex2 = vertex2\n        self.is_directed = is_directed\n        self.weight = weight\n\n    def __eq__(self, other):\n        return self.vertex1.id == other.vertex1.id and self.vertex2.id == other.vertex2.id\n\n    def __hash(self):\n        return hash(vertex1) + hash(vertex2)\n    \n    def __str__(self):\n        return \"Edge \" + str(self.vertex1) + \" \" + str(self.vertex2) + \" Weight-\" + str(self.weight)\n\n    def __repr__(self):\n        return self.__str__()\n    \nclass Vertex(object):\n\n    def __init__(self, id):\n        self.id = id;\n        self.edges = []\n        self.adjacent_vertices = []\n\n    def add_adjacent_vertex(self, edge, vertex):\n        self.edges.append(edge)\n        self.adjacent_vertices.append(vertex)\n\n    def get_degree(self):\n        return len(self.edges)\n\n    def __eq__(self, other):\n        return self.id == other.id\n\n    def __hash__(self):\n        return hash(self.id)\n\n    def __str__(self):\n        return str(\"Vertex-\" + str(self.id))\n\n    def __repr__(self):\n        return self.__str__();\n\n    def __lt__(self, other):\n        return self.id < other.id\n                    \n    def __gt__(self, other):\n        return self.id > other.id\n\nif __name__ == '__main__':            \n    g = Graph(False)\n    g.add_edge(1,2,10)\n    g.add_edge(2,3,5)\n    g.add_edge(1,4,6)\n\n    for edge in g.all_edges:\n        print(edge)\n\n    for vertex in g.all_vertex:\n        print(\"Vertex \" + str(g.all_vertex[vertex]))\n        for edge in g.all_vertex[vertex].edges:\n            print(\"Edge \" + str(edge))\n\n"
  },
  {
    "path": "python/graph/graphtraversal.py",
    "content": "#doing BFS and DFS traversal of the graph\n# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/GraphTraversal.java\n\nfrom graph import *\nimport queue\n\ndef dfs_util(v, visited):\n    if v in visited:\n        return\n    visited.add(v)\n    print(v)\n    for vertex in v.adjacent_vertices:\n        dfs_util(vertex, visited)\n        \ndef dfs(graph):\n    visited = set()\n    for id in graph.all_vertex:\n        dfs_util(graph.all_vertex[id], visited)\n\ndef bfs(graph):\n    q = queue.Queue()\n    visited = set()\n    for vertex in graph.all_vertex.values():\n        if vertex not in visited:\n            q.put(vertex)\n            visited.add(vertex)\n            while not q.empty():\n                v = q.get();\n                print(v)\n                for adj in v.adjacent_vertices:\n                    if adj not in visited:\n                        q.put(adj)\n                        visited.add(adj)\n                    \n                \nif __name__ == '__main__':   \n    g = Graph(False)\n    g.add_edge(1,2,10)\n    g.add_edge(2,3,5)\n    g.add_edge(1,4,6)\n\n    dfs(g)\n    bfs(g)\n"
  },
  {
    "path": "python/graph/kruskalmst.py",
    "content": "# kruskal minimum spanning tree\n# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/KruskalMST.java\n\nfrom disjointset import *\nfrom graph import *\n\ndef get_key(edge):\n    return edge.weight\n\ndef minimum_spanning_tree(graph):\n\n    disjoint_set = DisjointSet()\n    sorted_edges = sorted(graph.all_edges, key = get_key)\n    print(sorted_edges)\n\n    for vertex in graph.all_vertex.values():\n        disjoint_set.make_set(vertex.id)\n\n    result_edge = []\n\n    for edge in sorted_edges:\n        root1 = disjoint_set.find_set(edge.vertex1.id)\n        root2 = disjoint_set.find_set(edge.vertex2.id)\n\n        if root1 == root2:\n            continue\n        else:\n            result_edge.append(edge)\n            disjoint_set.union(edge.vertex1.id, edge.vertex2.id)\n\n    return result_edge\n\nif __name__ == '__main__':\n    graph = Graph(False)\n    graph.add_edge(1,3,1)\n    graph.add_edge(1,2,4)\n    graph.add_edge(2,4,2)\n    graph.add_edge(2,5,1)\n    graph.add_edge(2,6,3)\n    graph.add_edge(3,4,5)\n    graph.add_edge(3,7,8)\n    graph.add_edge(4,7,2)\n    graph.add_edge(6,5,2)\n    graph.add_edge(6,4,3)\n\n    result = minimum_spanning_tree(graph)\n    for edge in result:\n        print(edge)\n    \n"
  },
  {
    "path": "python/graph/primmst.py",
    "content": "#Prim's MST\n# Java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/PrimMST.java\n\nfrom graph import Graph\nfrom priorityqueue import PriorityQueue\nimport sys\n\ndef minimum_spanning_tree(graph):\n\n    min_heap = PriorityQueue(True)\n    vertex_to_edge = {}\n    result = []\n\n    for vertex in graph.all_vertex.values():\n        min_heap.add_task(sys.maxsize, vertex)\n    \n    start_vertex = next(iter((graph.all_vertex.values())))\n    min_heap.change_task_priority(0, start_vertex)\n    while min_heap.is_empty() is False:\n        current = min_heap.pop_task()\n        \n        if(current in vertex_to_edge):\n            spanning_tree_edge = vertex_to_edge[current]\n            result.append(spanning_tree_edge)\n\n        for edge in current.edges:\n            adjacent = get_other_vertex_for_edge(current, edge)\n            if min_heap.contains_task(adjacent) is True and min_heap.get_task_priority(adjacent) > edge.weight:\n                   min_heap.change_task_priority(edge.weight, adjacent)\n                   vertex_to_edge[adjacent] = edge\n                   \n    return result\n\n\ndef get_other_vertex_for_edge(vertex, edge):\n    if edge.vertex1.id == vertex.id:\n        return edge.vertex2\n    else:\n        return edge.vertex1\n\nif __name__ == '__main__':\n    graph = Graph(False)\n    graph.add_edge(1,2,3)\n    graph.add_edge(2,3,1)\n    graph.add_edge(3,1,1)\n    graph.add_edge(1,4,1)\n    graph.add_edge(2,4,3)\n    graph.add_edge(4,5,6)\n    graph.add_edge(5,6,2)\n    graph.add_edge(3,5,5)\n    graph.add_edge(3,6,4)\n    \n    result = minimum_spanning_tree(graph)\n    print(result)    \n"
  },
  {
    "path": "python/graph/priorityqueue.py",
    "content": "# add to heapq things like removing any item and changing key value\n# implementation of priority queue to support contains, change_task_priority\n# and remove_task in log time\n\nfrom heapq import *\n\nclass PriorityQueue(object):\n    \n    def __init__(self, is_min_heap):\n        self.pq = []\n        self.entry_finder = {}\n        if(is_min_heap is True):\n            self.mul = 1\n        else :\n            self.mul = -1\n         \n    def contains_task(self, task):\n        if task in self.entry_finder:\n            return True\n        else:\n            return False\n\n    def get_task_priority(self, task):\n        if task in self.entry_finder:\n            return (self.entry_finder[task])[0]\n        raise ValueError(\"task does not exist\")\n        \n    def add_task(self, priority, task):\n        if task in self.entry_finder:\n            raise KeyError(\"Key already exists\")\n        entry = [self.mul*priority, False, task]\n        self.entry_finder[task] = entry\n        heappush(self.pq, entry)\n\n    def change_task_priority(self, priority, task):\n        if task not in self.entry_finder:\n            raise KeyError(\"Task not found\")\n        self.remove_task(task)\n        entry = [self.mul*priority, False, task]\n        self.entry_finder[task] = entry\n        heappush(self.pq, entry)\n \n    def remove_task(self, task):\n        entry = self.entry_finder.pop(task)\n        entry[1] = True\n\n    def pop_task(self):\n        while self.pq:\n            priority, removed, task = heappop(self.pq)\n            if removed is False:\n                del self.entry_finder[task]\n                return task\n        raise KeyError(\"pop from an empty priority queue\")\n\n    def peek_task(self):\n        while self.pq:\n            priority, removed, task = tuple(heappop(self.pq))\n            if removed is False:\n                 heappush(self.pq, [priority, False, task])\n                 return task\n        raise KeyError(\"pop from an empty priority queue\")\n\n    def is_empty(self):\n        try:\n            self.peek_task()\n            return False\n        except KeyError:\n            return True\n\n    def __str__(self):\n        return str(self.entry_finder) + \" \" + str(self.pq)\n        \n\nif __name__ == '__main__':\n    task1 = \"Tushar\"\n    task2 = \"Roy\"\n    task3 = \"is\"\n    task4 = \"coder\"\n\n    min_pq = PriorityQueue(True)\n    min_pq.add_task(1, task1)\n    min_pq.add_task(3, task2)\n    min_pq.add_task(6, task3)\n    min_pq.add_task(7, task4)\n    print(min_pq.contains_task(task3))\n    print(min_pq.get_task_priority(task3))\n    print(min_pq)\n    while min_pq.is_empty() is False:\n        print(min_pq.pop_task())\n\n    max_pq = PriorityQueue(False)\n    max_pq.add_task(1, task1)\n    max_pq.add_task(3, task2)\n    max_pq.add_task(6, task3)\n    max_pq.add_task(7, task4)\n    while max_pq.is_empty() is False:\n        print(max_pq.pop_task())\n\n        \n"
  },
  {
    "path": "python/graph/topologicalsort.py",
    "content": "#topological sort\n# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/TopologicalSort.java\n\nfrom graph import Graph\n\ndef top_sort(graph):\n    stack = []\n    visited = set()\n    for vertex in graph.all_vertex.values():\n        if vertex in visited:\n            continue\n        top_sort_util(vertex, stack, visited)\n    return stack\n\ndef top_sort_util(vertex, stack, visited):\n    visited.add(vertex)\n    for adjacent in vertex.adjacent_vertices:\n        if adjacent in visited:\n            continue\n        top_sort_util(adjacent, stack, visited)\n    stack.append(vertex)\n\nif __name__ == '__main__':\n    graph = Graph(True)\n    graph.add_edge(1,3)\n    graph.add_edge(1,2)\n    graph.add_edge(3,4)\n    graph.add_edge(5,6)\n    graph.add_edge(6,3)\n    graph.add_edge(3,8)\n    graph.add_edge(8,11)\n\n    stack = top_sort(graph)\n\n    print(stack[::-1])\n\n     \n            \n"
  },
  {
    "path": "python/recursion/setpairtogether.py",
    "content": "# http://www.geeksforgeeks.org/minimum-number-of-swaps-required-for-arranging-pairs-adjacent-to-each-other/\n\ndef find_minimum_swaps(input, pair):\n    index = {}\n    for i, val in enumerate(input):\n        index[val] = i\n    return find_minimum_swaps_util(input, pair, index, 0)\n\ndef find_minimum_swaps_util(input, pair, index, current):\n    if current == len(input):\n        return 0\n\n    v1 = input[current]\n    v2 = input[current + 1]\n    pv2 = pair[v1]\n\n    if pv2 == v2:\n        return find_minimum_swaps_util(input, pair, index, current + 2)\n    else:\n        idx1 = index.get(v1)\n        idx2 = index.get(v2)\n        idx3 = index.get(pair[v1])\n        idx4 = index.get(pair[v2])\n\n        swap(index, input, idx2, idx3)\n        val1 = find_minimum_swaps_util(input, pair, index, current+2)\n        swap(index, input, idx2, idx3)\n\n        swap(index, input, idx1, idx4)\n        val2 = find_minimum_swaps_util(input, pair, index, current+2)\n        swap(index, input, idx1, idx4)\n\n        return 1 + max(val1, val2)\n        \n\ndef swap(index, input, i, j):\n    index[input[i]] = j\n    index[input[j]] = i\n    t = input[i]\n    input[i] = input[j]\n    input[j] = t\n\nif __name__ == '__main__':\n    input = [3, 5, 6, 4, 1, 2]\n    pair = {}\n    pair[1] = 3\n    pair[3] = 1\n    pair[2] = 6\n    pair[6] = 2\n    pair[4] = 5\n    pair[5] = 4\n\n    print(find_minimum_swaps(input, pair))\n    \n"
  },
  {
    "path": "python/recursion/stringpermutation.py",
    "content": "# string permutation in lexicographically order with repetition of characters in the string\n\ndef permute(input):\n    count_map = {}\n    for ch in input:\n        if ch in count_map.keys():\n            count_map[ch] = count_map[ch] + 1\n        else:\n            count_map[ch] = 1\n\n    keys = sorted(count_map)\n    str = []\n    count = []\n    for key in keys:\n        str.append(key)\n        count.append(count_map[key])\n    result = [0 for x in range(len(input))]\n    permute_util(str, count, result, 0)\n\ndef permute_util(str, count, result, level):\n    if level == len(result):\n        print(result)\n        return\n\n    for i in range(len(str)):\n        if count[i] == 0:\n            continue;\n        result[level] = str[i]\n        count[i] -= 1\n        permute_util(str, count, result, level + 1)\n        count[i] += 1\n\nif __name__ == '__main__':\n    input = ['B', 'C', 'A', 'A']\n    permute(input)\n"
  },
  {
    "path": "python/string/Z_Algorithm.py",
    "content": "#author: Pankaj Kumar\n\n#time complexity: O(length(string) + length(pattern))\n\n#space complexity: O(length(string) + length(pattern))\n\n#Link to theory: http://www.geeksforgeeks.org/z-algorithm-linear-time-pattern-searching-algorithm/\n\ndef z_algo(arr):\n    z = [0 for i in range(len(arr))]\n    left , right = 0 , 0\n    for k in range(1 , len(arr)):\n        if k > right:\n            left = k\n            right = k\n            while right < len(arr) and arr[right] == arr[right-left]:\n                right += 1\n            z[k] = right - left\n            right -= 1\n        else:\n            k1 = k - left\n            if z[k1] < right - k + 1:\n                z[k] = z[k1]\n            else:\n                left = k\n                while right < len(arr) and arr[right] == arr[right-left]:\n                    right += 1\n                z[k] = right - left\n                right -= 1\n    return z\n                \n            \ndef makepattern(string , pattern):\n    n , m = len(string) , len(pattern)\n    str_arr = []\n    for i in range(m):\n        str_arr.append(pattern[i])\n    str_arr.append('$')\n    for i in range(n):\n        str_arr.append(string[i])\n        \n    z_values = z_algo(str_arr)\n    result = []\n    for i in range(len(z_values)):\n        if z_values[i] == m:\n            result.append(i - m - 1)\n    print result\n\n\n\nif __name__ == '__main__':\n    string = 'abcdeabcd'\n    pattern = 'abc'\n    makepattern(string , pattern)\n"
  },
  {
    "path": "python/string/knuthmorrispratt.py",
    "content": "#  Knuth-Morris-Pratt algorithm \n\n\n# Compute temporary array to maintain size of suffix which is same as prefix\n# Time/space complexity is O(size of pattern)\ndef compute_temporary_array(pattern):\n    n = len(pattern)\n    lsp = [0 for j in range(n)]\n    index = 0\n    i = 1\n    while i < len(pattern):\n        if pattern[i] == pattern[index]:\n            lsp[i] = index + 1\n            index += 1\n            i += 1\n        else:\n            if index != 0:\n                index = lsp[index - 1]\n            else:\n                lsp[i] = 0\n                i += 1\n    return lsp\n\n\n# KMP algorithm of pattern matching.\ndef kmp(text, pattern):\n    lsp = compute_temporary_array(pattern)\n    i = 0\n    j = 0\n    while i < len(text) and j < len(pattern):\n        if text[i] == pattern[j]:\n            i += 1\n            j += 1\n        else:\n            if j != 0:\n                j = lsp[j - 1]\n            else:\n                i += 1\n    if j == len(pattern):\n        return True\n    else:\n        return False\n\nsrc = 'abcxabcdabcdabcy'\nsub_string = 'abcdabcy'\nresult = kmp(src, sub_string)\nprint(result)\n\n\n"
  },
  {
    "path": "python/string/rabinkarp.py",
    "content": "#Rabin Karp algorithm\n# Java code https://github.com/mission-peace/interview/blob/master/src/com/interview/string/RabinKarpSearch.java\n\nprime = 101\ndef pattern_matching(text, pattern):\n    m = len(pattern)\n    n = len(text)\n    pattern_hash = create_hash(pattern, m - 1)\n    text_hash = create_hash(text, m - 1)\n\n    for i in range(1, n - m + 2):\n        if pattern_hash == text_hash:\n            if check_equal(text[i-1:i+m-1], pattern[0:]) is True:\n                return i - 1;\n        if i < n - m + 1:    \n            text_hash = recalculate_hash(text, i-1, i+m-1, text_hash, m)\n    return -1;\n    \ndef check_equal(str1, str2):\n    if len(str1) != len(str2):\n        return False;\n    i = 0\n    j = 0\n    for i, j in zip(str1, str2):\n        if i != j:\n            return False;\n    return True\n    \ndef create_hash(input, end):\n    hash = 0\n    for i in range(end + 1):\n        hash = hash + ord(input[i])*pow(prime, i)\n    return hash\n\ndef recalculate_hash(input, old_index, new_index, old_hash, pattern_len):\n    new_hash = old_hash - ord(input[old_index])\n    new_hash = new_hash/prime\n    new_hash += ord(input[new_index])*pow(prime, pattern_len - 1)\n    return new_hash;\n\n\nindex = pattern_matching(\"TusharRoy\", \"sharRoy\")\nprint(\"Index \", index)\nindex = pattern_matching(\"TusharRoy\", \"Roy\")\nprint(\"Index \", index)\nindex = pattern_matching(\"TusharRoy\", \"shar\")\nprint(\"Index \", index)\nindex = pattern_matching(\"TusharRoy\", \"usha\")\nprint(\"Index \", index)\nindex = pattern_matching(\"TusharRoy\", \"Tus\")\nprint(\"Index \", index)\nindex = pattern_matching(\"TusharRoy\", \"Roa\")\nprint(\"Index \", index)\n"
  },
  {
    "path": "python/tree/binary_tree.py",
    "content": "from collections import namedtuple\n\nColor = namedtuple(\"Color\", \"RED BLACK\")\n\n\nclass Node:\n    def __init__(self):\n        self.color = None\n        self.height = None\n        self.lis = None\n        self.data = None\n        self.size = None\n        self.next = None\n        self.right = None\n        self.left = None\n\n    @staticmethod\n    def newNode(data):\n        n = Node()\n        n.data = data\n        n.lis = -1\n        n.height = 1\n        n.size = 1\n        n.color = Color.RED\n        return n\n\n\nclass BinaryTree:\n\n    def __init__(self):\n        pass\n\n    @staticmethod\n    def add_head(data, head):\n        temp_head = head\n        n = Node.newNode(data)\n\n        if head is None:\n            head = n\n            return head\n\n        prev = None\n\n        while head is not None:\n            prev = head\n            if head.data < data:\n                head = head.right\n            else:\n                head = head.left\n\n        if prev.data < data:\n            prev.right = n\n        else:\n            prev.left = n\n\n        return temp_head\n"
  },
  {
    "path": "python/tree/construct_tree_from_inorder_preorder.py",
    "content": "from binary_tree import Node\n\n\nclass ConstructTreeFromInorderPreOrder:\n    def __init__(self):\n        self.index = 0\n\n    def _createTree(self, inorder, preorder, start, end):\n        if start > end:\n            return None\n        i = 0\n        for i in range(start, end + 1):\n            if preorder[self.index] == inorder[i]:\n                break\n\n        node = Node.newNode(preorder[self.index])\n        self.index += 1\n        node.left = self._createTree(inorder, preorder, start, i - 1)\n        node.right = self._createTree(inorder, preorder, i + 1, end)\n        return node\n\n    def createTree(self, inorder, preorder):\n        return self._createTree(inorder, preorder, 0, len(inorder) - 1)\n"
  },
  {
    "path": "python/tree/fenwick_tree.py",
    "content": "#################################################################################################################################\n#Implementation of Binary Indexed Tree OR Fenwick Tree\n#Time Complexities:\n#\tConstruction of Tree: O (n.log (n))\n#\tUpdating an element: O (log (n))\n#\tPrefix Query (sum of elements 0 to i) or Range Minimum Query (sum of elements x to y): O (log (n))\n#Space Complexity: O (n)\n#################################################################################################################################\n\nclass FenTree (object):\n\tdef __init__ (self, array):\n\t\tself.array, self.tree = [0] * len (array), [0] * (len (array) + 1);\n\t\tfor i in range (len (array)):\n\t\t\tself.update (i, array [i]);\n\n\tdef get_parent (self, child):\n\t\treturn (child - (child & -child));\n\n\tdef get_next (self, index):\n\t\treturn (index + (index & -index));\n\n\tdef update (self, index, item):\n\t\tcurrent, self.array [index] = self.array [index], item;\n\t\titem -= current;\n\t\tindex += 1;\n\t\twhile (index <= len (self.array)):\n\t\t\tself.tree [index] += item;\n\t\t\tindex = self.get_next (index);\n\n\tdef prefix_sum (self, index):\n\t\tindex += 1;\n\t\ttotal = 0;\n\t\twhile (index > 0):\n\t\t\ttotal += self.tree [index];\n\t\t\tindex = self.get_parent (index);\n\t\treturn (total);\n\n\tdef range_sum (self, x, y):\n\t\treturn (self.prefix_sum (max (x, y)) - self.prefix_sum (min (x, y) - 1));\n\n\tdef describe (self):\n\t\tprint ('ARRAY =>\\t', self.array);\n\t\tprint ('Binary Indexed Tree =>\\t', self.tree);\n\nif (__name__ == '__main__'):\n\ttree = FenTree ([3,2,-1,6,5,4]);\n#\ttree = FenTree ([int (i) for i in input ('Enter the array (space-separated integers): ').split ()]);\n\ttree.describe ();\n\n\ttree.update (4, 8);\t#replaces 5 with 8 in the list given to the fenwick tree\n\ttree.describe ();\n\n\tprint (tree.range_sum (1, 5));\t#returns 2-1+6+5+4\n\tprint (tree.prefix_sum (5));\t#returns 3+2-1+6+5+4\n"
  },
  {
    "path": "python/tree/largest_bst_in_binary_tree.py",
    "content": "\"\"\" Given a binary tree, find size of largest binary search subtree in this binary tree.\n\nApproach\n--------\n\nTraverse tree in post order fashion. Left and right nodes return 4 piece of information to root which isBST, size of max\nBST, min and max in those subtree.\n\nIf both left and right subtree are BST and this node data is greater than max of left and less than min of right then it\nreturns to above level left size + right size + 1 and new min will be min of left side and new max will be max of right\nside.\n\nVideo link\n----------\n* https://youtu.be/4fiDs7CCxkc\n\nReferences\n----------\n* http://www.geeksforgeeks.org/find-the-largest-subtree-in-a-tree-that-is-also-a-bst/\n* https://leetcode.com/problems/largest-bst-subtree/\n* http://www.geeksforgeeks.org/construct-tree-from-given-inorder-and-preorder-traversal/\n\"\"\"\n\nfrom construct_tree_from_inorder_preorder import ConstructTreeFromInorderPreOrder\n\nclass MinMax:\n\n    def __init__(self):\n        self.min = float(\"inf\")\n        self.max = float(\"-inf\")\n        self.isBST = True\n        self.size = 0\n\n\nclass LargestBSTBinaryTree:\n\n    def largestBST(self, root):\n        m = self.largest(root)\n        return m.size\n\n    def largest(self, root):\n\n        if root is None:\n            return MinMax()\n\n        leftMinMax = self.largest(root.left)\n        rightMinMax = self.largest(root.right)\n\n        m = MinMax()\n\n        if ((leftMinMax.isBST == False or rightMinMax.isBST == False)\n            or (leftMinMax.max > root.data  or rightMinMax.min <= root.data)):\n\n            m.isBST = False\n            m.size = max(leftMinMax.size, rightMinMax.size)\n            return m\n\n        m.isBST = True\n        m.size = leftMinMax.size + rightMinMax.size + 1\n        m.min = leftMinMax.min if root.left is not None else root.data\n        m.max = rightMinMax.max if root.right is not None else root.data\n        return m\n\n\nif __name__ == '__main__':\n    lbi = LargestBSTBinaryTree()\n    ctf = ConstructTreeFromInorderPreOrder()\n    inorder  = [-7, -6, -5, -4, -3, -2, 1, 2, 3, 16, 6, 10, 11, 12, 14]\n    preorder = [3, -2, -3, -4, -5, -6, -7, 1, 2, 16, 10, 6, 12, 11, 14]\n    root = ctf.createTree(inorder, preorder)\n    largestBSTSize = lbi.largestBST(root)\n    print \"Size of the largest BST in the Binary Tree is \", largestBSTSize\n    assert 8 == lbi.largestBST(root)\n"
  },
  {
    "path": "python/tree/max_depth_binary_tree.py",
    "content": "\"\"\"\nProblem Statement\n=================\n\nGiven a binary tree, write a program to find the maximum depth at any given node.\n\nFor e.g, for this binary tree.\n\n  1\n / \\\n2   3\n   / \\\n  4   5\n\nThe height at 1 is 3, and the height at 3 is 2.\n\n\"\"\"\n\nclass Node:\n    def __init__(self, value):\n        self.value = value\n        self.left = None\n        self.right = None\n\n\nn1 = Node(1)\nn2 = Node(2)\nn3 = Node(3)\nn4 = Node(4)\nn5 = Node(5)\n\n# construct the tree as given in the problem.\n\nn1.left = n2\nn1.right = n3\nn3.left = n4\nn3.right = n5\n\n\ndef find_max_depth(n):\n    if n is None:\n        return 0\n    left_height = find_max_depth(n.left)\n    right_height = find_max_depth(n.right)\n    if left_height > right_height:\n        result = left_height + 1\n    else:\n        result = right_height + 1\n    return result\n\n\nif __name__ == '__main__':\n    assert 3 == find_max_depth(n1)\n    assert 2 == find_max_depth(n3)\n"
  },
  {
    "path": "python/tree/morris_traversal.py",
    "content": "\"\"\"Morris Traversal of a Binary Tree.\n\nVideo\n-----\n\n* https://youtu.be/wGXB9OWhPTg\n\nAnalysis\n--------\n\n* Time complexity O(n)\n* Space complexity O(1)\n\n\"\"\"\n\nfrom binary_tree import BinaryTree\n\n\nclass MorrisTraversal:\n\n    def __init__(self):\n        pass\n\n    @staticmethod\n    def find_predecessor(current):\n        predecessor = current.left\n        while predecessor.right != current and predecessor.right is not None:\n            predecessor = predecessor.right\n        return predecessor\n\n    @staticmethod\n    def inorder(root_node):\n        current = root_node\n        while current is not None:\n            if current.left is None:\n                print \"{data} \".format(data=current.data),\n                current = current.right\n            else:\n                predecessor = MorrisTraversal.find_predecessor(current)\n\n                if predecessor.right is None:\n                    predecessor.right = current\n                    current = current.left\n                else:\n                    predecessor.right = None\n                    print \"{data} \".format(data=current.data),\n                    current = current.right\n\n    @staticmethod\n    def preorder(root_node):\n        current = root_node\n        while current is not None:\n            if current.left is None:\n                print \"{data} \".format(data=current.data),\n                current = current.right\n            else:\n                predecessor = MorrisTraversal.find_predecessor(current)\n\n                if predecessor.right is None:\n                    print \"{data} \".format(data=current.data),\n                    predecessor.right = current\n                    current = current.left\n                else:\n                    predecessor.right = None\n                    current = current.right\n\n\nif __name__ == '__main__':\n    bt = BinaryTree()\n    root = None\n    root = bt.add_head(10, root)\n    root = bt.add_head(50, root)\n    root = bt.add_head(-10, root)\n    root = bt.add_head(7, root)\n    root = bt.add_head(9, root)\n    root = bt.add_head(-20, root)\n    root = bt.add_head(30, root)\n\n    mt = MorrisTraversal()\n    mt.inorder(root)\n    print \"\\n\",\n    mt.preorder(root)\n"
  },
  {
    "path": "python/tree/segmenttreesum.py",
    "content": "def create_segment_tree(input):\n    size = next_power_of_2(len(input));\n    segment_tree = [0 for x in range(2*size - 1)]\n    construct_tree(segment_tree, input, 0, len(input) - 1, 0)\n    return segment_tree\n\ndef construct_tree(segment_tree, input, low, high, pos):\n    if low == high:\n        segment_tree[pos] = input[low]\n        return\n\n    mid = (low + high)/2\n    construct_tree(segment_tree, input, low, mid, 2*pos + 1)\n    construct_tree(segment_tree, input, mid + 1, high, 2*pos + 2)\n    segment_tree[pos] = segment_tree[2*pos+1] + segment_tree[2*pos+2]\n\ndef sum_range_query(segment_tree, q_low, q_high, len):\n    return sum_range_query_util(segment_tree, 0, len - 1, q_low, q_high, 0)\n\ndef sum_range_query_util(segment_tree, low, high, q_low, q_high, pos):\n    if q_low <= low and q_high >= high:\n        return segment_tree[pos]\n\n    if q_high < low or q_low > high:\n        return 0\n\n    mid = (low + high)/2\n    return sum_range_query_util(segment_tree, low, mid, q_low, q_high, 2*pos + 1)\\\n           + sum_range_query_util(segment_tree, mid + 1, high, q_low, q_high, 2*pos + 2)\n\ndef update_value(input, segment_tree, new_value, index):\n    diff = new_value - input[index]\n    input[index] = new_value\n    update_value_util(segment_tree, 0, len(input)-1, diff, index, 0)\n\ndef update_value_util(segment_tree, low, high, diff, index, pos):\n    if low > index or high < index:\n        return\n    segment_tree[pos] += diff\n\n    if low >= high:\n        return\n    mid = (low + high)/2\n    update_value_util(segment_tree, low, mid, diff, index, 2*pos + 1)\n    update_value_util(segment_tree, mid + 1, high, diff, index, 2*pos + 2)\n\n\ndef next_power_of_2(n):\n    if n == 0:\n        return 1\n    if n & (n - 1) == 0:\n        return n\n    while n & (n - 1) > 0:\n        n &= (n - 1)\n\n    return n << 1\n\nif __name__ == '__main__':\n    input = [1,3,5,7,9,11]\n    segment_tree = create_segment_tree(input)\n    print(segment_tree)\n    print(sum_range_query(segment_tree, 2, 5, len(input)))\n    print(sum_range_query(segment_tree, 1, 3, len(input)))\n    update_value(input, segment_tree, 4, 3)\n    print(sum_range_query(segment_tree, 2, 5, len(input)))\n    print(sum_range_query(segment_tree, 1, 3, len(input)))\n\n\n"
  },
  {
    "path": "src/com/interview/array/AdditiveNumber.java",
    "content": "package com.interview.array;\n\nimport java.math.BigInteger;\n\n/**\n * Date 04/24/2016\n * @author Tushar Roy\n *\n * Additive number is a string whose digits can form additive sequence.\n * A valid additive sequence should contain at least three numbers.\n * Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two.\n *\n * https://leetcode.com/problems/additive-number/\n */\npublic class AdditiveNumber {\n\n    public boolean isAdditiveNumber(String num) {\n        if (num.length() < 3) {\n            return false;\n        }\n        for (int i = 0; i <= num.length()/2; i++) {\n            if (num.charAt(0) == '0' && i > 0) {\n                break;\n            }\n            BigInteger x1 = new BigInteger(num.substring(0, i + 1));\n            //make sure remaining size is at least size of first and second integer.\n            for (int j = i + 1; Math.max(i, j - (i + 1)) + 1 <= num.length() - j - 1 ; j++) {\n                if (num.charAt(i + 1) == '0' && j > i + 1) {\n                    break;\n                }\n                BigInteger x2 = new BigInteger(num.substring(i + 1, j + 1));\n                if (isValid(num, j + 1, x1, x2)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private boolean isValid(String num, int start, BigInteger x1, BigInteger x2) {\n        if (start == num.length()) {\n            return true;\n        }\n        BigInteger x3 = x1.add(x2);\n        //if num starts with x3 from offset start means x3 is found. So look for next number.\n        return num.startsWith(x3.toString(), start) && isValid(num, start + x3.toString().length(), x2, x3);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/ArrayAddition.java",
    "content": "package com.interview.array;\n\npublic class ArrayAddition {\n\n    public int[] add(int arr1[], int arr2[]){\n        int l = Math.max(arr1.length, arr2.length);\n        int[] result = new int[l];\n        int c=0;\n        int i = arr1.length-1;\n        int j= arr2.length-1;\n        int r=0;\n        l--;\n        while(i >=0 && j >=0){\n            r = arr1[i--] + arr2[j--] + c;\n            c = r/10;\n            result[l--] = r%10;\n        }\n        while(i>=0){\n            r = arr1[i--] + c;\n            c = r/10;\n            result[l--] = r%10;\n        }\n        while(j>=0){\n            r = arr2[j--] + c;\n            c = r/10;\n            result[l--] = r%10;\n        }\n        if(c != 0){\n            int[] newResult = new int[result.length+1];\n            for(int t= newResult.length-1; t> 0; t--){\n                newResult[t] = result[t-1];\n            }\n            newResult[0] = c;\n            return newResult;\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        \n        int arr1[] = {9,9,9,9,9,9,9};\n        int arr2[] = {1,6,8,2,6,7};\n        ArrayAddition aa = new ArrayAddition();\n        int result[] = aa.add(arr1, arr2);\n        for(int i=0; i < result.length; i++){\n            System.out.print(\" \" + result[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/BestMeetingPoint.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Date 03/24/2016\n * @author Tushar Roy\n *\n * A group of two or more people wants to meet and minimize the total travel distance.\n * You are given a 2D grid of values 0 or 1, where each 1 marks the home of someone in the group.\n * The distance is calculated using Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.\n * Find the total distance that needs to be travelled to reach this meeting point.\n *\n * Time complexity O(m*n)\n * Space complexity O(m + n)\n *\n * https://leetcode.com/problems/best-meeting-point/\n */\npublic class BestMeetingPoint {\n    public int minTotalDistance(int[][] grid) {\n        if (grid.length == 0 || grid[0].length == 0) {\n            return 0;\n        }\n        List<Integer> vertical = new ArrayList<>();\n        List<Integer> horizontal = new ArrayList<>();\n\n        for (int i = 0; i < grid.length; i++) {\n            for (int j = 0; j < grid[0].length; j++) {\n                if (grid[i][j] == 1) {\n                    vertical.add(i);\n                    horizontal.add(j);\n                }\n            }\n        }\n\n        Collections.sort(vertical);\n        Collections.sort(horizontal);\n\n        int size = vertical.size()/2;\n        int x = vertical.get(size);\n        int y = horizontal.get(size);\n        int distance = 0;\n        for (int i = 0; i < grid.length; i++) {\n            for (int j = 0; j < grid[0].length; j++) {\n                if (grid[i][j] == 1) {\n                    distance += Math.abs(x - i) + Math.abs(y - j);\n                }\n            }\n        }\n\n        return distance;\n    }\n\n    public static void main(String args[]) {\n        BestMeetingPoint bmp = new BestMeetingPoint();\n        int[][] grid = {{1, 0, 0, 0, 1}, {0, 0, 0, 0, 0},{0, 0, 1, 0, 0}};\n        System.out.print(bmp.minTotalDistance(grid));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/BuySellStockProfit.java",
    "content": "package com.interview.array;\n\n/**\n * Date 03/04/2016\n * @author Tushar Roy\n *\n * Best time to buy and sell stocks.\n * 1) Only 1 transaction is allowed\n * 2) Infinite number transactions are allowed\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * https://leetcode.com/problems/best-time-to-buy-and-sell-stock/\n * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/\n */\npublic class BuySellStockProfit {\n\n    public int oneProfit(int arr[]){\n        int minPrice = arr[0];\n        int maxProfit = 0;\n        for(int i=1; i < arr.length; i++){\n            if(arr[i] - minPrice > maxProfit){\n                maxProfit = arr[i] - minPrice;\n            }\n            if(arr[i] < minPrice){\n                minPrice = arr[i];\n            }\n        }\n        return maxProfit;\n    }\n    \n    public int allTimeProfit(int arr[]){\n        int profit = 0;\n        for(int i=1; i < arr.length;i++){\n            if(arr[i-1] < arr[i]){\n                profit += arr[i] - arr[i-1];\n            }\n        }\n        return profit;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {7,10,15,5,11,2,7,9,3};\n        int arr1[] = {6,4,1,3,5,7,3,1,3,4,7,9,2,5,6,0,1,2};\n        BuySellStockProfit bss = new BuySellStockProfit();\n        System.out.println(bss.oneProfit(arr));\n        System.out.print(bss.allTimeProfit(arr1));\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/CheckIfArrayElementsAreConsecutive.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/check-if-array-elements-are-consecutive/\n */\npublic class CheckIfArrayElementsAreConsecutive {\n\n    public boolean areConsecutive(int input[]){\n        int min = Integer.MAX_VALUE;\n        for(int i=0; i < input.length; i++){\n            if(input[i] < min){\n                min = input[i];\n            }\n        }\n        for(int i=0; i < input.length; i++){\n            if(Math.abs(input[i]) - min >= input.length){\n                return false;\n            }\n            if(input[Math.abs(input[i]) - min] < 0){\n                return false;\n            }\n            input[Math.abs(input[i]) - min] = -input[Math.abs(input[i]) - min];\n        }\n        for(int i=0; i < input.length ; i++){\n            input[i] = Math.abs(input[i]);\n        }\n        return true;\n    }\n    \n    public static void main(String args[]){\n        int input[] = {76,78,76,77,73,74};\n        CheckIfArrayElementsAreConsecutive cia = new CheckIfArrayElementsAreConsecutive();\n        System.out.println(cia.areConsecutive(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/ChunkMerge.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.PriorityQueue;\n\n/**\n * Given a list of lists. Each element in the list is sorted. Sort the \n * entire list.\n * Test cases\n * One or more lists are empty\n * All elements in one list are smaller than all elements in another list\n */\npublic class ChunkMerge {\n    \n    class Triplet implements Comparable<Triplet>{\n        int pos;\n        int val;\n        int index;\n        @Override\n        public int compareTo(Triplet o) {\n            if(val <= o.val){\n                return -1;\n            }else{\n                return 1;\n            }\n        }\n    }\n    \n    public List<Integer> mergeUsingHeap(List<List<Integer>> chunks){\n        List<Integer> result = new ArrayList<Integer>();\n        PriorityQueue<Triplet> queue = new PriorityQueue<Triplet>();\n        //add first element of every chunk into queue\n        for(int i=0; i < chunks.size(); i++){\n            Triplet p = new Triplet();\n            p.pos = i;\n            p.val = chunks.get(i).get(0);\n            p.index = 1;\n            queue.add(p);\n        }\n        \n        while(!queue.isEmpty()){\n            Triplet p = queue.poll();\n            result.add(p.val);\n            if(p.index < chunks.get(p.pos).size()){\n                p.val = chunks.get(p.pos).get(p.index);\n                p.index += 1;\n                queue.add(p);\n            }\n        }\n        return result;\n    }\n    \n    public List<Integer> mergeChunksOfDifferentSize(List<List<Integer>> chunks){\n        List<Integer> result = new ArrayList<Integer>();\n\n        int sum[] = new int[chunks.size()+1];\n        sum[0] = 0;\n        for(int i =1; i < sum.length;i++){\n            sum[i] = sum[i-1] + chunks.get(i-1).size();\n        }\n        \n        for(List<Integer> chunk : chunks){\n            for(Integer i : chunk){\n                result.add(i);\n            }\n        }\n        mergeSort(result,0,chunks.size()-1,sum);\n        return result;\n    }\n\n    private void mergeSort(List<Integer> result,int start,int end,int sum[]){\n        if(start >= end){\n            return;\n        }\n        int mid = (start + end)/2;\n        mergeSort(result,start,mid,sum);\n        mergeSort(result,mid+1,end,sum);\n        sortedMerge(result,start,end,sum);\n    }\n\n    private void sortedMerge(List<Integer> result,int start,int end,int sum[]){\n        \n        /**\n         * If chunks are of equal size then\n         * i = size*start to (mid+1)*size -1\n         * j = (mid+1)*size to size*(end+1)\n         */\n        \n        int mid = (start + end)/2; \n        int i = sum[start];\n        int j = sum[mid+1];\n        List<Integer> temp = new ArrayList<Integer>();\n        while(i < sum[mid+1] && j < sum[end+1]){\n            if(result.get(i) < result.get(j)){\n                temp.add(result.get(i));\n                i++;\n            }else{\n                temp.add(result.get(j));\n                j++;\n            }\n        }\n        while(i < sum[mid+1]){\n            temp.add(result.get(i));\n            i++;\n        }\n        while(j < sum[end+1]){\n            temp.add(result.get(j));\n            j++;\n        }\n        int index = sum[start];\n        for(int k : temp){\n            result.set(index, k);\n            index++;\n        }\n    }\n    public static void main(String args[]){\n        Integer arr1[] = {1,5,6,9,21};\n        Integer arr2[] = {4,6,11,14};\n        Integer arr3[] = {-1,0,7};\n        Integer arr4[] = {-4,-2,11,14,18};\n        Integer arr5[] = {2,6};\n        Integer arr6[] = {-5,-2,1,5,7,11,14};\n        Integer arr7[] = {-6,-1,0,15,17,22,24};\n        \n        List<Integer> list1 = Arrays.asList(arr1);\n        List<Integer> list2 = Arrays.asList(arr2);\n        List<Integer> list3 = Arrays.asList(arr3);\n        List<Integer> list4 = Arrays.asList(arr4);\n        List<Integer> list5 = Arrays.asList(arr5);\n        List<Integer> list6 = Arrays.asList(arr6);\n        List<Integer> list7 = Arrays.asList(arr7);\n        \n        \n        List<List<Integer>> chunks = new ArrayList<List<Integer>>();\n        chunks.add(list1);\n        chunks.add(list2);\n        chunks.add(list3);\n        chunks.add(list4);\n        chunks.add(list5);\n        chunks.add(list6);\n        chunks.add(list7);\n        \n        ChunkMerge cm = new ChunkMerge();\n        List<Integer> result = cm.mergeChunksOfDifferentSize(chunks);\n        System.out.println(result.size());\n        for(Integer r : result){\n            System.out.print(r + \" \");\n        }\n        \n        result = cm.mergeUsingHeap(chunks);\n        System.out.println();\n        for(Integer r : result){\n            System.out.print(r + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/CommonThreeSortedArray.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 01/01/2016\n * @author Tushar Roy\n *\n * Given 3 sorted array find common elements in these 3 sorted array.\n *\n * Time complexity is O(m + n + k)\n *\n * http://www.geeksforgeeks.org/find-common-elements-three-sorted-arrays/\n */\npublic class CommonThreeSortedArray {\n\n    public List<Integer> commonElements(int input1[], int input2[], int input3[]) {\n        int i = 0;\n        int j = 0;\n        int k = 0;\n        List<Integer> result = new ArrayList<>();\n        while (i < input1.length && j < input2.length && k < input3.length) {\n            if (input1[i] == input2[j] && input2[j] == input3[k]) {\n                result.add(input1[i]);\n                i++;\n                j++;\n                k++;\n            } else if (input1[i] < input2[j]) {\n                i++;\n            } else if (input2[j] < input3[k]) {\n                j++;\n            } else {\n                k++;\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        int input1[] = {1, 5, 10, 20, 40, 80};\n        int input2[] = {6, 7, 20, 80, 100};\n        int input3[] = {3, 4, 15, 20, 30, 70, 80, 120};\n\n        CommonThreeSortedArray cts = new CommonThreeSortedArray();\n        List<Integer> result = cts.commonElements(input1, input2, input3);\n        result.forEach(i -> System.out.print(i + \" \"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/ConvertAnArrayIntoDecreaseIncreaseFashion.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n\n/**\n * Convert an unsorted array into an array such that\n * a < b > c < d > e < f and so on\n */\npublic class ConvertAnArrayIntoDecreaseIncreaseFashion {\n\n    public void convert(int arr[]){\n        int k = 0;\n        if(arr.length % 2 ==0){\n            k = arr.length/2 ;\n        }else{\n            k = arr.length/2+1;\n        }\n        KthElementInArray kthElement = new KthElementInArray();\n        kthElement.kthElement(arr, k);\n        \n        int high = k;\n        int low = 1;\n        while(low < high && high < arr.length){\n            swap(arr,low,high);\n            high++;\n            low += 2;\n        }\n        \n    }\n    \n    /**\n     * Sort the array first.\n     * Then swap every adjacent element to get final result\n     * @param arr\n     */\n    public void convert1(int arr[]){\n        Arrays.sort(arr);\n        for(int i=1; i < arr.length; i+=2){\n            if(i+1 < arr.length){\n                swap(arr, i, i+1);\n            }\n        }\n    }\n    \n    private void swap(int arr[],int low,int high){\n        int temp = arr[low];\n        arr[low] = arr[high];\n        arr[high] = temp;\n    }\n    \n    public static void main(String args[]){\n        ConvertAnArrayIntoDecreaseIncreaseFashion can = new ConvertAnArrayIntoDecreaseIncreaseFashion();\n        int arr[] = {0,6,9,13,10,-1,8,2,4,14,-5};\n        can.convert(arr);\n        for(int i=0; i < arr.length; i++){\n            System.out.print(arr[i] + \" \");\n        }\n        System.out.println();\n        int arr1[] = {0,6,9,13,10,-1,8,2,4,14,-5};\n        can.convert1(arr1);\n        for(int i=0; i < arr1.length; i++){\n            System.out.print(arr1[i] + \" \");\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/array/CountInversionOfSize3.java",
    "content": "package com.interview.array;\n\n/**\n * Date 12/29/15\n * @author Tushar Roy\n *\n * Given input array find number of inversions where i < j < k and input[i] > input[j] > input[k]\n *\n * http://www.geeksforgeeks.org/count-inversions-of-size-three-in-a-give-array/\n */\npublic class CountInversionOfSize3 {\n\n    /**\n     * Time complexity of this method is O(n^2)\n     * Space complexity is O(1)\n     */\n    public int findInversions(int input[]) {\n        int inversion = 0;\n        for (int i = 1; i < input.length - 1 ; i++) {\n            int larger = 0;\n            for (int k = 0; k < i; k++) {\n                if (input[k] > input[i]) {\n                    larger++;\n                }\n            }\n            int smaller = 0;\n            for (int k = i+1; k < input.length; k++) {\n                if (input[k] < input[i]) {\n                    smaller++;\n                }\n            }\n            inversion += smaller*larger;\n        }\n        return inversion;\n    }\n\n    public static void main(String args[]) {\n        int input[] = {9, 6, 4, 5, 8};\n        CountInversionOfSize3 ci = new CountInversionOfSize3();\n        System.out.print(ci.findInversions(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/CountSmallerOnRight.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 03/01/2016\n * @author Tushar Roy\n *\n * Count number of smaller elements on right side of an array for every element.\n *\n * Time complexity is O(nlogn)\n * Space complexity is O(n)\n *\n * https://leetcode.com/problems/count-of-smaller-numbers-after-self/\n */\npublic class CountSmallerOnRight {\n    static class NumberIndex {\n        int val;\n        int index;\n        NumberIndex(int val, int index) {\n            this.val = val;\n            this.index = index;\n        }\n    }\n\n    public List<Integer> countSmaller(int[] nums) {\n        if (nums.length == 0) {\n            return new ArrayList<>();\n        }\n        NumberIndex[] input = new NumberIndex[nums.length];\n        for (int i = 0; i < nums.length; i++) {\n            input[i] = new NumberIndex(nums[i], i);\n        }\n\n        int result[] = new int[nums.length];\n\n        mergeUtil(input, result, 0, input.length - 1);\n\n        List<Integer> r = new ArrayList<>();\n        for (int s : result) {\n            r.add(s);\n        }\n        return r;\n    }\n\n    private void mergeUtil(NumberIndex[] nums, int[] result, int low, int high) {\n        if (low == high) {\n            return;\n        }\n        int mid = (low + high)/2;\n        mergeUtil(nums, result, low, mid);\n        mergeUtil(nums, result, mid + 1, high);\n\n        int i = low;\n        int j = mid + 1;\n        NumberIndex[] t = new NumberIndex[high - low + 1];\n        int k = 0;\n        int tempResult[] = new int[high - low + 1];\n        while (i <= mid && j <= high) {\n            if (nums[i].val <= nums[j].val) {\n                tempResult[nums[i].index - low] = j - mid - 1;\n                t[k++] = nums[i++];\n            } else {\n                tempResult[nums[i].index - low] = j - mid;\n                t[k++] = nums[j++];\n            }\n        }\n        int i1= i;\n        while (i1 <= mid) {\n            tempResult[nums[i1].index - low] = j - mid - 1;\n            t[k++] = nums[i1++];\n        }\n\n        while (j <= high) {\n            t[k++] = nums[j++];\n        }\n\n        k = 0;\n        for (i = low; i <= high; i++) {\n            nums[i] = t[k];\n            result[i] += tempResult[k++];\n        }\n    }\n\n    public static void main(String args[]) {\n        CountSmallerOnRight csr = new CountSmallerOnRight();\n        int nums[] = {5, 2, 6, 1, 0, 3};\n        List<Integer> result = csr.countSmaller(nums);\n        result.forEach(r -> System.out.print(r + \" \"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/DivideNumbersInEqualGroupWithClosestSum.java",
    "content": "package com.interview.array;\n\n/**\n * This solution is incorrect. It is greedy approach which will not work\n * e.g 1,6,6,8,9,10 - Result should be 1,9,10 and 6,6,8 but it will not give this result\n * since it will greedily break 9 and 10 into different sets\n * \n * INCORRECT SOLUTION.(Still keeping the code in case I can improve it)\n * \n */\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class DivideNumbersInEqualGroupWithClosestSum {\n\n    public void divide(int arr[],List<Integer> list1, List<Integer> list2){\n        Arrays.sort(arr);\n        int len = arr.length;\n        int sum1 = 0;\n        int sum2 = 0;\n        for(int i = len-1 ; i >=0; i--){\n            if((sum1 < sum2 && list1.size() < len/2) || (list2.size() >= len/2)){\n                list1.add(arr[i]);\n                sum1 = sum1 + arr[i];\n            }else{\n                list2.add(arr[i]);\n                sum2 = sum2 + arr[i];\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        List<Integer> list1 = new ArrayList<Integer>();\n        List<Integer> list2 = new ArrayList<Integer>();\n        int arr[] = {15,14,13,1,3,2,};\n        int arr1[] = {23, 45, 34, 12,11, 98, 99, 4, 189, 1,7,19,105, 201};\n        \n        DivideNumbersInEqualGroupWithClosestSum dn = new DivideNumbersInEqualGroupWithClosestSum();\n        dn.divide(arr, list1, list2);\n        System.out.println(list1);\n        System.out.println(list2);\n        \n        list1.clear();\n        list2.clear();\n        dn.divide(arr1, list1, list2);\n        System.out.println(list1);\n        System.out.println(list2);\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/DuplicateNumberDetection.java",
    "content": "package com.interview.array;\n\n/**\n * Date 03/04/2016\n * @author Tushar Roy\n *\n * Given an array of size n + 1 with elements from 1 to n. One element is duplicated mulitiple times.\n * Find that element in O(1) space. Array cannot be changed.\n *\n * Reference\n * https://leetcode.com/problems/find-the-duplicate-number/\n */\npublic class DuplicateNumberDetection {\n    public int findDuplicate(int[] nums) {\n        if (nums.length == 0 || nums.length == 1) {\n            return -1;\n        }\n\n        int slow = nums[0];\n        int fast = nums[nums[0]];\n        while (slow != fast) {\n            slow = nums[slow];\n            fast = nums[nums[fast]];\n        }\n        fast = 0;\n        while (slow != fast) {\n            slow = nums[slow];\n            fast = nums[fast];\n        }\n\n        return fast;\n    }\n\n    public static void main(String args[]) {\n        int[] input = {2,1,3,4,3};\n        DuplicateNumberDetection dd = new DuplicateNumberDetection();\n        System.out.println(dd.findDuplicate(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/DuplicateWithinkIndices.java",
    "content": "package com.interview.array;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Write a function that determines whether a array contains duplicate \n * characters within k indices of each other\n */\npublic class DuplicateWithinkIndices {\n\n    public boolean duplicate(int arr[],int k){\n        Set<Integer> visited = new HashSet<Integer>();\n        for(int i=0; i < arr.length; i++){\n            if(visited.contains(arr[i])){\n                return true;\n            }\n            if(i >= k){\n                visited.remove(arr[i-k]);\n            }\n            visited.add(arr[i]);\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {1,2,3,11,2,5,6};\n        DuplicateWithinkIndices dk = new DuplicateWithinkIndices();\n        System.out.println(dk.duplicate(arr, 3));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/FindElementsOccurringNByKTimesTetris.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/given-an-array-of-of-size-n-finds-all-the-elements-that-appear-more-than-nk-times/\n * The reason this algorithm works is there can never be more than k-1 elements of size\n * more than n/k\n * \n * This question does not make much sense. Why not just use a map and keep count and\n * check if occurrence is more than n/k. This is way too much effort to find elements more than\n * n by k even though it saves some space.\n */\npublic class FindElementsOccurringNByKTimesTetris {\n\n    public static class Pair{\n        public int element;\n        public int count;\n    }\n    \n    public void printElementsOccurringKTimes(int arr[],int k){\n        Pair[] p = new Pair[k];\n        for(int i=0; i < k; i++){\n            p[i] = new Pair();\n        }\n        for(int i=0; i < arr.length; i++){\n            \n            int j=0;\n            for(j=0; j < k; j++){\n                if(p[j].element == arr[i]){\n                    p[j].count++;\n                    break;\n                }\n            }\n            \n            if(j == k){\n                int l=0;\n                for(l =0; l < k ; l++){\n                    if(p[l].count == 0){\n                        p[l].element = arr[i];\n                        p[l].count = 1;\n                        break;\n                    }\n                }\n                if(l == k){\n                    for(int t =0; t < k ; t++){\n                        p[t].count--;\n                    }\n                }\n            }\n        }\n        \n        for(int i=0; i < k ; i++){\n            if(p[i].count > 0){\n                int count =0;\n                for(int j=0; j < arr.length; j++){\n                    if(arr[j] == p[i].element){\n                        count++;\n                    }\n                }\n                if(count >= arr.length/k){\n                    System.out.println(p[i].element);\n                }\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {3,2,2,1,1,2,3,3,4,5,3,1};\n        FindElementsOccurringNByKTimesTetris fe = new FindElementsOccurringNByKTimesTetris();\n        fe.printElementsOccurringKTimes(arr, 3);\n    }\n\n    \n}\n"
  },
  {
    "path": "src/com/interview/array/FirstPositiveMissing.java",
    "content": "package com.interview.array;\n\n/**\n * https://leetcode.com/problems/first-missing-positive/\n */\npublic class FirstPositiveMissing {\n    public int firstMissingPositive(int[] nums) {\n        int startOfPositive = segregate(nums);\n        for (int i = startOfPositive; i < nums.length; i++) {\n            int index = Math.abs(nums[i]) + startOfPositive - 1;\n            if (index < nums.length) {\n                nums[index] = -Math.abs(nums[index]);\n            }\n        }\n        for (int i = startOfPositive; i < nums.length; i++) {\n            if (nums[i] > 0) {\n                return i - startOfPositive + 1;\n            }\n        }\n        return nums.length - startOfPositive + 1;\n    }\n\n    private int segregate(int[] nums) {\n        int start = 0;\n        int end = nums.length -1 ;\n        while (start <= end) {\n            if (nums[start] <= 0) {\n                start++;\n            } else if (nums[end] > 0) {\n                end--;\n            } else {\n                swap(nums, start, end);\n            }\n        }\n        return start;\n    }\n\n    private void swap(int[] nums, int start, int end) {\n        int t = nums[start];\n        nums[start] = nums[end];\n        nums[end] = t;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/Flip0sMaximum1s.java",
    "content": "package com.interview.array;\n\n/**\n * Date 12/29/2015\n * @author Tushar Roy\n *\n * Given input array of 0s and 1s and number of flips allowed from 0 to 1, what is maximum consecutive 1s we can have\n * in array\n *\n * Time complexity - O(n)\n * Space complexity - O(1)\n *\n * http://www.geeksforgeeks.org/find-zeroes-to-be-flipped-so-that-number-of-consecutive-1s-is-maximized/\n */\npublic class Flip0sMaximum1s {\n\n    public int flip0sToMaximizeConsecutive1s(int input[], int flipsAllowed) {\n\n        int windowStart = 0;\n        int countZero = 0;\n        int result = 0;\n        for (int i = 0 ; i < input.length; i++) {\n            if (input[i] == 1) {\n                result = Math.max(result, i - windowStart + 1);\n            } else {\n                if (countZero < flipsAllowed) {\n                    countZero++;\n                    result = Math.max(result, i - windowStart + 1);\n                } else {\n                    while(true) {\n                        if (input[windowStart] == 0) {\n                            windowStart++;\n                            break;\n                        }\n                        windowStart++;\n                    }\n                }\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        int input[] = {0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};\n        Flip0sMaximum1s fm = new Flip0sMaximum1s();\n        System.out.print(fm.flip0sToMaximizeConsecutive1s(input, 1));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/FourSum.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Date 07/31/2016\n * @author Tushar Roy\n *\n * Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?\n * Find all unique quadruplets in the array which gives the sum of target.\n *\n * Time complexity O(n^3)\n * Space complexity O(1)\n *\n * Reference\n * https://leetcode.com/problems/4sum/\n */\npublic class FourSum {\n\n    public List<List<Integer>> fourSum(int[] nums, int target) {\n        if (nums.length < 4) {\n            return Collections.EMPTY_LIST;\n        }\n        Arrays.sort(nums);\n        List<List<Integer>> result = new ArrayList<>();\n        for (int i = 0; i < nums.length - 3; i++) {\n            if (i != 0 && nums[i] == nums[i - 1]) {\n                continue;\n            }\n            if(nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target) {\n                break;\n            }\n            if(nums[i] + nums[nums.length - 3] + nums[nums.length - 2] + nums[nums.length - 1] < target) {\n                continue;\n            }\n            for (int j = i + 1; j < nums.length - 2; j++) {\n                if (j != i + 1 && nums[j] == nums[j - 1]) {\n                    continue;\n                }\n                if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {\n                    break;\n                }\n                if (nums[i] + nums[j] + nums[nums.length - 1] + nums[nums.length - 1] < target) {\n                    continue;\n                }\n                int low = j + 1;\n                int high = nums.length - 1;\n                while (low < high) {\n                    if (low != j + 1 && nums[low] == nums[low - 1]) {\n                        low++;\n                        continue;\n                    }\n                    if (high != nums.length - 1 && nums[high] == nums[high + 1]) {\n                        high--;\n                        continue;\n                    }\n\n                    int sum = nums[i] + nums[j] + nums[low] + nums[high];\n                    if (sum == target) {\n                        List<Integer> r = new ArrayList<>();\n                        r.add(nums[i]);\n                        r.add(nums[j]);\n                        r.add(nums[low]);\n                        r.add(nums[high]);\n                        result.add(r);\n                        low++;\n                        high--;\n                    } else if (sum < target) {\n                        low++;\n                    } else {\n                        high--;\n                    }\n                }\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        int[] nums = {1, 1, 4, 5, 9, 11};\n        int[] nums1 = {1, 0, -1, 0, -2, 2};\n        int target = 0;\n        FourSum fourSum = new FourSum();\n        List<List<Integer>> result = fourSum.fourSum(nums1, target);\n        result.forEach(System.out::print);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/GasStationCircle.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/find-a-tour-that-visits-all-stations/\n * You can solve this one using kadane wrap since it finds max contiguous sum\n * for wrapped array. That start point is a best place to start a tour.\n * Test cases\n * Check if length of both input array is same\n * Check that there exists a path after kadane wrap responds\n * Check that there is at least one positive difference before you call kadane\n */\npublic class GasStationCircle {\n\n    public int startTour(int gasAvailable[],int gasRequired[]){\n        int start = -1;\n        int end = 0;\n        int currentGas = 0;\n        boolean visitedOnce = false;\n        while(start != end){\n            currentGas += gasAvailable[end] - gasRequired[end];\n            if(start == -1){\n                start = end;\n            }\n            if(end == gasAvailable.length-1 && visitedOnce == false){\n                visitedOnce = true;\n            }else if(end == gasAvailable.length-1 && visitedOnce == true){\n                return -1;\n            }\n            if(currentGas < 0){\n                start = -1;\n                currentGas = 0;\n            }\n            end = (end + 1)%gasAvailable.length;\n        }\n        \n        return end;\n    }\n    \n    /**\n     * If it is not guaranteed that tour exists then once you get\n     * result of kadanewrap make an actual trip to see if value is positive\n     * @return -1 if no solution exists otherwise returns gas station at which to start.\n     */\n    public int startTour1(int gasAvailable[], int gasRequired[]){\n        int diff[] = new int[gasAvailable.length];\n        for(int i=0; i < diff.length; i++){\n            diff[i] = gasAvailable[i] - gasRequired[i];\n        }\n\n        boolean allNegative = true;\n        for (int i = 0; i < diff.length; i++) {\n            if (diff[i] >= 0) {\n                allNegative = false;\n                break;\n            }\n        }\n\n        if (allNegative) {\n            return -1;\n        }\n\n        KadaneWrapArray kwa = new KadaneWrapArray();\n        Triplet t = kwa.kadaneWrap(diff);\n        //make sure this solution leads to answer\n        int i = t.start;\n        int netGas = 0;\n        do {\n            netGas += diff[i];\n            i = (i + 1)%diff.length;\n            if (netGas < 0) {\n                return -1;\n            }\n        } while (i != t.start);\n\n        return t.start;\n    }\n\n    public static void main(String args[]){\n        GasStationCircle gsc = new GasStationCircle();\n        int[] gasAvailable = {4, 4, 6};\n        int[] gasRequired = {5, 6, 1};\n        System.out.println(gsc.startTour(gasAvailable, gasRequired));\n        System.out.println(gsc.startTour1(gasAvailable, gasRequired));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/GreedyTextJustification.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 03/12/2016\n * @author Tushar Roy\n *\n * Given an array of words and a length L, format the text such that each line has exactly L characters and is fully\n * (left and right) justified.\n * You should pack your words in a greedy approach; that is, pack as many words as you can in each line.\n *\n * Time complexity - O(n) where n is the number of words\n * Space complexity - O(1)\n *\n * https://leetcode.com/problems/text-justification/\n */\npublic class GreedyTextJustification {\n    public List<String> fullJustify(String[] words, int maxWidth) {\n        List<String> result = new ArrayList<>();\n        for (int i = 0; i < words.length; ) {\n            int total = words[i].length();\n            int j = i + 1;\n            StringBuffer buff = new StringBuffer();\n            buff.append(words[i]);\n            while(j < words.length && total + words[j].length() + 1 <= maxWidth) {\n                total += words[j].length() + 1;\n                j++;\n            }\n            int remaining = maxWidth - total;\n            //since j is not word length means its not a last line. So pad accordingly.\n            if (j != words.length) {\n                int count = j - i - 1;\n                if (count == 0) {\n                    padSpace(buff, remaining);\n                } else {\n                    int q = remaining/count;\n                    int r = remaining % count;\n                    for (int k = i + 1; k < j; k++) {\n                        padSpace(buff, q);\n                        if (r > 0) {\n                            buff.append(\" \");\n                            r--;\n                        }\n                        buff.append(\" \").append(words[k]);\n                    }\n                }\n            } else { //if it is last line then left justify all the words.\n                for (int k = i + 1; k < j; k++) {\n                    buff.append(\" \").append(words[k]);\n                }\n                padSpace(buff, remaining);\n            }\n            result.add(buff.toString());\n            i = j;\n        }\n        return result;\n    }\n\n    private void padSpace(StringBuffer buff, int count) {\n        for (int i = 0; i < count; i++) {\n            buff.append(\" \");\n        }\n    }\n\n    public List<String> fullJustify1(String[] words, int maxWidth) {\n       int currentLength = 0;\n        int prevIndex = 0;\n        List<String> result = new ArrayList<>();\n\n        for (int i = 0; i < words.length; i++) {\n            //keep track of length for currentLine. For first word only use length while for remaining words use\n            //lenght + 1 since there will be a space b/w them.\n            currentLength += (words[i].length() + (i == prevIndex ? 0 : 1));\n\n            //if currentLength exceeds maxWidth it means currentWord cannot in same line.\n            if (currentLength > maxWidth) {\n                //subtract current word's length from currentLength\n                currentLength -= words[i].length() + 1;\n                StringBuffer builder = new StringBuffer();\n\n                //find number of words which will find in the line.\n                int gaps = i - 1 - prevIndex;\n                if (gaps > 0) {//if more than one word fits in the gap.\n                    //available number of spaces is below. Subtract gaps because that many spaces have been accounted\n                    //for in currentLength.\n                    int availableSpace = maxWidth - currentLength + gaps;\n\n                    //first remaining gaps get one extra space.\n                    int remaining = availableSpace % gaps;\n\n                    //every gap gets this much extra space.\n                    int atleast = availableSpace / gaps;\n                    for (int j = prevIndex; j <= i - 2; j++) {\n                        builder.append(words[j]);\n                        padSpace(builder, atleast);\n                        if (j - prevIndex < remaining) {\n                            padSpace(builder, 1);\n                        }\n                    }\n                    builder.append(words[i - 1]);\n                } else { //if only one word can fit in a one line then left specify it.\n                    builder.append(words[i - 1]);\n                    padSpace(builder, maxWidth - words[i - 1].length());\n                }\n                result.add(builder.toString());\n                prevIndex = i;\n                currentLength = words[i].length();\n            }\n        }\n        //handle the last line. Left justify the remaining words\n        if (prevIndex < words.length) {\n            StringBuffer builder = new StringBuffer();\n            int count = 0;\n            while (prevIndex < words.length) {\n                builder.append(words[prevIndex]).append(\" \");\n                count += words[prevIndex].length() + 1;\n                prevIndex++;\n            }\n            count--;\n            //delete extra space added by above for looop.\n            builder.deleteCharAt(builder.length() - 1);\n            //whatever spae is left just put it at the end.\n            padSpace(builder, maxWidth - count);\n            result.add(builder.toString());\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        String[] input = {\"What\",\"must\",\"be\",\"shall\",\"be.\"};\n        GreedyTextJustification gtj = new GreedyTextJustification();\n        List<String> result = gtj.fullJustify(input, 12);\n        System.out.print(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/GroupElementsInSizeM.java",
    "content": "package com.interview.array;\n\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.PriorityQueue;\n\n/**\n * http://www.careercup.com/question?id=6026101998485504\n * This answer two questions.\n * Group elements in size m such that in every group only unique elements are possible.\n * It also answers question where rearrange array such that same elements are exactly m\n * distance from each other\n */\nclass Pair{\n    int num;\n    int count;\n    Pair(int num,int count){\n        this.count = count;\n        this.num = num;\n    }\n}\n\nclass Comparators implements Comparator<Pair>{\n\n    @Override\n    public int compare(Pair o1, Pair o2) {\n        if(o1.count <= o2.count){\n            return 1;\n        }else{\n            return -1;\n        }\n    }\n    \n}\n\npublic class GroupElementsInSizeM {\n\n    public boolean group(int input[],int m){\n        Map<Integer,Integer> count = new HashMap<Integer,Integer>();\n        for(Integer i : input){\n            int c = 1;\n            if(count.containsKey(i)){\n                c = count.get(i);\n                c++;\n            }\n            count.put(i, c);\n        }\n        \n        PriorityQueue<Pair> maxHeap = new PriorityQueue<Pair>(count.size(),new Comparators());\n        for(Integer s : count.keySet()){\n            int c = count.get(s);\n            //if any count is greater than len/m then this arrangement is not possible\n            if(c > Math.ceil(input.length*1.0/m)){\n                return false;\n            }\n            maxHeap.offer(new Pair(s,c));\n        }\n        int current = 0;\n        int start = current;\n        while(maxHeap.size() > 0){\n            Pair p = maxHeap.poll();\n            int i =0;\n            while(i < p.count){\n                input[start] = p.num;\n                start = start + m;\n                if(start >= input.length){\n                    current++;\n                    start = current;\n                }\n                i++;\n            }\n        }\n        return true;\n    }\n    \n    public static void main(String args[]){\n        int input[] = {2,1,5,1,3,5,3,3,4};\n        int input1[] = {1,2,3,8,8,8,7,8};\n        GroupElementsInSizeM gps = new GroupElementsInSizeM();\n        boolean r = gps.group(input1, 3);\n        System.out.println(r);\n        for(int i=0; i < input1.length; i++){\n            System.out.println(input1[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/HIndex.java",
    "content": "package com.interview.array;\n\n/**\n * Given an array of citations (each citation is a non-negative integer) of a researcher,\n * write a function to compute the researcher's h-index.\n * https://leetcode.com/problems/h-index/\n */\npublic class HIndex {\n    public int hIndex(int[] citations) {\n        int[] count = new int[citations.length + 1];\n        for (int c : citations) {\n            if (c <= citations.length) {\n                count[c]++;\n            } else {\n                count[citations.length]++;\n            }\n        }\n\n        int sum = 0;\n        int max = 0;\n        for (int i = 0; i < count.length; i++) {\n            sum += count[i];\n            //we are trying to see if i is answer.\n            //already everything before i has less than i citations.\n            //so only thing to check is that p >= i where p is\n            //total number of papers with i or more citations.\n            int p = citations.length - sum + count[i];\n            if (i <= p) {\n                max = i;\n            }\n        }\n        return max;\n    }\n\n    public static void main(String args[]) {\n        HIndex hi = new HIndex();\n        int[] input = {0, 1, 1, 1, 1, 6, 7 ,8};\n        System.out.print(hi.hIndex(input));\n    }\n}\n\n//0 1 2 6 6 6 6 7\n//0 1 2 3 4 5 6 7\n//0 1 1 1 3 6 7 8\n//0 1 2 3 4 5 6 7\n\n//0 1 2 5 6\n"
  },
  {
    "path": "src/com/interview/array/IncreasingSubsequnceOfLength3WithMaxProduct.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/increasing-subsequence-of-length-three-with-maximum-product/\n * Keep two arrays which keeps max from current position to right side\n * Other array keeps max on left size which is smaller than current element\n * Once you have these two arrays from 2nd to 2nd last position keep multiplying\n * elements at 3 arrays index position to get max product\n * Test cases\n * Negative numbers\n * 0 in the input\n */\npublic class IncreasingSubsequnceOfLength3WithMaxProduct {\n\n    public int maxProduct(int arr[]){\n        int RGN[] = new int[arr.length];\n        int LGN[] = new int[arr.length];\n        RGN[arr.length-1] = arr[arr.length-1];\n        int max = arr[arr.length-1];\n        for(int i=arr.length-2; i>=0; i--){\n            if(max < arr[i]){\n                max = arr[i];\n            }\n            if(max > arr[i]){\n                RGN[i] = max;\n            }\n            else{\n                RGN[i] = 0;\n            }\n        }\n        LGN[0] = 0;\n        //This can be implemented using an AVL tree instead of this way which will\n        //make it O(nLogn) operation insteado ofO(n2).\n        for(int i=1; i < arr.length; i++){\n            getLGN(arr,i,LGN);\n        }\n        int maxProduct = 0;\n        for(int i=1; i < arr.length-1; i++){\n            int product = arr[i]*LGN[i]*RGN[i];\n            if(maxProduct < product){\n                maxProduct = product;\n            }\n        }\n        return maxProduct;\n    }\n    \n    private void getLGN(int arr[],int pos,int LGN[]){\n        int max = 0;\n        int i =0;\n        while(i < pos){\n            if(arr[i] < arr[pos]){\n                if(arr[i] > max){\n                    max = arr[i];\n                }\n            }\n            i++;\n        }\n        LGN[pos] = max;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {6, 7, 8, 1, 2, 3, 9, 10};\n        IncreasingSubsequnceOfLength3WithMaxProduct iss = new IncreasingSubsequnceOfLength3WithMaxProduct();\n        System.out.println(iss.maxProduct(arr));\n        int arr1[] = {1, 5, 10, 8, 9};\n        System.out.println(iss.maxProduct(arr1));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/IncreasingTripletSubsequence.java",
    "content": "package com.interview.array;\n\n/**\n * Date 03/06/2016\n * @author Tushar Roy\n *\n * Find if there exists an increasing triplet subsequence.\n * Similar method to longest increasing subsequence in nlogn time.\n *\n * Time complexity is O(n)\n * Space complexity is O(1)\n *\n * https://leetcode.com/problems/increasing-triplet-subsequence/\n */\npublic class IncreasingTripletSubsequence {\n    public boolean increasingTriplet(int[] nums) {\n        int T[] = new int[3];\n        int len = 0;\n        for (int i = 0; i < nums.length; i++) {\n            boolean found = false;\n            for (int j = 0; j < len; j++) {\n                if (T[j] >= nums[i]) {\n                    T[j] = nums[i];\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) {\n                T[len++] = nums[i];\n            }\n            if (len == 3) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public static void main(String args[]) {\n        IncreasingTripletSubsequence tripletSubsequence = new IncreasingTripletSubsequence();\n        int input[] = {9, 10, -2, 12, 6, 7, -1};\n        System.out.print(tripletSubsequence.increasingTriplet(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/JumpGame.java",
    "content": "package com.interview.array;\n\n/**\n * Date 07/31/2016\n * @author Tushar Roy\n *\n * Given an array of non-negative integers, you are initially positioned at the first index of the array.\n * Each element in the array represents your maximum jump length at that position.\n * Determine if you are able to reach the last index.\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * https://leetcode.com/problems/jump-game/\n *\n *  Given an array of non-negative integers, you are initially positioned at the first index of the array.\n * Each element in the array represents your maximum jump length at that position.\n * Your goal is to reach the last index in the minimum number of jumps.\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * https://leetcode.com/problems/jump-game-ii/\n */\npublic class JumpGame {\n\n    public boolean canJump(int[] nums) {\n        int jump = 0;\n        int i;\n        for (i = 0; i < nums.length && i <= jump; i++) {\n            jump = Math.max(jump, i + nums[i]);\n        }\n        return i == nums.length;\n    }\n\n    public int jump(int[] nums) {\n        int current = 0;\n        int max = 0;\n        int count = 0;\n        for (int i = 0; i < nums.length - 1; i++) {\n            max = Math.max(max, i + nums[i]);\n            if (current == i) {\n                count++;\n                current = max;\n            }\n        }\n        return count;\n    }\n\n    public static void main(String args[]) {\n        JumpGame jumpGame = new JumpGame();\n        int[] nums = {3, 2, 3, 0, 2, 1};\n        System.out.println(jumpGame.jump(nums));\n        int[] nums1 = {3, 0, 2, 0, 0, 1};\n        System.out.println(jumpGame.canJump(nums1));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/KadaneWrapArray.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/maximum-contiguous-circular-sum/\n * Test cases\n * All negative\n * All positives\n * all 0s\n */\n\nclass Triplet{\n    int start;\n    int end;\n    int sum;\n    @Override\n    public String toString() {\n        return \"Triplet [start=\" + start + \", end=\" + end + \", sum=\" + sum\n                + \"]\";\n    }\n    \n}\npublic class KadaneWrapArray {\n\n    public Triplet kadaneWrap(int arr[]){\n        Triplet straightKadane = kadane(arr);\n        int sum =0;\n        for(int i=0; i < arr.length; i++){\n            sum += arr[i];\n            arr[i] = -arr[i];\n        }\n        Triplet wrappedNegKadane = kadane(arr);\n        for(int i=0; i < arr.length; i++){\n            arr[i] = -arr[i];\n        }\n        if(straightKadane.sum < sum + wrappedNegKadane.sum){\n            straightKadane.sum = wrappedNegKadane.sum + sum;\n            straightKadane.start = wrappedNegKadane.end+1;\n            straightKadane.end = wrappedNegKadane.start-1;\n        }\n        return straightKadane;\n    }\n    \n    /**\n     * This method assumes there is at least one positive number in the array.\n     * Otherwise it will break\n     * @param arr\n     * @return\n     */\n    public Triplet kadane(int arr[]){\n        int sum =0;\n        int cStart = 0;\n        int mStart = 0;\n        int end = 0;\n        int maxSum = Integer.MIN_VALUE;\n        for(int i=0; i < arr.length; i++){\n            sum += arr[i];\n            if(sum <= 0){\n                sum = 0;\n                cStart = i+1;\n            }else{\n                if(sum > maxSum){\n                    maxSum = sum;\n                    mStart = cStart;\n                    end = i;\n                }\n            }\n        }\n        Triplet p = new Triplet();\n        p.sum = maxSum;\n        p.start = mStart;\n        p.end = end;\n        return p;\n    }\n    \n    public static void main(String args[]){\n        KadaneWrapArray kwa = new KadaneWrapArray();\n        int input[] = {12, -2, -6, 5, 9, -7, 3};\n        int input1[] = {8, -8, 9, -9, 10, -11, 12};\n        System.out.println(kwa.kadaneWrap(input));\n        System.out.println(kwa.kadaneWrap(input1));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/KthElementInArray.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Kth largest element in an array.\n * Use quickselect of quicksort to find the solution in hopefully O(nlogn) time.\n * Test cases\n * Sorted array\n * Reverse sorted array\n */\npublic class KthElementInArray {\n    \n    public int kthElement(int arr[],int k){\n        int low = 0;\n        int high = arr.length-1;\n        int pos =0;\n        while(true){\n            pos = quickSelect(arr,low,high);\n            if(pos == (k+low)){\n                return arr[pos];\n            }\n            if(pos > k + low){\n                high = pos-1;\n            }else{\n                k = k - (pos - low + 1);\n                low = pos+1;\n            }\n        }\n    }\n    \n    private int quickSelect(int arr[],int low,int high){\n        int pivot = low;\n        low++;\n        while(low <= high){\n            if(arr[pivot] > arr[low]){\n                low++;\n                continue;\n            }\n            if(arr[pivot] <= arr[high]){\n                high--;\n                continue;\n            }\n            swap(arr,low,high);\n        }\n        if(arr[high] < arr[pivot]){\n            swap(arr,pivot,high);\n        }\n        return high;\n    }\n    \n    private void swap(int arr[],int low,int high){\n        int temp = arr[low];\n        arr[low] = arr[high];\n        arr[high] = temp;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {6, 2, 1, 6, 8, 9, 6};\n        KthElementInArray kthElement = new KthElementInArray();\n        System.out.print(kthElement.kthElement(arr, arr.length/2));\n        System.out.print(Arrays.toString(arr));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/array/KthLargestInTwoSortedArray.java",
    "content": "package com.interview.array;\n\n/**\n * http://stackoverflow.com/questions/4686823/given-2-sorted-arrays-of-integers-find-the-nth-largest-number-in-sublinear-time\n * http://articles.leetcode.com/2011/01/find-k-th-smallest-element-in-union-of.html\n */\npublic class KthLargestInTwoSortedArray {\n\n    \n    public int kthLargest1(int arr1[],int arr2[],int low1,int high1,int low2,int high2,int k){\n        int len1 = high1-low1 +1;\n        int len2 = high2 - low2+1;\n        \n        if(len1 == 0){\n            return arr2[low2+k];\n        }\n        if(len2 ==0){\n            return arr1[low1+k];\n        }\n        if(k == 0){\n            return Math.min(arr1[low1], arr2[low2]);\n        }\n        \n     \n        int mid1 = len1*k/(len1 + len2);\n        int mid2 = k - mid1 - 1;\n        \n        mid1 = low1+mid1;\n        mid2 = low2 + mid2;\n        \n        if(arr1[mid1] > arr2[mid2]){\n            k = k - mid2 + low2 -1;\n            high1 = mid1;\n            low2 = mid2 + 1;\n        }else{\n            k = k - mid1 + low1 -1;\n            high2 = mid2;\n            low1 = mid1+1;\n        }\n        return kthLargest(arr1, arr2, low1, high1, low2, high2, k);\n    }\n\n    \n    \n    public int kthLargest(int input1[],int input2[],int k){\n        return kthLargest(input1, input2, 0, input1.length-1, 0, input2.length-1, k);\n    }\n    \n    private int kthLargest(int input1[],int input2[],int l1, int h1, int l2,int h2,int k){\n        if(l1 > h1){\n            return input2[k-1];\n        }\n        if(l2 > h2){\n            return input1[k-1];\n        }\n        \n        if((h1 - l1 + 1) + (h2 - l2 + 1) == k){\n            return Math.max(input1[h1], input2[h2]);\n        }\n\n        if(k == 1){\n            return Math.min(input1[l1],input2[l2]);\n        }\n\n        //handle the situation where only one element is left\n        //in either of array.\n        //e.g k =2 and arr1 = 8 arr2 = 1,9,11\n        //we try to find if 8 is before 9 betweenn 1 and 9\n        //or before 1. In all these cases k will be either\n        //1 8 or 9 \n        if(l2 == h2 || l1 == h1){\n            if(l2 == h2){\n                if(input1[l1+k-1] < input2[l2]){\n                    return input1[l1+k-1];\n                }else if(input1[l1+k-2] > input2[l2]){\n                    return input1[l1+k-2];\n                }else{\n                    return input2[l2];\n                }\n            }\n            if(l1 == h1){\n                if(input2[l2+k-1] < input1[l1]){\n                    return input2[l2+k-1];\n                }else if(input2[l2+k-2] > input1[l1]){\n                    return input2[l2+k-2];\n                }else{\n                    return input1[l1];\n                }\n            }\n        }\n        \n    \n        int m1 = (h1 + l1)/2;\n        int m2 = (h2 + l2)/2;\n        \n        int diff1 = m1 - l1+1;\n        int diff2 = m2 - l2+1;\n        if(diff1 + diff2 >= k){\n            if(input1[m1] < input2[m2]){\n                return kthLargest(input1, input2, l1, h1, l2, m2, k);\n            }else{\n                return kthLargest(input1, input2, l1, m1, l2, h2, k);\n            }\n        }else{\n            if(input1[m1] < input2[m2]){\n                return kthLargest(input1, input2,m1+1, h1, l2, h2, k - diff1);\n            }else{\n                return kthLargest(input1, input2, l1, h1, m2+1, h2, k -diff2);\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        KthLargestInTwoSortedArray kis = new KthLargestInTwoSortedArray();\n        int input1[] = {1,4,7,11,17,21};\n        int input2[] = {-4,-1,3,4,6,28,35,41,56,70};\n        for(int i = 0; i < input1.length + input2.length; i++){\n            System.out.println(kis.kthLargest(input1, input2, i+1));\n        }\n//      System.out.println(kis.kthLargest(input1, input2, 6));\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/LargerElementOnRight.java",
    "content": "package com.interview.array;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * http://www.geeksforgeeks.org/next-greater-element/\n * Find next larger element on right side of a number in array for \n * all positions in array\n * This is different than finding largest element on right side which can \n * be done by keeping max while iterating from right\n * It is also different from find next higher number on right side which can\n * be found by keeping AVL tree and finding ceiling.\n */\npublic class LargerElementOnRight {\n\n    public int[] larger(int input[]){\n        Deque<Integer> stack = new LinkedList<Integer>();\n        int result[] = new int[input.length];\n        for(int i=0; i < result.length; i++){\n            result[i] = -1;\n        }\n        \n        stack.offerFirst(0);\n        for(int i=1; i < input.length; i++){\n            while(stack.size() > 0){\n                int t = stack.peekFirst();\n                if(input[t] < input[i]){\n                    result[t] = i;\n                    stack.pollFirst();\n                }else{\n                    break;\n                }\n            }\n            stack.offerFirst(i);\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        LargerElementOnRight leo = new LargerElementOnRight();\n        int input[] = {4,2,-8,6,0,-3,-1,1,9};\n        int result[] = leo.larger(input);\n        for(int i=0; i < result.length; i++){\n            if(result[i] != -1){\n                System.out.print(input[result[i]] + \" \");\n            }else{\n                System.out.print(\"NIL \");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/LargestMountain.java",
    "content": "package com.interview.array;\n\n/**\n * https://leetcode.com/problems/longest-mountain-in-array/description/\n */\npublic class LargestMountain {\n\n    public int longestMountain(int[] nums) {\n        int start = 0;\n        int max = 0;\n        State state = State.STARTED;\n        for (int i = 1; i < nums.length; i++) {\n            if (nums[i] == nums[i - 1]) {\n                start = i;\n                state = State.STARTED;\n            }\n            else if (nums[i] > nums[i - 1]) {\n                if (state == State.DECREASING || state == State.STARTED) {\n                    start = i - 1;\n                    state = State.INCREASING;\n                }\n            } else {\n                if (state == State.INCREASING || state == State.DECREASING) {\n                    state = State.DECREASING;\n                    max = Math.max(max, i - start + 1);\n                } else {\n                    start = i;\n                }\n            }\n        }\n        return max;\n    }\n\n    enum State {\n        STARTED,\n        INCREASING,\n        DECREASING;\n    }\n\n    public static void main(String[] args) {\n        LargestMountain lm = new LargestMountain();\n        int[] nums = {2, 1, 4, 7, 3, 2, 5};\n        System.out.println(lm.longestMountain(nums));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/LargestSubArrayWithEqual0sAnd1s.java",
    "content": "package com.interview.array;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * http://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/\n * Test cases\n * Starting with either 0 or 1\n * Maximum length of 0 1 2 or more\n * \n*/\npublic class LargestSubArrayWithEqual0sAnd1s {\n\n    public int equalNumber(int arr[]){\n\n        int sum[] = new int[arr.length];\n        sum[0] = arr[0] == 0? -1 : 1;\n        for(int i=1; i < sum.length; i++){\n            sum[i] = sum[i-1] + (arr[i] == 0? -1 : 1);\n        }\n        \n        Map<Integer,Integer> pos = new HashMap<Integer,Integer>();\n        int maxLen = 0;\n        int i = 0;\n        for(int s : sum){\n            if(s == 0){\n                maxLen = Math.max(maxLen, i+1);\n            }\n            if(pos.containsKey(s)){\n                maxLen = Math.max(maxLen, i-pos.get(s));\n            }else{\n                pos.put(s, i);\n            }\n            i++;\n        }\n        return maxLen;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {0,0,0,1,0,1,0,0,1,0,0,0};\n        LargestSubArrayWithEqual0sAnd1s mse = new LargestSubArrayWithEqual0sAnd1s();\n        System.out.println(mse.equalNumber(arr));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/array/LeetCodeCandy.java",
    "content": "package com.interview.array;\n\n/**\n * References\n * https://leetcode.com/problems/candy/\n */\npublic class LeetCodeCandy {\n    public int candy(int[] ratings) {\n        int pointOfChange = 0;\n        int totalCandies = 1;\n        int currentCandy = 1;\n        boolean isIndependent = true;\n        int maxHeight = 0;\n        int diff = 0;\n        for (int i = 1; i < ratings.length; i++) {\n            diff = 0;\n            if (ratings[i] > ratings[i-1]) {\n                currentCandy += 1;\n            } else if (ratings[i] == ratings[i-1]) {\n                isIndependent = true;\n                pointOfChange = i;\n                currentCandy = 1;\n            } else {\n                if (currentCandy == 1) {\n                    if (!isIndependent) {\n                        if (i - pointOfChange == maxHeight - 1) {\n                            pointOfChange--;\n                        }\n                    }\n                }\n                else {\n                    maxHeight = currentCandy;\n                    currentCandy = 1;\n                    isIndependent = false;\n                    pointOfChange = i;\n                }\n                diff = i - pointOfChange;\n            }\n            totalCandies += (diff + currentCandy);\n        }\n        return totalCandies;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/LongestConsecutiveSubsequence.java",
    "content": "package com.interview.array;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 12/03/2016\n * @author Tushar Roy\n *\n * Find longest consecutive subsequence in unsorted array.\n *\n * Time complexity O(n)\n * Space complexity O(n)\n *\n * Reference\n * https://leetcode.com/problems/longest-consecutive-sequence/\n */\npublic class LongestConsecutiveSubsequence {\n    public int longestConsecutive(int[] nums) {\n        Map<Integer, Integer> map = new HashMap<Integer, Integer>();\n        int result = 1;\n        for (int i : nums) {\n            if (map.containsKey(i)) {\n                continue;\n            }\n            int left = map.containsKey(i - 1) ? map.get(i - 1) : 0;\n            int right = map.containsKey(i + 1) ? map.get(i + 1) : 0;\n\n            int sum = left + right + 1;\n            map.put(i, sum);\n            result = Math.max(sum, result);\n            map.put(i - left, sum);\n            map.put(i + right, sum);\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        LongestConsecutiveSubsequence lcs = new LongestConsecutiveSubsequence();\n        int[] input = {100, 4, 200, 1, 3, 2};\n        System.out.println(lcs.longestConsecutive(input));\n    }\n}"
  },
  {
    "path": "src/com/interview/array/LongestIncreasingSubSequenceOlogNMethod.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Date 08/01/2015\n * @author Tushar Roy\n *\n * Given an array, find longest increasing subsequence in nlogn time complexity\n *\n * References\n * http://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/\n * http://www.geeksforgeeks.org/construction-of-longest-monotonically-increasing-subsequence-n-log-n/\n */\npublic class LongestIncreasingSubSequenceOlogNMethod {\n\n    /**\n     * Returns index in T for ceiling of s\n     */\n    private int ceilIndex(int input[], int T[], int end, int s){\n        int start = 0;\n        int middle;\n        int len = end;\n        while(start <= end){\n            middle = (start + end)/2;\n            if(middle < len && input[T[middle]] < s && s <= input[T[middle+1]]){\n                return middle+1;\n            }else if(input[T[middle]] < s){\n                start = middle+1;\n            }else{\n                end = middle-1;\n            }\n        }\n        return -1;\n    }\n    \n    public int longestIncreasingSubSequence(int input[]){\n        int T[] = new int[input.length];\n        int R[] = new int[input.length];\n        for(int i=0; i < R.length ; i++) {\n            R[i] = -1;\n        }\n        T[0] = 0;\n        int len = 0;\n        for(int i=1; i < input.length; i++){\n            if(input[T[0]] > input[i]){ //if input[i] is less than 0th value of T then replace it there.\n                T[0] = i;\n            }else if(input[T[len]] < input[i]){ //if input[i] is greater than last value of T then append it in T\n                len++;\n                T[len] = i;\n                R[T[len]] = T[len-1];\n            }else{ //do a binary search to find ceiling of input[i] and put it there.\n                int index = ceilIndex(input, T, len,input[i]);\n                T[index] = i;\n                R[T[index]] = T[index-1];\n            }\n        }\n\n        //this prints increasing subsequence in reverse order.\n        System.out.print(\"Longest increasing subsequence \");\n        int index = T[len];\n        while(index != -1) {\n            System.out.print(input[index] + \" \");\n            index = R[index];\n        }\n\n        System.out.println();\n        return len+1;\n    }\n    \n    public static void main(String args[]){\n        //int input[] = {2,5,3,1,2,10,6,7,8};\n        int input[] = {3, 4, -1, 5, 8, 2, 3, 12, 7, 9, 10};\n        LongestIncreasingSubSequenceOlogNMethod lis = new LongestIncreasingSubSequenceOlogNMethod();\n        System.out.println(\"Maximum length \" + lis.longestIncreasingSubSequence(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/LongestSameSumSpan.java",
    "content": "package com.interview.array;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 12/29/2015\n * @author Tushar Roy\n *\n * Give two arrays of same size consisting of 0s and 1s find span (i, j) such that\n * sum of input1[i..j] = sum of input2[i..j]\n *\n * Time complexity O(n)\n * Space complexity O(n)\n *\n * http://www.geeksforgeeks.org/longest-span-sum-two-binary-arrays/\n */\npublic class LongestSameSumSpan {\n\n    public int longestSpan(int input1[], int input2[]) {\n        if (input1.length != input2.length) {\n            throw new IllegalArgumentException(\"Not same length input\");\n        }\n        Map<Integer, Integer> diff = new HashMap<>();\n        int prefix1 = 0, prefix2 = 0;\n        int maxSpan = 0;\n        diff.put(0, -1);\n        for (int i = 0; i < input1.length ; i++) {\n            prefix1 += input1[i];\n            prefix2 += input2[i];\n            int currDiff = prefix1 - prefix2;\n            if (diff.containsKey(currDiff)) {\n                maxSpan = Math.max(maxSpan, i - diff.get(currDiff));\n            } else {\n                diff.put(currDiff, i);\n            }\n        }\n        return maxSpan;\n    }\n\n    public static void main(String args[]) {\n        int input1[] = {1, 0, 0, 1, 1, 0};\n        int input2[] = {0, 1, 1, 0, 1, 1};\n        LongestSameSumSpan lsss = new LongestSameSumSpan();\n        System.out.print(lsss.longestSpan(input1, input2));\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/array/LongestSubstringWithAtMost2Char.java",
    "content": "package com.interview.array;\n\n/**\n * Longest Substring with At Most Two Distinct Characters\n * https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/\n */\npublic class LongestSubstringWithAtMost2Char {\n    public int lengthOfLongestSubstringTwoDistinct(String s) {\n        int count1 = 0;\n        int count2 = 0;\n        char c1 = 0;\n        char c2 = 0;\n        int start = 0;\n        int current = 0;\n        int max = 0;\n        for (char ch: s.toCharArray()) {\n            if (ch == c1 || ch == c2) {\n                if (ch == c1) {\n                    count1++;\n                } else {\n                    count2++;\n                }\n            } else {\n                if (count1 != 0 && count2 != 0) {\n                    while (start < current) {\n                        if (s.charAt(start) == c1) {\n                            count1--;\n                        } else if (s.charAt(start) == c2) {\n                            count2--;\n                        }\n                        start++;\n                        if (count1 == 0 || count2 == 0) {\n                            break;\n                        }\n                    }\n                }\n                if (count1 == 0) {\n                    c1 = ch;\n                    count1 = 1;\n                } else {\n                    c2 = ch;\n                    count2 = 1;\n                }\n            }\n            max = Math.max(max, current - start + 1);\n            current++;\n        }\n        return max;\n    }\n\n    public static void main(String args[]) {\n        LongestSubstringWithAtMost2Char lc = new LongestSubstringWithAtMost2Char();\n        System.out.print(lc.lengthOfLongestSubstringTwoDistinct(\"eceba\"));\n    }\n}"
  },
  {
    "path": "src/com/interview/array/MaxNumberFromTwoArray.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * Date 03/01/2016\n * @author Tushar Roy\n *\n * Given two arrays of length m and n with digits 0-9 representing two numbers.\n * Create the maximum number of length k <= m + n from digits of the two\n *\n * e.g\n * nums1 = [3, 4, 6, 5]\n * nums2 = [9, 1, 2, 5, 8, 3]\n * k = 5\n * return [9, 8, 6, 5, 3]\n * \n * https://leetcode.com/problems/create-maximum-number/\n */\npublic class MaxNumberFromTwoArray {\n    public int[] maxNumber(int[] nums1, int[] nums2, int k) {\n        int[] max = new int[k];\n        for (int i = 0; i <= k; i++) {\n            if (nums1.length < i || nums2.length < k - i) {\n                continue;\n            }\n            int[] a = merge(findLargest1(nums1, i), findLargest1(nums2, k - i));\n            if (isGreater(a, max, 0, 0)) {\n                max = a;\n            }\n        }\n        return max;\n    }\n\n    private int[] merge(int[] a1, int[] a2) {\n        int[] result = new int[a1.length + a2.length];\n        int i = 0;\n        int j = 0;\n        int k = 0;\n        while (i < a1.length || j < a2.length) {\n            if (i == a1.length) {\n                result[k++] = a2[j++];\n            } else if (j == a2.length) {\n                result[k++] = a1[i++];\n            } else if (a1[i] > a2[j]) {\n                result[k++] = a1[i++];\n            } else if (a1[i] < a2[j]) {\n                result[k++] = a2[j++];\n            } else {\n                if (isGreater(a1, a2, i, j)) {\n                    result[k++] = a1[i++];\n                } else {\n                    result[k++] = a2[j++];\n                }\n            }\n        }\n        return result;\n    }\n\n    private boolean isGreater(int[] a, int[] b, int i, int j) {\n        while (i < a.length && j < b.length) {\n            if (a[i] > b[j]) {\n                return true;\n            } else if (a[i] < b[j]) {\n                return false;\n            }\n            i++;\n            j++;\n        }\n        return j == b.length;\n    }\n\n    private int[] findLargest1(int[] nums, int k) {\n        if (k == 0) {\n            return new int[0];\n        }\n        int[] result = new int[k];\n        int index = 0;\n        for (int i = 0; i < nums.length; i++) {\n            while (index > 0 && index + (nums.length - i - 1) >= k && result[index - 1] < nums[i]) {\n                index--;\n            }\n            if (index < k) {\n                result[index++] = nums[i];\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        MaxNumberFromTwoArray max = new MaxNumberFromTwoArray();\n        int[] input1 = {9,1,2,5,8,3};\n        int[] input2 = {3,4,6,5};\n\n        int[] input3 = {2,5,6,4,4,0};\n        int[] input4 = {7,3,8,0,6,5,7,6,2};\n        int[] result = max.maxNumber(input3, input4, 15);\n        System.out.print(Arrays.toString(result));\n    }\n}"
  },
  {
    "path": "src/com/interview/array/MaxProductSubarray.java",
    "content": "package com.interview.array;\n\n/**\n * Date 04/`7/2016\n * @author Tushar Roy\n *\n * Find the contiguous subarray within an array (containing at least one number) which has the largest product.\n *\n * Time complexity is O(n)\n * Space complexity is O(1)\n *\n * http://www.geeksforgeeks.org/maximum-product-subarray/\n * https://leetcode.com/problems/maximum-product-subarray/\n */\npublic class MaxProductSubarray {\n\n    public int maxProduct(int[] nums) {\n        //neg maintains the multiplication which is negative since last 0\n        //pos maintains the multiplication which is positive since last 0\n        int neg = 1;\n        int pos = 1;\n        int maxProduct = nums[0];\n        for (int i = 0; i < nums.length; i++) {\n            if (nums[i] == 0) {\n                neg = 1;\n                pos = 1;\n                maxProduct = Math.max(maxProduct, 0);\n            } else if (nums[i] < 0) {\n                int temp = pos;\n                if (neg < 0) {\n                    pos = neg * nums[i];\n                    maxProduct = Math.max(pos, maxProduct);\n                } else {\n                    pos = 1;\n                }\n                neg = temp * nums[i];\n            } else {\n                if (neg < 0) {\n                    neg *= nums[i];\n                }\n                pos *= nums[i];\n                maxProduct = Math.max(pos, maxProduct);\n            }\n        }\n        return maxProduct;\n    }\n    \n    public static void main(String args[]){\n        MaxProductSubarray mps = new MaxProductSubarray();\n        int input[] = {-6, -3, 8, -9, -1, -1, 3, 6, 9, 0, 3, -1};\n        System.out.println(mps.maxProduct(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MaxRepeatingNumber.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/find-the-maximum-repeating-number-in-ok-time/\n * Given an array of size n, the array contains numbers in range from 0 to k-1 \n * where k is a positive integer and k <= n.\n * Find the maximum repeating number in this array\n */\npublic class MaxRepeatingNumber {\n\n    public int maxRepeatingNumber(int arr[], int k){\n        int len = k;\n        for(int i=0;  i < arr.length; i++){\n            arr[arr[i]%len] += len;\n        }\n        int maxRepeating = 0;\n        int maxRepeatingIndex =0;\n        for(int i=0; i < len; i++){\n            if(maxRepeating < arr[i]){\n                maxRepeating = arr[i];\n                maxRepeatingIndex = i;\n            }\n        }\n        for(int i=0; i < len; i++){\n            arr[i] = arr[i] % len;\n        }\n        return maxRepeatingIndex;\n    }\n    \n    public static void main(String args[]){\n        MaxRepeatingNumber mrn = new MaxRepeatingNumber();\n        int arr[] = {2,2,1,3,1,2,0,3,0,0,0,4,5,4,4,4,4};\n        System.out.println(mrn.maxRepeatingNumber(arr, 6));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MaximumGap.java",
    "content": "package com.interview.array;\n\n/**\n * Date 03/12/2016\n * @author Tushar Roy\n *\n * Given an unsorted array find maximum gap between consecutive element in sorted array.\n *\n * Time complexity O(n)\n * Space complexity O(n)\n *\n * Reference\n * https://leetcode.com/problems/maximum-gap/\n */\npublic class MaximumGap {\n\n    class Bucket {\n        int low ;\n        int high;\n        boolean isSet = false;\n        void update(int val) {\n            if (!isSet) {\n                low = val;\n                high = val;\n                isSet = true;\n            } else {\n                low = Math.min(low, val);\n                high = Math.max(high, val);\n            }\n        }\n    }\n\n    public int maximumGap(int[] input) {\n        if (input == null || input.length < 2) {\n            return 0;\n        }\n        int min = Integer.MAX_VALUE;\n        int max = Integer.MIN_VALUE;\n\n        for (int i = 0; i < input.length; i++) {\n            min = Math.min(min, input[i]);\n            max = Math.max(max, input[i]);\n        }\n\n        int gap = (int) Math.ceil((double) (max - min) / (input.length - 1));\n\n        Bucket[] buckets = new Bucket[input.length - 1];\n\n        for (int i = 0; i < buckets.length; i++) {\n            buckets[i] = new Bucket();\n        }\n\n        for (int i = 0; i < input.length; i++) {\n            if (input[i] == max || input[i] == min) {\n                continue;\n            }\n            buckets[(input[i] - min) / gap].update(input[i]);\n        }\n\n        int prev = min;\n        int maxGap = 0;\n        for (int i = 0; i < buckets.length; i++) {\n            if (!buckets[i].isSet) {\n                continue;\n            }\n            maxGap = Math.max(maxGap, buckets[i].low - prev);\n            prev = buckets[i].high;\n        }\n\n        return Math.max(maxGap, max - prev);\n    }\n\n    public static void main(String args[]) {\n        int[] input = {4, 3, 13, 2, 9, 7};\n        MaximumGap mg = new MaximumGap();\n        System.out.println(mg.maximumGap(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MaximumIminusJSuchThatAiGTAj.java",
    "content": "package com.interview.array;\n\nimport java.util.Iterator;\nimport java.util.LinkedList;\n\n/**\n * http://www.geeksforgeeks.org/given-an-array-arr-find-the-maximum-j-i-such-that-arrj-arri/\n */\npublic class MaximumIminusJSuchThatAiGTAj {\n\n    class Node{\n        int index;\n        int size;\n    }\n    \n    public int maximumGeeks(int input[]){\n        int lhs[] = new int[input.length];\n        int rhs[] = new int[input.length];\n        lhs[0] = 0;\n        for(int i=1; i < lhs.length; i++){\n            if(input[lhs[i-1]] < input[i]){\n                lhs[i] = lhs[i-1];\n            }else{\n                lhs[i] = i;\n            }\n        }\n        rhs[input.length-1] = input.length-1;\n        for(int i=input.length-2; i >= 0; i--){\n            if(input[rhs[i+1]] > input[i]){\n                rhs[i] = rhs[i+1];\n            }else{\n                rhs[i] = i;\n            }\n        }\n        \n        int i=0;\n        int j=0;\n        int max = 0;\n        for(;j < input.length;){\n            if(input[lhs[i]] < input[rhs[j]]){\n                max = Math.max(max, j-i);\n                j++;\n            }else{\n                i++;\n            }\n        }\n        return max;\n    }\n    \n    public static void main(String args[]){\n        MaximumIminusJSuchThatAiGTAj mj = new MaximumIminusJSuchThatAiGTAj();\n        int input[] = {11,14,13,1,4,13,1,10};\n        System.out.println(mj.maximumGeeks(input));\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/array/MaximumMinimumArrangement.java",
    "content": "package com.interview.array;\n\n/**\n * Date 04/16/2016\n * @author Tushar Roy\n *\n * Given a sorted array of positive integers, rearrange the array alternately i.e first element should be maximum value,\n * second minimum value, third second max, fourth second min and so on.\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * http://www.geeksforgeeks.org/rearrange-array-maximum-minimum-form/\n */\npublic class MaximumMinimumArrangement {\n\n    public void rearrange(int[] input) {\n        for (int i = 0; i < input.length; i++) {\n            int t = input[i];\n            if (t < 0) {\n                continue;\n            }\n            int i1 = i;\n            while (true) {\n                int j = i1 < input.length/2 ? 2 * i1 + 1 : (input.length - 1 - i1) * 2;\n                if (j == i1) {\n                    break;\n                }\n                if (input[j] < 0) {\n                    break;\n                }\n                int t1 = input[j];\n                input[j] = -t;\n                t = t1;\n                i1 = j;\n            }\n        }\n\n        for (int i = 0; i < input.length; i++) {\n            input[i] = Math.abs(input[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MaximumOfSubarrayOfSizeK.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/maximum-of-all-subarrays-of-size-k/\n * Test cases\n * input containg neg and pos values\n * val of k is neg 0 or pos\n * val of k is larger than size of input\n * val of k is same as size of input\n */\nimport java.util.Deque;\nimport java.util.LinkedList;\n\npublic class MaximumOfSubarrayOfSizeK {\n\n    public int[] maxSubArray(int input[], int k) {\n        Deque<Integer> queue = new LinkedList<Integer>();\n        int max[] = new int[input.length - k + 1];\n        int maxVal = Integer.MIN_VALUE;\n        //first find max of first k values and make it 0th element of max array\n        for (int i = 0; i < k; i++) {\n            if(maxVal < input[i]){\n                maxVal = input[i];\n            }\n            if (queue.isEmpty()) {\n                queue.offerLast(i);\n            } else {\n                while (!queue.isEmpty() && input[queue.peekLast()] <= input[i]) {\n                    queue.pollLast();\n                }\n                queue.offerLast(i);\n            }\n            \n        }\n        max[0] = maxVal;\n        int index=1;\n        //continue from k till end of the input array\n        for (int i = k; i < input.length; i++) {\n            //if index of peek is k distance from i then its no value to us.\n            //throw it away\n            if (i - k + 1 > queue.peekFirst()) {\n                queue.pollFirst();\n            }\n            while (!queue.isEmpty() && input[queue.peekLast()] <= input[i]) {\n                queue.pollLast();\n            }\n            queue.offerLast(i);\n            //Only reason first element survived was because it was biggest element.\n            //make it the max value for this k\n            max[index] = input[queue.peekFirst()];\n            index++;\n        }\n        return max;\n    }\n    \n    public static void main(String args[]){\n        int input[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13};\n        MaximumOfSubarrayOfSizeK msa = new MaximumOfSubarrayOfSizeK();\n        int max[] = msa.maxSubArray(input, 4);\n        for(int i : max){\n            System.out.print(i + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MaximumSumPathTwoArrays.java",
    "content": "package com.interview.array;\n\n/**\n * Date 12/31/2015\n * @author Tushar Roy\n *\n * Given two sorted arrays such the arrays may have some common elements. Find the sum of the maximum sum\n * path to reach from beginning of any array to end of any of the two arrays. We can switch from one array\n * to another array only at common elements.\n *\n * Time complexity is O(n + m)\n * Space complexity is O(1)\n *\n * http://www.geeksforgeeks.org/maximum-sum-path-across-two-arrays/\n */\npublic class MaximumSumPathTwoArrays {\n\n    public int maxSum(int input1[], int input2[]) {\n        int maxSum = 0;\n        int i = 0, j = 0;\n        int sum1 = 0;\n        int sum2 = 0;\n        while (i < input1.length && j < input2.length) {\n            if (input1[i] == input2[j]) {\n                if (sum1 > sum2) {\n                    maxSum += sum1 + input1[i];\n                } else {\n                    maxSum += sum2 + input2[j];\n                }\n                i++;\n                j++;\n                sum1 = 0;\n                sum2 = 0;\n            } else if (input1[i] < input2[j]) {\n                sum1 += input1[i++];\n            } else {\n                sum2 += input2[j++];\n            }\n        }\n        while(i < input1.length) {\n            sum1 += input1[i++];\n        }\n        while(j < input2.length) {\n            sum2 += input2[j++];\n        }\n\n        if (sum1 > sum2) {\n            maxSum += sum1;\n        } else {\n            maxSum += sum2;\n        }\n        return maxSum;\n    }\n\n    public static void main(String args[]) {\n        int input1[] = {2, 3, 7, 10, 12, 15, 30, 34};\n        int input2[] = {1, 5, 7, 8, 10, 15, 16, 19};\n\n        MaximumSumPathTwoArrays msp = new MaximumSumPathTwoArrays();\n        System.out.println(msp.maxSum(input1, input2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MaximumSumThreeNonOverlappingSubarray.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\nimport java.util.Deque;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n *https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/description/\n */\npublic class MaximumSumThreeNonOverlappingSubarray {\n\n    public int[] maxSumOfThreeSubarrays(int[] nums, int k) {\n        int sum = 0;\n        int[] sumArray = new int[nums.length - k + 1];\n        for (int i = 0; i < nums.length; i++) {\n            if (i < k) {\n                sum += nums[i];\n            } else {\n                sumArray[i - k] = sum;\n                sum += nums[i];\n                sum -= nums[i - k];\n            }\n        }\n        sumArray[sumArray.length - 1] = sum;\n\n        int[][] dp = new int[4][sumArray.length + 1];\n\n        for (int i = 1; i <= 3; i++) {\n            for (int j = 1; j <= sumArray.length; j++) {\n                if (j >= k) {\n                    if (dp[i][j - 1] >= sumArray[j - 1] + dp[i - 1][j - k]) {\n                        dp[i][j] = dp[i][j - 1];\n                    } else {\n                        dp[i][j] = sumArray[j - 1] + dp[i - 1][j - k];\n                    }\n                } else {\n                    if (dp[i][j - 1] >= sumArray[j - 1]) {\n                        dp[i][j] = dp[i][j - 1];\n                    } else {\n                        dp[i][j] = sumArray[j - 1];\n                    }\n                }\n            }\n        }\n        int[] output = new int[3];\n        int j = dp[0].length - 1;\n        for (int i = 3; i > 0;) {\n            if (dp[i][j] == dp[i][j - 1]) {\n                j--;\n            } else {\n                output[i - 1] = j - 1;\n                i--;\n                j = j - k;\n            }\n        }\n        return output;\n    }\n\n    public static void main(String[] args) {\n        MaximumSumThreeNonOverlappingSubarray mss = new MaximumSumThreeNonOverlappingSubarray();\n        int[] input = {3, 2, 2, 1, 1, 0, 5};\n        int[] input1 = {1, 2, 1, 2, 6, 7, 5, 1};\n        int[] output = mss.maxSumOfThreeSubarrays(input1, 2);\n        for (int i : output) {\n            System.out.println(i);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MeetingRooms.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\nimport java.util.PriorityQueue;\n\n/**\n * Date 05/01/2016\n * @author Tushar Roy\n *\n * Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei),\n * find the minimum number of conference rooms required.\n *\n * Both methods have time comlexity of nlogn\n * Method 1 has space complexity of O(1)\n * \n * https://leetcode.com/problems/meeting-rooms-ii/\n */\npublic class MeetingRooms {\n\n    public static class Interval {\n          int start;\n          int end;\n          Interval() { start = 0; end = 0; }\n          Interval(int s, int e) { start = s; end = e; }\n    }\n\n    public int minMeetingRooms1(Interval[] intervals) {\n        int[] start = new int[intervals.length];\n        int[] end = new int[intervals.length];\n\n        for (int i = 0; i < intervals.length; i++) {\n            start[i] = intervals[i].start;\n            end[i] = intervals[i].end;\n        }\n\n        Arrays.sort(start);\n        Arrays.sort(end);\n\n        int j = 0;\n        int rooms = 0;\n        for (int i = 0; i < start.length; i++) {\n            if (start[i] < end[j]) {\n                rooms++;\n            } else {\n                j++;\n            }\n        }\n        return rooms;\n    }\n\n    public int minMeetingRooms(Interval[] intervals) {\n        if (intervals.length == 0) {\n            return 0;\n        }\n        Arrays.sort(intervals, (a, b) ->  a.start - b.start);\n        PriorityQueue<Interval> pq = new PriorityQueue<>((a, b) -> a.end - b.end);\n        pq.offer(intervals[0]);\n        int rooms = 1;\n        for (int i = 1; i < intervals.length; i++) {\n            Interval it = pq.poll();\n            if (it.end <= intervals[i].start) {\n                it = new Interval(it.start, intervals[i].end);\n            } else {\n                rooms++;\n                pq.offer(intervals[i]);\n            }\n            pq.offer(it);\n        }\n        return rooms;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MinimumDistanceBetweenTwoNumbers.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/\n */\npublic class MinimumDistanceBetweenTwoNumbers {\n\n    public int minDistance(int input[],int x, int y){\n        int prev = -1;\n        int prevFound = -1;\n        int min = 10000;\n        for(int i=0; i < input.length; i++){\n            if(input[i] == x){\n                if(prevFound == -1){\n                    prevFound = x;\n                    prev = i;\n                }else if(prevFound == x){\n                    prev = i;\n                }else{\n                    min = min > i - prev ? i -prev : min;\n                    prev = i;\n                    prevFound = x;\n                }\n            }else if(input[i] == y){\n                if(prevFound == -1){\n                    prevFound = y;\n                    prev = i;\n                }else if(prevFound == y){\n                    prev =i;\n                }else{\n                    min = min > i - prev ? i -prev : min;\n                    prevFound = y;\n                    prev = i;\n                }\n            }\n        }\n        return min;\n    }\n    \n    public static void main(String args[]){\n        MinimumDistanceBetweenTwoNumbers mdb = new MinimumDistanceBetweenTwoNumbers();\n        int input[] = {6,4,1,5,6,9,10,4,6,6};\n        System.out.println(mdb.minDistance(input, 5, 6));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MinimumNumberFromSequence.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Date 02/26/2016\n * @author Tushar Roy\n *\n * Time complexity : O(n^2)\n * Space complexity : O(n)\n *\n * Reference\n * http://www.geeksforgeeks.org/form-minimum-number-from-given-sequence/\n */\npublic class MinimumNumberFromSequence {\n\n    public int[] find(char[] input) {\n        int[] output = new int[input.length + 1];\n        output[0] = 1;\n        int low = 0;\n        int start = 0;\n        for (int i = 0; i < input.length; i++) {\n            if (input[i] == 'D') {\n                output[i + 1] = output[i] - 1;\n                if (output[i+1] == low) {\n                    for (int j = start; j <= i + 1; j++) {\n                        output[j] = output[j] + 1;\n                    }\n                }\n            } else {\n                low = output[start];\n                output[i + 1] = low + 1;\n                start = i + 1;\n            }\n        }\n        return output;\n    }\n\n    public static void main(String args[]) {\n        MinimumNumberFromSequence ms = new MinimumNumberFromSequence();\n        int output[] = ms.find(\"DDIDDIID\".toCharArray());\n        System.out.println(Arrays.toString(output));\n\n        output = ms.find(\"IIDDD\".toCharArray());\n        System.out.println(Arrays.toString(output));\n\n        output = ms.find(\"DIDI\".toCharArray());\n        System.out.println(Arrays.toString(output));\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MinimumSortedWhichSortsEntireArray.java",
    "content": "package com.interview.array;\n\n/**\n *http://www.geeksforgeeks.org/minimum-length-unsorted-subarray-sorting-which-makes-the-complete-array-sorted/\n */\npublic class MinimumSortedWhichSortsEntireArray {\n\n    public int minLength(int arr[]){\n        int  i=0;\n        while(i < arr.length -1 && arr[i] < arr[i+1]){\n            i++;\n        }\n        if(i == arr.length-1){\n            return 0;\n        }\n        int j = arr.length-1;\n        while(j > 0 && arr[j] > arr[j-1]){\n            j--;\n        }\n        \n        int max = Integer.MIN_VALUE;\n        int min = Integer.MAX_VALUE;\n        for(int k = i; k <= j; k++){\n            if(max < arr[k]){\n                max = arr[k];\n            }\n            if(min > arr[k]){\n                min = arr[k];\n            }\n        }\n        int x = i-1;\n        while(x >=0){\n            if(min > arr[x]){\n                break;\n            }\n            x--;\n        }\n        \n        int y = j +1;\n        while(y < arr.length){\n            if(max < arr[y]){\n                break;\n            }\n            y++;\n        }\n        return y -x -2 + 1;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {4,5,10,21,18,23,7,8,19,34,38};\n        int arr1[] = {4,5,6,12,11,15};\n        int arr2[] = {4,5,6,10,11,15};\n        MinimumSortedWhichSortsEntireArray msw = new MinimumSortedWhichSortsEntireArray();\n        System.out.println(msw.minLength(arr1));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/array/MissingRanges.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Given a sorted integer array where the range of elements are in the inclusive range [lower, upper], return its missing ranges.\n * For example, given [0, 1, 3, 50, 75], lower = 0 and upper = 99, return [\"2\", \"4->49\", \"51->74\", \"76->99\"].\n *\n * Time complexity O(n)\n *\n * https://leetcode.com/problems/missing-ranges/\n */\npublic class MissingRanges {\n    public List<String> findMissingRanges(int[] nums, int lower, int upper) {\n        if (nums.length == 0) {\n            return Collections.singletonList(makeRange(lower, upper));\n        }\n        List<String> result = new ArrayList<>();\n        if (lower < nums[0]) {\n            result.add(makeRange(lower, nums[0] - 1));\n        }\n        for (int i = 0; i < nums.length - 1; i++) {\n            if (nums[i] == nums[i + 1]) {\n                continue;\n            }\n            if ((nums[i] + 1) != nums[i + 1]) {\n                result.add(makeRange(nums[i] + 1, nums[i + 1] - 1));\n            }\n        }\n        if (nums[nums.length - 1] < upper) {\n            result.add(makeRange(nums[nums.length - 1] + 1, upper));\n        }\n        return result;\n    }\n\n    private String makeRange(int a, int b) {\n        if (a == b) {\n            return String.valueOf(a);\n        } else {\n            return a + \"->\" + b;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MoveAllZerosToEnd.java",
    "content": "package com.interview.array;\n\npublic class MoveAllZerosToEnd {\n\n    public void moveZeros(int arr[]){\n        int slow =0;\n        int fast =0;\n        while(fast < arr.length){\n            if(arr[fast] == 0){\n                fast++;\n                continue;\n            }\n            arr[slow] = arr[fast];\n            slow++;\n            fast++;\n        }\n        while(slow < arr.length){\n            arr[slow++] = 0;\n        }\n    }\n    \n    public static void main(String args[]){\n        MoveAllZerosToEnd maz  = new MoveAllZerosToEnd();\n        int arr[] = {0,0,1,2,0,5,6,7,0};\n        maz.moveZeros(arr);\n        for(int i=0; i < arr.length; i++){\n            System.out.print(arr[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/MultiplyAllFieldsExceptOwnPosition.java",
    "content": "package com.interview.array;\n\n/**\n * https://leetcode.com/problems/product-of-array-except-self/\n */\npublic class MultiplyAllFieldsExceptOwnPosition {\n\n    public int[] multiply(int nums[]) {\n        if (nums.length == 0) {\n            return new int[0];\n        }\n        int[] output = new int[nums.length];\n        output[0] = 1;\n        for (int i = 1; i < nums.length; i++) {\n            output[i] = output[i - 1] * nums[i - 1];\n        }\n\n        int mult = 1;\n        for (int i = nums.length - 1; i >= 0; i--) {\n            output[i] *= mult;\n            mult *= nums[i];\n        }\n        return output;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/NthElementOfCountNumberSequence.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 07/20/2015\n * @author Tushar Roy\n *\n * Given a sequence like\n * 1 11 21 1211 111221 312211\n * Print nth element of this sequence.\n */\npublic class NthElementOfCountNumberSequence {\n\n    public List<Integer> nthElement(int n) {\n        int  i = 1;\n        List<Integer> current = new ArrayList<>();\n        current.add(1);\n        List<Integer> result = new ArrayList<>();\n        while(i < n) {\n            int count = 1;\n            int index = 0;\n            for(int j = 1; j < current.size(); j++) {\n                if(current.get(index) == current.get(j)) {\n                    count++;\n                } else {\n                    result.add(count);\n                    result.add(current.get(index));\n                    count = 1;\n                    index = j;\n                }\n            }\n            result.add(count);\n            result.add(current.get(index));\n            current = result;\n            result = new ArrayList<>();\n            i++;\n        }\n        return current;\n    }\n\n    public static void main(String args[]) {\n        NthElementOfCountNumberSequence nes = new NthElementOfCountNumberSequence();\n        for(int i = 1 ; i <= 10; i++) {\n            List<Integer> result = nes.nthElement(i);\n            result.forEach(System.out::print);\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/NumberOfTrianglesInUnsortedArray.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * http://www.geeksforgeeks.org/find-number-of-triangles-possible/\n */\npublic class NumberOfTrianglesInUnsortedArray {\n\n    public int numberOfTriangles(int input[]){\n        Arrays.sort(input);\n        \n        int count = 0;\n        for(int i=0; i < input.length-2; i++){\n            int k = i+2;\n            for(int j=i+1; j < input.length; j++){\n                while(k < input.length && input[i] + input[j] > input[k]){\n                    k++;\n                }\n                count += k - j -1;\n            }\n        }\n        return count;\n        \n    }\n    \n    public static void main(String args[]){\n        int input[] = {3, 4, 5, 6, 8, 9, 15};\n        NumberOfTrianglesInUnsortedArray not = new NumberOfTrianglesInUnsortedArray();\n        System.out.println(not.numberOfTriangles(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/PositiveAndNegativeNumberAlternatively.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/\n */\npublic class PositiveAndNegativeNumberAlternatively {\n\n    public void arrange(int arr[]){\n        int startOfPos = segregate(arr);\n        \n        int startOfNeg = 1;\n        while(startOfNeg < startOfPos && startOfPos < arr.length){\n            swap(arr,startOfNeg,startOfPos);\n            startOfNeg+=2;\n            startOfPos++;\n        }\n    }\n    \n    private int segregate(int arr[]){\n        int low =0;\n        int high = arr.length-1;\n        while(low < high){\n            if(arr[low] < 0){\n                low++;\n            }else if(arr[high] >= 0){\n                high--;\n            }else{\n                swap(arr,low,high);\n            }\n        }\n        return low;\n    }\n    \n    private void swap(int arr[],int i,int j){\n        int t = arr[i];\n        arr[i] = arr[j];\n        arr[j] = t;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {-1,-2,-3,-4,-5,1,2,3,4,5};\n        PositiveAndNegativeNumberAlternatively pan = new PositiveAndNegativeNumberAlternatively();\n        pan.arrange(arr);\n        for(int i=0; i < arr.length; i++){\n            System.out.print(arr[i]+ \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/PositiveAndNegativeNumberAlternativelyMaintainingOrder.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Date 12/31/2015\n * @author Tushar Roy\n *\n * Given an array of positive and negative integers arrange them alternatively maintaining initial order.\n * If there are more +ve or -ve integer then push them to the end together.\n *\n * Time complexity is O(n)\n * Space complexity is O(1)\n *\n * http://www.geeksforgeeks.org/rearrange-array-alternating-positive-negative-items-o1-extra-space/\n */\npublic class PositiveAndNegativeNumberAlternativelyMaintainingOrder {\n\n    public void rearrange(int input[]) {\n\n        for (int i = 0; i < input.length; i++) {\n            if (i % 2 == 0 && input[i] >= 0) {\n                int indexOfNextNegative = findNext(input, i + 1, false);\n                if (indexOfNextNegative == -1) {\n                    return;\n                } else {\n                    rightRotate(input, i, indexOfNextNegative);\n                }\n            } else if (i % 2 != 0 && input[i] < 0) {\n                int indexOfNextPositive = findNext(input, i + 1, true);\n                if (indexOfNextPositive == -1) {\n                    return;\n                } else {\n                    rightRotate(input, i, indexOfNextPositive);\n                }\n            }\n        }\n    }\n\n    private int findNext(int input[], int start, boolean isPositive) {\n        for (int i = start; i < input.length; i++) {\n            if ((isPositive && input[i] >= 0) || (!isPositive && input[i] < 0)) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    private void rightRotate(int input[], int start, int end) {\n        int t = input[end];\n        for (int i = end; i > start; i--) {\n            input[i] = input[i - 1];\n        }\n        input[start] = t;\n    }\n\n    public static void main(String args[]) {\n        int input[] = {-5, -2, 5, 2, 4, 7, 1, 8, 0, -8};\n        PositiveAndNegativeNumberAlternativelyMaintainingOrder pss = new PositiveAndNegativeNumberAlternativelyMaintainingOrder();\n        pss.rearrange(input);\n        Arrays.stream(input).forEach(i -> System.out.print(i + \" \"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/RearrangeArrayPerIndex.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Date 12/30/2015\n *\n * Given an array of size n where elements are in range 0 to n-1. Rearrange elements of array\n * such that if arr[i] = j then arr[j] becomes i.\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * http://www.geeksforgeeks.org/rearrange-array-arrj-becomes-arri-j/\n */\npublic class RearrangeArrayPerIndex {\n\n    public void rearrange(int input[]) {\n\n        for (int i = 0; i < input.length; i++) {\n            input[i]++;\n        }\n\n        for (int i = 0; i < input.length; i++) {\n            if (input[i] > 0) {\n                rearrangeUtil(input, i);\n            }\n        }\n\n        for (int i = 0; i < input.length; i++) {\n            input[i] = -input[i] - 1;\n        }\n    }\n\n    private void rearrangeUtil(int input[], int start) {\n        int i = start + 1;\n        int v = input[start];\n        while (v > 0) {\n            int t = input[v - 1];\n            input[v - 1] = -i;\n            i = v;\n            v = t;\n        }\n    }\n\n    public static void main(String args[]) {\n        RearrangeArrayPerIndex rai = new RearrangeArrayPerIndex();\n        int input[] = {1, 2, 0, 5, 3, 4};\n        rai.rearrange(input);\n        Arrays.stream(input).forEach(i -> System.out.print(i + \" \"));\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/array/RearrangeSuchThatArriBecomesArrArri.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/rearrange-given-array-place/\n */\npublic class RearrangeSuchThatArriBecomesArrArri {\n\n    public void rearrange(int arr[]){\n        for(int i=0; i < arr.length; i++){\n            int temp;\n            if(arr[arr[i]] > arr.length-1){\n                temp = arr[arr[i]]/arr.length-1;\n            }else{\n                temp = arr[arr[i]];\n            }\n            arr[i] = temp + arr.length*(arr[i]+1);\n        }\n        \n        for(int i=0; i < arr.length;i++){\n            arr[i] = arr[i] % arr.length;\n        }\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {4,2,0,1,3};\n        RearrangeSuchThatArriBecomesArrArri rss = new RearrangeSuchThatArriBecomesArrArri();\n        rss.rearrange(arr);\n        for(int i=0; i < arr.length; i++){\n            System.out.print(arr[i]);\n        }\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/array/ReorderArrayByIndex.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Date 12/29/2015\n * @author Tushar Roy\n *\n * Given two arrays one with values and other with index where values should be positioned. Move values to correct\n * position\n *\n * Time complexity - O(n)\n * Space complexity - O(1)\n *\n * http://www.geeksforgeeks.org/reorder-a-array-according-to-given-indexes/\n */\npublic class ReorderArrayByIndex {\n    public void reorder(int input[], int index[]) {\n        if(index.length != input.length) {\n            throw new IllegalArgumentException();\n        }\n        for (int i = 0 ; i < index.length; i++) {\n            while (index[i] != i) {\n                int sIndex = index[index[i]];\n                int sVal = input[index[i]];\n\n                index[index[i]] = index[i];\n                input[index[i]] = input[i];\n\n                index[i] = sIndex;\n                input[i] = sVal;\n            }\n        }\n    }\n\n    public static void main(String args[]) {\n        int input[] = {50, 40, 70, 60, 90};\n        int index[] = {3,  0,  4,  1,  2};\n        ReorderArrayByIndex reorderArrayByIndex = new ReorderArrayByIndex();\n        reorderArrayByIndex.reorder(input, index);\n        Arrays.stream(input).forEach(i -> System.out.print(i + \" \"));\n        System.out.println();\n        Arrays.stream(index).forEach(i -> System.out.print(i + \" \"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/RepeatingAndMissingNumber.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/find-a-repeating-and-a-missing-number/\n */\npublic class RepeatingAndMissingNumber {\n\n    class Pair{\n        int repeating;\n        int missing;\n        public String toString(){\n            return repeating + \" \" + missing;\n        }\n    }\n    \n    public Pair findNumbers(int input[]){\n        Pair p = new Pair();\n        for(int i=0; i < input.length; i++){\n            if(input[Math.abs(input[i])-1] < 0){\n                p.repeating = Math.abs(input[i]);\n            }else{\n                input[Math.abs(input[i])-1] = -input[Math.abs(input[i])-1];\n            }\n        }\n    \n        for(int i=0; i < input.length; i++){\n            if(input[i] < 0){\n                input[i] = -input[i];\n            }else{\n                p.missing = i + 1;\n            }\n        }\n        return p;\n    }\n    \n    public static void main(String args[]){\n        RepeatingAndMissingNumber rmn = new RepeatingAndMissingNumber();\n        int input[] = {3,1,2,4,6,8,2,7};\n        System.out.println(rmn.findNumbers(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/RotationWithMaxSum.java",
    "content": "package com.interview.array;\n\n/**\n * Date 12/30/2015\n * @author Tushar Roy\n *\n * Given an input array find which rotation will give max sum of i * arr[i]\n *\n * Time complexity - O(n)\n * Space complexity - O(1)\n *\n * http://www.geeksforgeeks.org/find-maximum-value-of-sum-iarri-with-only-rotations-on-given-array-allowed/\n */\npublic class RotationWithMaxSum {\n    int maxSum(int input[]) {\n        int arrSum = 0;\n        int rotationSum = 0;\n        for (int i =0; i < input.length; i++) {\n            arrSum += input[i];\n            rotationSum += i*input[i];\n        }\n\n        int maxRotationSum = rotationSum;\n\n        for (int i = 1; i < input.length; i++) {\n            rotationSum += input.length*input[i - 1] - arrSum;\n            maxRotationSum = Math.max(maxRotationSum, rotationSum);\n        }\n        return maxRotationSum;\n    }\n\n    public static void main(String args[]) {\n        int input[] = {10, 1, 2, 3, 4, 5, 6, 7, 8, 9};\n        RotationWithMaxSum rms = new RotationWithMaxSum();\n        System.out.print(rms.maxSum(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/SelfCrossing.java",
    "content": "package com.interview.array;\n\n/**\n * Created by tushar_v_roy on 3/10/16.\n */\npublic class SelfCrossing {\n\n    public boolean isSelfCrossing(int[] x) {\n        if (x.length < 4) {\n            return false;\n        }\n        int v1 = -x[0];\n        int v2 = -x[1];\n\n        int i = 2;\n        while (i < x.length) {\n            if (i % 2 == 0) {\n                if (i % 4 == 0) {\n                    v1 -= x[i];\n                } else {\n                    v1 += x[i];\n                }\n            } else {\n                if ((i + 1) % 4 == 0) {\n                    v2 += x[i];\n                } else {\n                    v2 -= x[i];\n                }\n            }\n            if (i % 2 != 0) {\n                if ((v1 >= 0 && v2 <= 0) || (v1 <= 0 && v2 >= 0)) {\n                    return true;\n                }\n            }\n            i++;\n        }\n        return false;\n    }\n\n    public static void main(String args[]) {\n        SelfCrossing sc = new SelfCrossing();\n        int input[] = {3, 3, 4, 2, 2};\n        System.out.print(sc.isSelfCrossing(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/ShortestPalindrome.java",
    "content": "package com.interview.array;\n\n/**\n * Date 03/04/2016\n * @author Tushar Roy\n *\n * How to append minimum numbers of characters in front of string to make it a palindrome.\n *\n * Idea is to create a new string which is original ttring + $ + reverse of original string\n * Get value of suffix which is also prefix using KMP.\n * This part of string is good. Rest needs to be copied in the front.\n *\n * Time complexity is O(n)\n * Space complexity is O(n)\n *\n * https://leetcode.com/problems/shortest-palindrome/\n */\npublic class ShortestPalindrome {\n    public String shortestPalindrome(String s) {\n        char[] input = createInput(s);\n        int val = kmp(input);\n\n        StringBuffer sb = new StringBuffer();\n        int remaining = s.length() - val;\n        int i = s.length() - 1;\n        while (remaining > 0) {\n            sb.append(s.charAt(i));\n            i--;\n            remaining--;\n        }\n        sb.append(s);\n        return sb.toString();\n\n    }\n\n    private int kmp(char[] input) {\n        int T[] = new int[input.length];\n\n        int j = 1;\n        int i = 0;\n\n        T[0] = 0;\n\n        while (j < input.length) {\n            if (input[i] == input[j]) {\n                T[j] = i + 1;\n                i++;\n            } else {\n                while (i != 0) {\n                    i = T[i-1];\n                    if (input[j] == input[i]) {\n                        T[j] = i + 1;\n                        i++;\n                        break;\n                    }\n                }\n            }\n            j++;\n        }\n        return T[input.length - 1];\n    }\n\n    private char[] createInput(String s) {\n        char[] input = new char[2*s.length() + 1];\n        int index = 0;\n        for (char ch: s.toCharArray()) {\n            input[index++] = ch;\n        }\n        input[index++] = '$';\n\n        for (int i = s.length() - 1; i >= 0; i--) {\n            input[index++] = s.charAt(i);\n        }\n        return input;\n    }\n\n    public static void main(String args[]) {\n        ShortestPalindrome sp = new ShortestPalindrome();\n        System.out.print(sp.shortestPalindrome(\"aacecaaa\"));\n    }\n }\n"
  },
  {
    "path": "src/com/interview/array/SmallestIntegerNotRepresentedBySubsetSum.java",
    "content": "package com.interview.array;\n\n/**\n * Date 12/31/2015\n * @author Tushar Roy\n *\n * Given array in non decreasing order find smallest integer which cannot be represented by\n * subset sum of these integers.\n *\n * Time complexity is O(n)\n *\n * http://www.geeksforgeeks.org/find-smallest-value-represented-sum-subset-given-array/\n */\npublic class SmallestIntegerNotRepresentedBySubsetSum {\n\n    public int findSmallestInteger(int input[]) {\n        int result = 1;\n        for (int i = 0; i < input.length; i++) {\n            if (input[i] <= result) {\n                result += input[i];\n            } else {\n                break;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Leetcode variation https://leetcode.com/problems/patching-array/\n     */\n    public int minPatches(int[] nums, int n) {\n        int patch = 0;\n        long t = 1;\n        int i = 0;\n        while(t <= n) {\n            if (i == nums.length || t < nums[i]) {\n                patch++;\n                t += t;\n            } else {\n                t = nums[i] + t;\n                i++;\n            }\n        }\n        return patch;\n    }\n\n\n    public static void main(String args[]) {\n        int input[] = {1, 2, 3, 8};\n        SmallestIntegerNotRepresentedBySubsetSum ss = new SmallestIntegerNotRepresentedBySubsetSum();\n        System.out.println(ss.findSmallestInteger(input));\n\n        int input1[] = {};\n        System.out.println(ss.minPatches(input1, 7));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/SmallestSubarrayWithAtleastKSum.java",
    "content": "package com.interview.array;\n\n/**\n * https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/description/\n */\npublic class SmallestSubarrayWithAtleastKSum {\n\n    public int shortestSubarray(int[] A, int K) {\n        int[] skip = new int[A.length];\n\n        int sum = 0;\n        int start = A.length - 1;\n        skip[A.length - 1] = 1;\n        for (int i = A.length - 1; i > 0; i--) {\n            skip[i - 1] = 1;\n            sum += A[i];\n            if (sum <= 0) {\n                skip[i - 1] = start - i + 1;\n            } else {\n                start = i;\n                sum = 0;\n            }\n        }\n\n        start = 0;\n        int end = 0;\n        sum = 0;\n        int min = Integer.MAX_VALUE;\n        while (end < A.length) {\n            sum += A[end++];\n            while (start <= end && sum >= K) {\n                min = Math.min(end - start, min);\n                for (int j = start; j < start + skip[start]; j++) {\n                    sum -= A[j];\n                }\n                start = start + skip[start];\n            }\n            if (sum <= 0) {\n                start = end;\n                sum = 0;\n            }\n        }\n\n        return min == Integer.MAX_VALUE ? -1 : min;\n    }\n\n    public  static void main(String[] args) {\n        int[] input = {1, 3, -1, -4, -2, 3, 4, -5, -1, 8};\n        SmallestSubarrayWithAtleastKSum ss = new SmallestSubarrayWithAtleastKSum();\n        ss.shortestSubarray(input, 8);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/SortedArrayTransformation.java",
    "content": "package com.interview.array;\n\n/**\n * Date 10/08/2016\n * @author Tushar Roy\n *\n * Given a sorted array of integers nums and integer values a, b and c.\n * Apply a function of the form f(x) = ax2 + bx + c to each element x in the array.\n *\n * Time complexity O(n)\n *\n * https://leetcode.com/problems/sort-transformed-array/\n */\npublic class SortedArrayTransformation {\n    public int[] sortTransformedArray(int[] nums, int a, int b, int c) {\n        int start = 0;\n        int end = nums.length - 1;\n        int[] result = new int[nums.length];\n        int index = (a >= 0 ? nums.length - 1 : 0);\n        while (start <= end) {\n            int x = apply(nums[start], a, b, c);\n            int y = apply(nums[end], a, b, c);\n            boolean condition = (a >= 0 ? x >= y : x <= y);\n            if (condition) {\n                result[index] = x;\n                start++;\n            } else {\n                result[index] = y;\n                end--;\n            }\n            index = index + (a >= 0 ? -1 : 1);\n        }\n        return result;\n    }\n\n    private int apply(int x, int a, int b, int c) {\n        return a*x*x + b * x + c;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/StableMarriageProblem.java",
    "content": "package com.interview.array;\n\npublic class StableMarriageProblem {\n\n    private boolean checkIfNewIsBetter(int priority[][], int bride,\n            int currentGroom, int suitor) {\n        for (int groom : priority[bride]) {\n            if (currentGroom == groom) {\n                return false;\n            }\n            if (suitor == groom) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public int[] findPair(int[][] priority) {\n        int pair = priority[0].length;\n        int groomToBride[] = new int[pair];\n        int brideToGroom[] = new int[pair];\n        for(int i=0; i < groomToBride.length; i++){\n            groomToBride[i] = -1;\n        }\n        for(int i=0; i < brideToGroom.length; i++){\n            brideToGroom[i] = -1;\n        }\n        int groom ;\n        int remaingGrooms = pair;\n        while (remaingGrooms > 0) {\n            groom = -1;\n            for (int hasBride : groomToBride) {\n                if (hasBride != -1) {\n                    continue;\n                }\n                groom++;\n                for (int bride : priority[groom]) {\n                    if (brideToGroom[bride-pair] == -1) {\n                        groomToBride[groom] = bride;\n                        brideToGroom[bride-pair] = groom;\n                        remaingGrooms--;\n                        break;\n                    } else {\n                        boolean flag = checkIfNewIsBetter(priority, bride,\n                                brideToGroom[bride-pair], groom);\n                        if (flag) {\n                            int currentGroom = brideToGroom[bride-pair];\n                            brideToGroom[bride-pair] = groom;\n                            groomToBride[groom] = bride;\n                            groomToBride[currentGroom] = -1;\n                        }\n                    }\n                }\n            }\n        }\n        return groomToBride;\n    }\n    \n    public static void main(String args[]){\n        int priority[][] = {{5,4,7,6},\n                           {4,5,6,7},\n                           {5,4,6,7},\n                           {5,4,7,6},\n                           {0,1,2,3},\n                           {0,1,3,2},\n                           {0,3,1,2},\n                           {0,1,2,3}};\n        StableMarriageProblem smp = new StableMarriageProblem();\n        int[] result = smp.findPair(priority);\n        for(int i=0; i < result.length; i++){\n            System.out.println(i + \" \" + result[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/SubarrayWithGivenSum.java",
    "content": "package com.interview.array;\n\n/**\n * http://www.geeksforgeeks.org/find-subarray-with-given-sum/\n */\npublic class SubarrayWithGivenSum {\n\n    class Pair{\n        int start;\n        int end;\n        \n        public String toString(){\n            return start + \" \" + end;\n        }\n    }\n    public Pair findSubArray(int input[],int sum){\n        int currentSum = 0;\n        Pair p = new Pair();\n        p.start = 0;\n        for(int i=0; i < input.length; i++){\n            currentSum += input[i];\n            p.end = i;\n            if(currentSum == sum){\n                return p;\n            }else if(currentSum > sum){\n                int s = p.start;\n                while(currentSum  > sum){\n                    currentSum -= input[s];\n                    s++;\n                }\n                p.start = s;\n                if(currentSum == sum){\n                    return p;\n                }\n            }\n        }\n        return null;\n    }\n    \n    public static void main(String args[]){\n        SubarrayWithGivenSum sgs = new SubarrayWithGivenSum();\n        int input[] = {6,3,9,11,1,3,5};\n        System.out.println(sgs.findSubArray(input,15));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/SummaryRanges.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Date 10/19/2016\n * @author Tushar Roy\n *\n * Given a sorted integer array without duplicates, return the summary of its ranges.\n * For example, given [0,1,2,4,5,7], return [\"0->2\",\"4->5\",\"7\"].\n *\n * Solution -\n * Just check if num[i] + 1 != num[i + 1]. If its not equal means you need to add previous range to result\n * and start a new range.\n * \n * Time complexity O(n)\n *\n * https://leetcode.com/problems/summary-ranges/\n */\npublic class SummaryRanges {\n    public List<String> summaryRanges(int[] nums) {\n        if (nums.length == 0) {\n            return Collections.EMPTY_LIST;\n        }\n        if (nums.length == 1) {\n            return Collections.singletonList(String.valueOf(nums[0]));\n        }\n        int start = 0;\n        List<String> result = new ArrayList<>();\n        for (int i = 0; i < nums.length - 1; i++) {\n            if ((nums[i] + 1) != nums[i + 1]) {\n                result.add(makeRange(nums[start], nums[i]));\n                start = i + 1;\n            }\n        }\n        if ((nums[nums.length - 2] + 1) != nums[nums.length - 1]) {\n            start = nums.length - 1;\n        }\n        result.add(makeRange(nums[start], nums[nums.length - 1]));\n        return result;\n    }\n\n    private String makeRange(int a, int b) {\n        if (a == b) {\n            return String.valueOf(a);\n        }\n        return a + \"->\" + b;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/ThreeSumSmallerThanTarget.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Given an array of n integers nums and a target, find the number of index triplets i, j, k\n * with 0 <= i < j < k < n that satisfy the condition nums[i] + nums[j] + nums[k] < target.\n *\n * https://leetcode.com/problems/3sum-smaller/\n */\npublic class ThreeSumSmallerThanTarget {\n    public int threeSumSmaller(int[] nums, int target) {\n        if (nums.length < 3) {\n            return 0;\n        }\n        Arrays.sort(nums);\n        int count = 0;\n        for (int i = 0; i < nums.length; i++) {\n            int j = i + 1;\n            int k = nums.length - 1;\n            while (j < k) {\n                if (nums[i] + nums[j] + nums[k] >= target) {\n                    k--;\n                } else {\n                    count += k - j;\n                    j++;\n                }\n            }\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/TrappingWater.java",
    "content": "package com.interview.array;\n/**\n * References\n * https://oj.leetcode.com/problems/trapping-rain-water/\n * https://leetcode.com/problems/trapping-rain-water/\n */\npublic class TrappingWater {\n\n    public int trap(int[] height) {\n       if(height == null || height.length == 0) {\n            return 0;\n        }\n        int len = height.length;\n        int left[] = new int[len];\n        int right[] = new int[len];\n        left[0] = height[0];\n        right[len-1] = height[len -1];\n        for (int i = 1; i < len; i++) {\n            left[i] = Math.max(height[i], left[i-1]);\n            right[len - i - 1] = Math.max(height[len- i - 1], right[len-i]);\n        }\n\n        int maxWaterTrapped = 0;\n        for (int i = 1; i < len - 1; i++) {\n            int min = Math.min(left[i], right[i]);\n            if (height[i] < min) {\n                maxWaterTrapped += min - height[i];\n            }\n        }\n        return maxWaterTrapped;\n    }\n\n    public static void main(String args[]){\n        int input[] = {0,1,0,2,1,0,1,3,2,1,2,1};\n        TrappingWater tw = new TrappingWater();\n        System.out.println(tw.trap(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/TripletInArray.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * http://www.geeksforgeeks.org/find-a-triplet-that-sum-to-a-given-value/\n */\npublic class TripletInArray {\n\n    class Triplet {\n        int a;\n        int b;\n        int c;\n\n        public String toString() {\n            return a + \" \" + b + \" \" + c;\n        }\n    }\n\n    public Triplet findTriplet(int input[], int sum) {\n        Arrays.sort(input);\n        for (int i = 0; i < input.length - 2; i++) {\n\n            int start = i + 1;\n            int end = input.length - 1;\n            int new_sum = sum - input[i];\n            while (start < end) {\n                if (new_sum == input[start] + input[end]) {\n                    Triplet t = new Triplet();\n                    t.a = input[i];\n                    t.b = input[start];\n                    t.c = input[end];\n                    return t;\n                }\n                if (new_sum > input[start] + input[end]) {\n                    start++;\n                } else {\n                    end--;\n                }\n            }\n        }\n        return null;\n    }\n\n    /**\n     * https://leetcode.com/problems/3sum/\n     */\n    public List<List<Integer>> threeSum(int[] nums) {\n        Arrays.sort(nums);\n        List<List<Integer>> result = new ArrayList<>();\n        for (int i = 0; i < nums.length - 2; i++) {\n            if (i != 0 && nums[i] == nums[i-1]) {\n                continue;\n            }\n            int start = i + 1;\n            int end = nums.length - 1;\n            while (start < end) {\n                if (nums[i] + nums[start] + nums[end] == 0) {\n                    List<Integer> r = new ArrayList<>();\n                    r.add(nums[i]);\n                    r.add(nums[start]);\n                    r.add(nums[end]);\n                    result.add(r);\n                    start++;\n                    end--;\n                    while(start < nums.length && nums[start] == nums[start - 1]) {\n                        start++;\n                    }\n                    while(end >= 0 && nums[end] == nums[end+1]) {\n                        end--;\n                    }\n                } else if (nums[i] + nums[start] + nums[end] < 0) {\n                    start++;\n                } else {\n                    end--;\n                }\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]){\n        TripletInArray tip = new TripletInArray();\n        int input[] = {1,2,6,9,11,18,26,28};\n        int sum = 22;\n        System.out.println(tip.findTriplet(input, sum));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/TripletSumLessThanTotal.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Date 12/29/2015\n * @author Tushar Roy\n *\n * Given array with unique numbers and a total,  find all triplets whose sum is less than total\n *\n * http://www.geeksforgeeks.org/count-triplets-with-sum-smaller-that-a-given-value/\n */\npublic class TripletSumLessThanTotal {\n\n    public int findAllTriplets(int input[], int total) {\n        Arrays.sort(input);\n        int result = 0;\n        for (int i = 0; i < input.length - 2; i++) {\n            int j = i + 1;\n            int k = input.length - 1;\n\n            while (j < k) {\n                if (input[i] + input[j] + input[k] >= total) {\n                    k--;\n                } else {\n                    result += k - j;\n                    j++;\n                }\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        int input[] = {5, 1, 3, 4, 7};\n        TripletSumLessThanTotal tt = new TripletSumLessThanTotal();\n        System.out.print(tt.findAllTriplets(input, 12));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/TugOfWar.java",
    "content": "package com.interview.array;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/*\n * http://www.geeksforgeeks.org/tug-of-war/\n */\npublic class TugOfWar {\n\n    private int minFoundSoFar = 1000000;\n    public int findMind(int arr[]){\n        int total = 0;\n        for(int i=0; i < arr.length; i++){\n            total += arr[i];\n        }\n        List<Integer> result = new ArrayList<>();\n        combinationUtil(arr,arr.length/2,0,0,total,0,result);\n        return minFoundSoFar;\n    }\n\n    private void combinationUtil(int arr[],int k, int start,int sum, int total,int pos, List<Integer> result){\n        if(pos == k){\n            if(Math.abs(sum - total/2) < minFoundSoFar) {\n                minFoundSoFar = Math.abs(sum - total/2);\n                System.out.println(result);\n            }\n            return;\n        }\n        for(int i=start; i < arr.length; i++){\n            sum += arr[i];\n            result.add(arr[i]);\n            combinationUtil(arr,k,i+1,sum,total,pos+1,result);\n            result.remove(result.size()-1);\n            sum -= arr[i];\n        }\n    }\n\n    public static void main(String args[]){\n        TugOfWar tow = new TugOfWar();\n        int arr[] = {23, 45, 34, 12,11, 98, 99, 4, 189, 1,7,19,105, 201};\n        int min = tow.findMind(arr);\n        System.out.print(min);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/WaterContainer.java",
    "content": "package com.interview.array;\n\n/**\n * Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).\n * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines,\n * which together with x-axis forms a container, such that the container contains the most water.\n *\n * https://leetcode.com/problems/container-with-most-water/\n */\npublic class WaterContainer {\n    public int maxArea(int[] height) {\n        int i = 0;\n        int j = height.length - 1;\n        int maxArea = 0;\n        while (i < j) {\n            if (height[i] < height[j]) {\n                maxArea = Math.max(maxArea, (height[i]) * (j - i));\n                i++;\n            } else {\n                maxArea = Math.max(maxArea, height[j] * (j - i));\n                j--;\n            }\n        }\n        return maxArea;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/WiggleSort.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Date 03/23/2016\n * @author Tushar Roy\n *\n * Convert an unsorted array into an array of form num[0] < num[1] > nums[2] < num[3]....\n * \n * Time complexity O(n) - This depends on KthElementInArray time\n * Space complexity O(1)\n *\n * https://leetcode.com/problems/wiggle-sort/\n * https://leetcode.com/problems/wiggle-sort-ii/\n */\npublic class WiggleSort {\n\n    //looking for nums[0] < nums[1] > nums[2] < nums[3] and so on.\n    public void wiggleSort2(int[] arr) {\n        if (arr.length == 0) {\n            return;\n        }\n        int k = arr.length/2;\n        KthElementInArray kthElementInArray = new KthElementInArray();\n        kthElementInArray.kthElement(arr, k);\n\n        int mid = arr[k];\n        int n = arr.length;\n        int i = 0, j = 0;\n        k = n - 1;\n        while (j <= k) {\n            if (arr[next(j, n)] > mid) {\n                swap(arr, next(i++, n), next(j++, n));\n            }\n            else if (arr[next(j, n)] < mid) {\n                swap(arr, next(j, n), next(k--, n));\n            }\n            else {\n                j++;\n            }\n        }\n    }\n\n    //in this version we are looking for nums[0] <= nums[1] >= nums[2] <= nums[3] and so on.\n    public void wiggleSort1(int[] nums) {\n        boolean flag = true;\n        for (int i = 0; i < nums.length - 1; i++) {\n            if (flag) {\n                if (nums[i] > nums[i + 1]) {\n                    swap(nums, i, i + 1);\n                }\n            } else {\n                if (nums[i] < nums[i + 1]) {\n                    swap(nums, i, i + 1);\n                }\n            }\n            flag = !flag;\n        }\n    }\n\n    private int next(int index, int n) {\n        return (2*index + 1) % (n | 1);\n    }\n\n    private void swap(int arr[],int low,int high){\n        int temp = arr[low];\n        arr[low] = arr[high];\n        arr[high] = temp;\n    }\n\n    public static void main(String args[]) {\n        WiggleSort ws = new WiggleSort();\n        int input[] =  {6, 2, 1, 6, 8, 9, 6};\n        ws.wiggleSort2(input);\n        System.out.print(Arrays.toString(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/array/ZigZagArrangement.java",
    "content": "package com.interview.array;\n\nimport java.util.Arrays;\n\n/**\n * Date 12/30/2015\n * @author Tushar Roy\n *\n * Given an array of unique elements rearrange the array to be a < b > c < d > e form\n *\n * Time complexity - O(n)\n * Space complexity - O(1)\n *\n * http://www.geeksforgeeks.org/convert-array-into-zig-zag-fashion/\n */\npublic class ZigZagArrangement {\n\n    public void rearrange(int input[]) {\n        boolean isLess = true;\n        for (int i = 0; i < input.length - 1; i++) {\n            if(isLess) {\n                if (input[i] > input[i+1]) {\n                    swap(input, i, i+1);\n                }\n            } else {\n                if (input[i] < input[i+1]) {\n                    swap(input, i, i+1);\n                }\n            }\n            isLess = !isLess;\n        }\n    }\n\n    private void swap(int input[], int i, int j) {\n        int t = input[i];\n        input[i] = input[j];\n        input[j] = t;\n    }\n\n    public static void main(String args[]) {\n        int input[] = {4, 3, 2, 6, 7, 1, 9};\n        ZigZagArrangement zza = new ZigZagArrangement();\n        zza.rearrange(input);\n        Arrays.stream(input).forEach(i -> System.out.print(i + \" \"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/ArithmeticProgressionSearch.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * http://www.careercup.com/question?id=4798365246160896\n */\npublic class ArithmeticProgressionSearch {\n\n    public int search(int input[]){\n        int low =0;\n        int high = input.length-1;\n        int ap = (input[high] - input[low])/(input.length);\n        int middle = -1;\n        while(low <= high){\n            middle = (low + high)/2;\n            if(input[middle] == input[0] + (middle)*ap){\n                low = middle+1;\n            }else if((input[middle] > input[0] + (middle)*ap) && \n                    input[middle-1] == input[0] + (middle-1)*ap){\n                return input[0] + (middle)*ap;\n            }else{\n                high = middle-1;\n            }\n        }\n        return -1;\n    }\n    public static void main(String args[]){\n        int input[] = {1,7,10,13,16,19,22};\n        ArithmeticProgressionSearch aps = new ArithmeticProgressionSearch();\n        System.out.println(aps.search(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/BinarySearch.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * Regular binary search\n */\npublic class BinarySearch {\n\n    public int search(final int input[], int search) {\n        int low = 0;\n        int high = input.length - 1;\n        int mid;\n        while (low <= high) {\n            mid = low + ((high - low) / 2);\n            if (input[mid] == search) {\n                return mid;\n            } else if (input[mid] < search) {\n                low = mid + 1;\n            } else {\n                high = mid - 1;\n            }\n        }\n        return -1;\n    }\n\n    public static void main(String args[]) {\n        BinarySearch bSearch = new BinarySearch();\n        final int arr1[] = {1, 2, 4, 5, 7, 8};\n        System.out.println(bSearch.search(arr1, -1));\n        System.out.println(bSearch.search(arr1, 1));\n        System.out.println(bSearch.search(arr1, 8));\n        System.out.println(bSearch.search(arr1, 2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/CircularBinarySearch.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * http://www.careercup.com/question?id=4877486110277632\n * Given a circle with N defined points and a point M outside the circle, \n * find the point that is closest to M among the set of N. O(LogN)\n * Test cases\n * 1) smallest element at center\n * 2) smallest element at left/right end\n * 3) largest element at center\n * 4) smallest element at left side\n * 5) smallest element at right side\n */\npublic class CircularBinarySearch {\n\n    //if mid is greater than both ends than result is low of two ends else move in direction\n    //where either mid-1 or mid+1 is less\n    public int search(int arr[]) {\n        int low = 0;\n        int high = arr.length - 1;\n        int mid = 0;\n        while (low < high) {\n            mid = (low + high) / 2;\n            //if middle is less than both mid-1 and mid+1 then mid is the answer\n            if((low == mid || arr[mid] < arr[mid-1])&& arr[mid] < arr[mid+1]){\n                return arr[mid];\n            }\n            if ((arr[mid] >= arr[low] && arr[mid] >= arr[high])){\n                if(arr[low] < arr[high]){\n                    high = mid-1;\n                }else{\n                    low = mid+1;\n                }\n            }else{\n                if(arr[mid-1] < arr[mid+1]){\n                    high = mid-1;\n                }else{\n                    low = mid+1;\n                }\n            }\n        }\n        return arr[low];\n    }\n\n    public static void main(String args[]) {\n        CircularBinarySearch cbs = new CircularBinarySearch();\n        int arr[] = { 7, 10, 8, 5, 2, 3, 5 };\n        System.out.print(cbs.search(arr));\n\n        int arr1[] = { 5, 8, 10, 7, 5, 3, 2 };\n        System.out.print(cbs.search(arr1));\n\n        int arr2[] = { 3, 5, 7, 10, 8, 5, 2 };\n        System.out.print(cbs.search(arr2));\n\n        int arr3[] = { 8, 5, 2, 3, 5, 7, 10 };\n        System.out.print(cbs.search(arr3));\n\n        int arr4[] = { 5, 3, 2, 5, 8, 10, 7 };\n        System.out.print(cbs.search(arr4));\n\n        int arr5[] = {100,20,10,5,2,8,11,16,19};\n        System.out.print(cbs.search(arr5));\n\n        int arr6[] = {200,2,10,15,20,80,110,160,190};\n        System.out.print(cbs.search(arr6));\n\n        int arr7[] = {5,10,20,50,200,800,1100,1600,1900,2};\n        System.out.print(cbs.search(arr7));\n\n        int arr8[] = {2,5,10,20,50,200,800,1100,1600,1900};\n        System.out.print(cbs.search(arr8));\n        \n        int arr9[] = {3,1,8,5,4};\n        System.out.print(cbs.search(arr9));\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/CountNDistinctPairsWithDifferenceK.java",
    "content": "package com.interview.binarysearch;\n\nimport java.util.Arrays;\n\n/**\n * http://www.geeksforgeeks.org/count-pairs-difference-equal-k/\n */\npublic class CountNDistinctPairsWithDifferenceK {\n\n    public int count(int arr[],int k){\n        Arrays.sort(arr);\n        int count = 0;\n        for(int i=0; i < arr.length; i++){\n            boolean result = binarySearch(arr, i+1, arr.length-1, arr[i] + k);\n            if(result){\n                count++;\n            }\n        }\n        return count;\n    }\n    \n    private boolean binarySearch(int arr[],int start,int end,int num){\n        if(start > end){\n            return false;\n        }\n        int mid = (start + end)/2;\n        if(arr[mid] == num){\n            return true;\n        }\n        else if(arr[mid] > num){\n            return binarySearch(arr,start,mid-1,num);\n        }else{\n            return binarySearch(arr,mid+1,end,num);\n        }\n    }\n    \n    public static void main(String args[]){\n        CountNDistinctPairsWithDifferenceK cn = new CountNDistinctPairsWithDifferenceK();\n        int arr[] = {1,2,3,4,5,7,9};\n        System.out.print(cn.count(arr, 3));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/FirstOccurrenceOfNumberInSortedArray.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * http://www.geeksforgeeks.org/check-for-majority-element-in-a-sorted-array/\n */\npublic class FirstOccurrenceOfNumberInSortedArray {\n\n    public int firstOccurrence(int input[], int x){\n        int low = 0;\n        int high = input.length-1;\n        \n        while(low <= high){\n            int middle = (low + high)/2;\n            if(input[middle] == x && (middle == 0 || input[middle-1] < x)){\n                return middle;\n            }else if(input[middle] < x){\n                low = middle+1;\n            }else{\n                high = middle-1;\n            }\n        }\n        return -1;\n    }\n    \n    public static void main(String args[]){\n        FirstOccurrenceOfNumberInSortedArray fos = new FirstOccurrenceOfNumberInSortedArray();\n        int input[] = {1,2,2,2,2,2,5,7,7};\n        System.out.println(fos.firstOccurrence(input, 6));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/FloorAndCeilingSortedArray.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * http://www.geeksforgeeks.org/search-floor-and-ceil-in-a-sorted-array/\n */\npublic class FloorAndCeilingSortedArray {\n\n    public int floor(int input[], int x){\n        int low = 0;\n        int high = input.length-1;\n        while(low <= high){\n            int middle = (low + high)/2;\n            if(input[middle] == x || (input[middle] < x && (middle == input.length-1 || input[middle+1] > x))){\n                return middle;\n            }else if(input[middle] < x){\n                low = middle+1;\n            }else{\n                high = middle-1;\n            }\n        }\n        return -1;\n    }\n\n    public int ceiling(int input[], int x){\n        int low = 0;\n        int high = input.length-1;\n        while(low <= high){\n            int middle = (low + high)/2;\n            if(input[middle] == x || (input[middle] > x && (middle == 0 || input[middle-1] < x))){\n                return middle;\n            }else if(input[middle] < x){\n                low = middle+1;\n            }else{\n                high = middle-1;\n            }\n        }\n        return -1;\n    }\n    \n    public static void main(String args[]){\n        int input[] = {1,2,5,6,11,15};\n        FloorAndCeilingSortedArray foc = new FloorAndCeilingSortedArray();\n        System.out.println(foc.floor(input, 15));\n        System.out.println(foc.ceiling(input, 2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/MedianOfTwoSortedArray.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * http://www.geeksforgeeks.org/median-of-two-sorted-arrays/\n */\npublic class MedianOfTwoSortedArray {\n\n    public double median(int arr1[],int arr2[]){\n        int low1 = 0;\n        int high1 = arr1.length-1;\n        \n        int low2 = 0;\n        int high2 = arr2.length-1;\n\n        while(true){\n            \n            if(high1 == low1){\n                return (arr1[low1] + arr2[low2])/2;\n            }\n            \n            if(high1 - low1 == 1){\n                return (double)(Math.max(arr1[low1], arr2[low2]) + Math.min(arr1[high1], arr2[high2]))/2;\n            }\n            \n            double med1 = getMedian(arr1,low1,high1);\n            double med2 = getMedian(arr2,low1,high2);\n            if(med1 <= med2){\n                if((high1-low1 + 1) % 2 == 0){\n                    low1 = (high1+low1)/2;\n                    high2 = (high2+low2)/2 + 1;\n                }else{\n                    low1 = (low1+high1)/2;\n                    high2 = (low2+high2)/2;\n                }\n            }\n            else{\n                if((high1-low1 + 1) % 2 == 0){\n                    low2 = (high2+low2)/2;\n                    high1 = (high1+low1)/2 + 1;\n                }else{\n                    low2 = (low2+high2)/2;\n                    high1 = (low1+high1)/2;\n                }\n            }\n        }\n    }\n    \n    private double getMedian(int arr[],int low,int high){\n        int len = high - low+1;\n        if(len % 2 == 0){\n            return (arr[low + len/2] + arr[low+ len/2-1])/2;\n        }else{\n            return arr[low+len/2];\n        }\n    }\n    \n    public static void main(String args[]){\n        int arr1[] = {1,2,3,4,6};\n        int arr2[] = {-1,5,6,7,8};\n        MedianOfTwoSortedArray mts = new MedianOfTwoSortedArray();\n        System.out.println(mts.median(arr1, arr2));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * There are two sorted arrays nums1 and nums2 of size m and n respectively.\n * Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).\n *\n * Solution\n * Take minimum size of two array. Possible number of partitions are from 0 to m in m size array.\n * Try every cut in binary search way. When you cut first array at i then you cut second array at (m + n + 1)/2 - i\n * Now try to find the i where a[i-1] <= b[j] and b[j-1] <= a[i]. So this i is partition around which lies the median.\n *\n * Time complexity is O(log(min(x,y))\n * Space complexity is O(1)\n *\n * https://leetcode.com/problems/median-of-two-sorted-arrays/\n * https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation/4\n */\npublic class MedianOfTwoSortedArrayOfDifferentLength {\n\n    public double findMedianSortedArrays(int input1[], int input2[]) {\n        //if input1 length is greater than switch them so that input1 is smaller than input2.\n        if (input1.length > input2.length) {\n            return findMedianSortedArrays(input2, input1);\n        }\n        int x = input1.length;\n        int y = input2.length;\n\n        int low = 0;\n        int high = x;\n        while (low <= high) {\n            int partitionX = (low + high)/2;\n            int partitionY = (x + y + 1)/2 - partitionX;\n\n            //if partitionX is 0 it means nothing is there on left side. Use -INF for maxLeftX\n            //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX\n            int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1];\n            int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX];\n\n            int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1];\n            int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY];\n\n            if (maxLeftX <= minRightY && maxLeftY <= minRightX) {\n                //We have partitioned array at correct place\n                // Now get max of left elements and min of right elements to get the median in case of even length combined array size\n                // or get max of left for odd length combined array size.\n                if ((x + y) % 2 == 0) {\n                    return ((double)Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY))/2;\n                } else {\n                    return (double)Math.max(maxLeftX, maxLeftY);\n                }\n            } else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side.\n                high = partitionX - 1;\n            } else { //we are too far on left side for partitionX. Go on right side.\n                low = partitionX + 1;\n            }\n        }\n\n        //Only we we can come here is if input arrays were not sorted. Throw in that scenario.\n        throw new IllegalArgumentException();\n    }\n\n    public static void main(String[] args) {\n        int[] x = {1, 3, 8, 9, 15};\n        int[] y = {7, 11, 19, 21, 18, 25};\n\n        MedianOfTwoSortedArrayOfDifferentLength mm = new MedianOfTwoSortedArrayOfDifferentLength();\n        mm.findMedianSortedArrays(x, y);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/MinimumInSortedRotatedArray.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/\n */\npublic class MinimumInSortedRotatedArray {\n    public int findMin(int[] nums) {\n        int low = 0;\n        int high = nums.length - 1;\n        while (low < high) {\n            int middle = (low + high)/2;\n            if ((middle == 0 && nums[middle] < nums[middle + 1]) || (middle > 0 && nums[middle] < nums[middle - 1])) {\n                return nums[middle];\n            }\n            else if (nums[middle] > nums[high]) {\n                low = middle + 1;\n            } else {\n                high = middle - 1;\n            }\n        }\n        return nums[low];\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/MissingNumberInConsecutiveNumbers.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * Find missing number in consecutive numbers.\n */\npublic class MissingNumberInConsecutiveNumbers {\n\n    public Integer findMissing(int arr[]){\n    \n        int lowNum = arr[0];\n        int low = 0;\n        int high = arr.length -1;\n        int middle = (low + high)/2;\n        while(low <= high){\n            middle = (low + high)/2;\n            if(arr[middle] == (middle+1 + lowNum) && middle-1 >=0 && arr[middle-1] == (middle + lowNum-1)){\n                return middle + lowNum;\n            }\n            else if((middle + lowNum) == arr[middle]){\n                low = middle+1;\n            }else {\n                high = middle-1;\n            }\n        }\n        return null;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {3,4,5,6,7,8,9,10,11,12};\n        int arr1[] = {-5,-4,-3,-1,0,1,2,3};\n        MissingNumberInConsecutiveNumbers mn = new MissingNumberInConsecutiveNumbers();\n        System.out.println(mn.findMissing(arr1));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/MonotonicallyIncreasingFunctionBecomesPositive.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * http://www.geeksforgeeks.org/find-the-point-where-a-function-becomes-negative/\n */\npublic class MonotonicallyIncreasingFunctionBecomesPositive {\n\n    private int f(int x){\n        return x*x - 10*x - 20;\n    }\n    \n    public int findPoint(){\n        int i=1;\n        while(f(i) <=0 ){\n            i = i*2;\n        }\n        return binarySearch(i/2,i);\n    }\n    \n    private int binarySearch(int start,int end){\n        int mid = (start+end)/2;\n        while(start < end){\n            mid = (start+end)/2;\n            if(f(mid) >0 && f(mid-1) <=0){\n                return mid;\n            }\n            if(f(mid) <=0 && f(mid+1)>0){\n                return mid+1;\n            }\n            if(f(mid) <= 0){\n                start = mid+1;\n            }else{\n                end = mid-1;\n            }\n        }\n        return mid;\n    }\n    \n    public static void main(String args[]){\n        MonotonicallyIncreasingFunctionBecomesPositive mif = new MonotonicallyIncreasingFunctionBecomesPositive();\n        System.out.print(mif.findPoint());\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/NumberOfPairWithXPowerYGreaterThanYPowerX.java",
    "content": "package com.interview.binarysearch;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * http://www.geeksforgeeks.org/find-number-pairs-xy-yx/\n */\npublic class NumberOfPairWithXPowerYGreaterThanYPowerX {\n\n    public int countPairs(int X[],int Y[]){\n        Map<Integer,Integer> hardCoded = new HashMap<Integer,Integer>();\n        for(int i=0; i < Y.length; i++){\n            if(Y[i] < 4){\n                Integer count = hardCoded.get(Y[i]);\n                if(count != null){\n                    hardCoded.put(Y[i], count++);\n                }else{\n                    hardCoded.put(Y[i], 1);\n                }\n            }\n        }\n        Arrays.sort(Y);\n        int countPairs = 0;\n        for(int i=0 ; i < X.length; i++){\n            countPairs += count(X[i],Y,hardCoded);\n        }\n        return countPairs;\n    }\n    \n    private int count(int x, int Y[],Map<Integer,Integer> hardCount){\n        \n        if(x == 0){\n            return 0;\n        }\n        if(x == 1){\n            return upperBound(0,Y);\n        }\n        int result = Y.length - upperBound(x,Y);\n        result +=  (hardCount.containsKey(1) ? hardCount.get(1) : 0 ) + (hardCount.containsKey(0) ? hardCount.get(0) : 0);\n    \n        if(x == 2){\n            result -= (hardCount.containsKey(3)  ? hardCount.get(3) : 0);\n        }\n        if(x == 3){\n            result += (hardCount.containsKey(2)  ? hardCount.get(2) : 0);\n        }\n        return result;\n    }\n    \n    private int upperBound(int x, int arr[]){\n        int low = 0;\n        int high = arr.length-1;\n        while(low <= high){\n            int mid = (low+high)/2;\n            if(arr[mid] > x && (mid-1 < 0 || arr[mid-1] <= x)){\n                return mid;\n            }else if(arr[mid] > x){\n                high = mid-1;\n            }else{\n                low = mid+1;\n            }\n        }\n        return -1;\n        \n    }\n    \n    public static void main(String args[]){\n        NumberOfPairWithXPowerYGreaterThanYPowerX nop = new NumberOfPairWithXPowerYGreaterThanYPowerX();\n        int X[] = {7,9,5,8,9,11,0,1,1,3};\n        int Y[] = {6,8,9,11,14,5,1,0,2,3,9};\n        System.out.println(nop.countPairs(X, Y));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/PeakElement.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * @author Tushar Roy\n * Date 01/17/2107\n * A peak element is an element that is greater than its neighbors. Find index of peak element in the array.\n *\n * Space complexity is O(1)\n * Time complexity is O(n)\n *\n * https://leetcode.com/problems/find-peak-element/\n */\npublic class PeakElement {\n\n    public int findPeakElement(int[] nums) {\n        int low = 0;\n        int high = nums.length - 1;\n        int middle = 0;\n        while (low <= high) {\n            middle = (low + high)/2;\n            int before = Integer.MIN_VALUE;\n            if (middle > 0) {\n                before = nums[middle - 1];\n            }\n            int after = Integer.MIN_VALUE;\n            if (middle < nums.length - 1) {\n                after = nums[middle + 1];\n            }\n            if (nums[middle] > before && nums[middle] > after) {\n                return middle;\n            } else if (before > after) {\n                high = middle - 1;\n            } else {\n                low = middle + 1;\n            }\n        }\n        return middle;\n    }\n\n    public static void main(String args[]){\n        int arr[] = {10,5,15,2,23,90,67};\n        PeakElement pe = new PeakElement();\n        System.out.println(pe.findPeakElement(arr));\n        int arr1[] = {10,20,30,40,50};\n        System.out.println(pe.findPeakElement(arr1));\n        int arr2[] = {100,90,80,70,60};\n        System.out.println(pe.findPeakElement(arr2));\n                \n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/SearchForRange.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * Date 07/31/2016\n * @author Tushar Roy\n *\n * Given a sorted array of integers, find the starting and ending position of a given target value.\n *\n * Time complexity O(logn)\n * Space complexity O(1)\n * \n * https://leetcode.com/problems/search-for-a-range/\n */\npublic class SearchForRange {\n    public int[] searchRange(int[] nums, int target) {\n        int first = firstOccurence(nums, target);\n        if (first == -1) {\n            return new int[]{-1, -1};\n        }\n        int last = lastOccurence(nums, target);\n        return new int[]{first, last};\n    }\n\n    private int firstOccurence(int[] nums, int target) {\n        int low = 0;\n        int high = nums.length - 1;\n        while (low <= high) {\n            int mid = low + (high - low)/2;\n            if (nums[mid] == target && (mid == 0 || nums[mid - 1] < target)) {\n                return mid;\n            } else if (nums[mid] >= target) {\n                high = mid - 1;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return -1;\n    }\n\n    private int lastOccurence(int[] nums, int target) {\n        int low = 0;\n        int high = nums.length - 1;\n        while (low <= high) {\n            int mid = low + (high - low)/2;\n            if (nums[mid] == target && (mid == nums.length - 1 || nums[mid + 1] > target)) {\n                return mid;\n            } else if (nums[mid] <= target) {\n                low = mid + 1;\n            } else {\n                high = mid - 1;\n            }\n        }\n        return -1;\n    }\n\n    public static void main(String args[]) {\n        SearchForRange searchForRange = new SearchForRange();\n        int[] nums = {0, 1, 1, 3, 6, 9, 11};\n        int[] r = searchForRange.searchRange(nums, 11);\n        System.out.println(r[0] + \" \" + r[1]);\n        r = searchForRange.searchRange(nums, 0);\n        System.out.println(r[0] + \" \" + r[1]);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/SearchInsertPosition.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * https://leetcode.com/problems/search-insert-position/\n */\npublic class SearchInsertPosition {\n    public int searchInsert(int[] nums, int target) {\n        int low = 0;\n        int high = nums.length - 1;\n        while (low <= high) {\n            int middle = (low + high)/2;\n            if (nums[middle] == target) {\n                return middle;\n            }\n            if (nums[middle] < target && (middle == nums.length - 1 ||  nums[middle + 1] > target)) {\n                return middle + 1;\n            }\n            if (nums[middle] < target) {\n                low = middle + 1;\n            } else {\n                high = middle - 1;\n            }\n        }\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/SortedAndRotatedArraySearch.java",
    "content": "package com.interview.binarysearch;\n\n/**\n * @author Tushar Roy\n * Date 01/22/17\n *\n * Search in sorted and rotated array. In one version duplicate is not allowed and\n * in another version duplicate is allowed.\n *\n * Time complexity with no duplicate - O(logn)\n * Time complexity with duplicates - O(n)\n *\n * https://leetcode.com/problems/search-in-rotated-sorted-array/\n * https://leetcode.com/problems/search-in-rotated-sorted-array-ii/\n */\npublic class SortedAndRotatedArraySearch {\n\n    /**\n     * Duplicates are not allowed in arr.\n     */\n    public int search(int arr[],int search){\n        int low =0;\n        int high = arr.length-1;\n        while(low <= high){\n            int mid = (low + high)/2;\n            if(arr[mid] == search){\n                return mid;\n            }\n            \n            if(arr[mid] < arr[high]){\n                if(arr[mid] < search && search <= arr[high]){\n                    low = mid+1;\n                }else{\n                    high = mid-1;\n                }\n            }else{\n                if(search >= arr[low] && search < arr[mid]){\n                    high = mid-1;\n                }else{\n                    low = mid+1;\n                }\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Duplicates are allowed in arr.\n     */\n    public boolean searchWithDuplicates(int[] arr, int search) {\n        int low =0;\n        int high = arr.length-1;\n        while(low <= high){\n            int mid = (low + high)/2;\n            if(arr[mid] == search) {\n                return true;\n            }\n            //if low is same as mid then increment low.\n            if (arr[mid] == arr[low]) {\n                low++;\n            } else if (arr[mid] == arr[high]) { //if high is same as mid then decrement high.\n                high--;\n            } else if (arr[mid] < arr[high]) {\n                if(arr[mid] < search && search <= arr[high]) {\n                    low = mid + 1;\n                } else {\n                    high = mid - 1;\n                }\n            } else {\n                if(search >= arr[low] && search < arr[mid]) {\n                    high = mid - 1;\n                } else {\n                    low = mid + 1;\n                }\n            }\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        SortedAndRotatedArraySearch ras = new SortedAndRotatedArraySearch();\n        int arr1[] = {1,2,5,6,7,8,11,21};\n        System.out.print(ras.search(arr1, 1));\n        System.out.print(ras.search(arr1, 5));\n        System.out.print(ras.search(arr1, 22));\n        System.out.println();\n    \n        int arr2[] = {18,21,1,2,5,6,7,8,10,15};\n        System.out.print(ras.search(arr2, 1));\n        System.out.print(ras.search(arr2, 5));\n        System.out.print(ras.search(arr2, 10));\n        System.out.print(ras.search(arr2, 14));\n        System.out.println();\n\n        int arr3[] = {7,8,15,17,18,21,1,2,5,6};\n        System.out.print(ras.search(arr3, 1));\n        System.out.print(ras.search(arr3, 5));\n        System.out.print(ras.search(arr3, 10));\n        System.out.print(ras.search(arr3, 7));\n        System.out.print(ras.search(arr3, 6));\n        System.out.print(ras.search(arr3, 16));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/binarysearch/SquareRootOfNumber.java",
    "content": "package com.interview.binarysearch;\n\n/**\n *\n * https://leetcode.com/problems/sqrtx/\n */\npublic class SquareRootOfNumber {\n    public int mySqrt(int x) {\n        if (x == 0)\n            return 0;\n        int left = 1, right = x;\n        while (true) {\n            int mid = left + (right - left)/2;\n            if (mid > x/mid) {\n                right = mid - 1;\n            } else {\n                if (mid + 1 > x/(mid + 1))\n                    return mid;\n                left = mid + 1;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/AddTwoNumberInBinaryRepresentation.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.geeksforgeeks.org/add-two-bit-strings/\n * http://www.geeksforgeeks.org/binary-representation-of-a-given-number/\n * http://www.geeksforgeeks.org/add-two-numbers-without-using-arithmetic-operators/\n */\npublic class AddTwoNumberInBinaryRepresentation {\n\n    public int add(char[] num1,char[] num2){\n        int index1 = num1.length -1;\n        int index2 = num2.length -1;\n        int carry = 0;\n        int result = 0;\n        int index = 0;\n        while(index1 >= 0 && index2 >= 0){\n            int r1 = num1[index1] - '0';\n            int r2 = num2[index2] - '0';\n            result = result | (r1^r2^carry)<<index;\n            index1--;\n            index2--;\n            index++;\n            carry = r1 & carry | r2 & carry | r1 & r2;\n        }\n        while(index1 >= 0){\n            int r1 = num1[index1] - '0';\n            result = result | (r1^carry)<<index;\n            index1--;\n            index++;\n            carry = r1 & carry;\n        }\n        while(index2 >= 0){\n            int r2 = num1[index2] - '0';\n            result = result | (r2^carry)<<index;\n            index2--;\n            index++;\n            carry = r2 & carry;\n        }\n        return result;\n    }\n    \n    public int addTwoNumbersWithoutArithmeticOperator(int num1,int num2){\n        int carry = 0;\n        int result = 0;\n        for(int i=0; i <=31; i++){\n            int r1 = (num1 & 1<<i) != 0 ? 1 : 0;\n            int r2 = (num2 & 1<<i) !=0 ? 1 : 0;\n            \n            result = result | (r1^r2^carry)<<i;\n            if((r1 & r2) != 0 || (r1 & carry) != 0 || (r2 & carry) != 0){\n                carry = 1;\n            }else{\n                carry = 0;\n            }\n        }\n        return result;\n    }\n    \n    public int addTwoNumbersWithoutArithmeticOperatorFaster(int num1,int num2){\n        while(num2 != 0){\n            int carry = num1 & num2;\n            num1 = num1 ^ num2;\n            num2 = carry << 1;\n        }\n        return num1;\n    }\n    \n    public void printResult(int num){\n        for(int i= 1<<31; i !=0 ; i = i>>>1){\n            if((num & i) > 0){\n                System.out.print(\"1\");\n            }else{\n                System.out.print(\"0\");\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        AddTwoNumberInBinaryRepresentation anp = new AddTwoNumberInBinaryRepresentation();\n        char num1[] = \"1010001110\".toCharArray();\n        char num2[] = \"10011\".toCharArray();\n        int result = anp.add(num1, num2);\n        System.out.println(anp.addTwoNumbersWithoutArithmeticOperator(296, 5662));\n        System.out.println(anp.addTwoNumbersWithoutArithmeticOperatorFaster(296, 5662));\n        anp.printResult(result);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/bits/BitRotation.java",
    "content": "package com.interview.bits;\n\n/*\n * http://www.geeksforgeeks.org/rotate-bits-of-an-integer/\n */\npublic class BitRotation {\n\n    public byte rotateLeft(byte num, int d){\n        return (byte)((num << d) | (num >>> (8-d)));\n    }\n    \n    public static void main(String args[]){\n        BitRotation br = new BitRotation();\n        System.out.println(br.rotateLeft((byte)28, 2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/ByteAsStorage.java",
    "content": "package com.interview.bits;\n\npublic class ByteAsStorage {\n\n    void useByteAsBoolean(boolean[] visited){\n        byte[] bytes = new byte[(int)(Math.ceil(visited.length*1.0/8))];\n        for(int i=0; i < visited.length; i++){\n            int row = i/8;\n            int col = i%8;\n            if(visited[i]){\n                bytes[row] = (byte)(bytes[row] | (byte)(1<<col));\n            }else{\n                bytes[row] = (byte)(bytes[row] & ~(byte)(1<<col));\n            }\n        }\n        \n        for(int i=0; i < visited.length; i++){\n            int row = i/8;\n            int col = i%8;\n            if((bytes[row] & 1<<col) >= 1){\n                System.out.print(\"True\");\n            }else{\n                System.out.print(\"False\");\n            }\n        }\n    }\n    public static void main(String args[]){\n        boolean visited[] = {true,false,true,true,false};\n        ByteAsStorage bas = new ByteAsStorage();\n        bas.useByteAsBoolean(visited);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/CountBits.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.geeksforgeeks.org/count-set-bits-in-an-integer/\n */\npublic class CountBits {\n\n    public CountBits(){\n        preCalculate();\n    }\n    public int countBits(int num){\n        int count=0;\n        while(num > 0){\n            num &= num-1;\n            count++;\n        }\n        return count;\n    }\n    \n    private int count[] = new int[256];\n    \n    void preCalculate(){\n        for(int i=0; i < 256; i++){\n            count[i] = countBits(i);\n        }\n    }\n    \n    public int countBitsFaster(int num){\n        //get 8 bits at a time and check count from count array\n        int total = 0;\n        int mask = (1<<8) - 1;\n        for(int i=0 ; i < 4; i++){\n            total += count[num & mask];\n            num = num>>>8;\n        }\n        return total;\n    }\n    \n    //http://bits.stephan-brumme.com/countBits.html\n    public int countBitsEvenFaster(int x){\n        // count bits of each 2-bit chunk\n        x = x - ((x >> 1) & 0x55555555);\n        // count bits of each 4-bit chunk\n        x = (x & 0x33333333) + ((x >> 2) & 0x33333333);\n        // count bits of each 8-bit chunk\n        x = x + (x >> 4);\n        // mask out junk\n        x &= 0xF0F0F0F;\n        // add all four 8-bit chunks\n        return (x * 0x01010101) >> 24;\n    }\n\n    public static void main(String args[]){\n        CountBits cb = new CountBits();\n        System.out.println(cb.countBits(3636363));\n        System.out.println(cb.countBitsFaster(3636363));\n        System.out.println(cb.countBitsEvenFaster(3636363));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/CountingBitsTillNum.java",
    "content": "package com.interview.bits;\n\n/**\n * Date 04/03/2016\n * @author Tushar Roy\n *\n * Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate\n * the number of 1's in their binary representation and return them as an array.\n *\n * Time complexity O(n)\n * Space complexity O(n)\n *\n * https://leetcode.com/problems/counting-bits/\n */\npublic class CountingBitsTillNum {\n    public int[] countBits(int num) {\n        if (num == 0) {\n            return new int[1];\n        }\n        int[] count = new int[num + 1];\n        count[0] = 0;\n        int n = 1;\n        int start = n;\n        while (start <= num) {\n            start = n;\n            count[start++] = 1;\n            int end = n<<1;\n            while (start < end && start <= num) {\n                count[start] = 1 + count[start - n];\n                start++;\n            }\n            n = n<<1;\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/DrawHorizontalLine.java",
    "content": "package com.interview.bits;\n\n/**\n * Exercise 5.8 150qs \n */\npublic class DrawHorizontalLine {\n\n    public void draw(byte[] screen, int width, int x1, int x2,int y){\n        int pos1 = y*width + x1;\n        int pos2 = y*width + x2;\n        \n        int start = pos1;\n        while(start <= pos2){\n            int row = start/8;\n            int col = start%8;\n            \n            screen[row] = (byte)(screen[row] | 1<<col);\n            start++;\n        }\n        printScreen(screen,width);\n    }\n    \n    public void drawFaster(byte[] screen,int width,int x1,int x2,int y){\n        int pos1 = y*width + x1;\n        int pos2 = y*width + x2;\n        \n        int row1 = pos1/8;\n        int col1= pos1%8;\n        \n        int row2 = pos2/8;\n        int col2= pos2%8;\n\n        int mask = ~((1<<col1) -1);\n        screen[row1] = (byte)(screen[row1] | mask);\n        \n        mask = ((1<<(col2+1)) -1);\n        screen[row2] = (byte)(screen[row2] | mask);\n        \n        while(row1 + 1 < row2){\n            screen[row1+1] = (byte)(screen[row1+1] | 0xFF);\n            row1++;\n        }\n        \n        printScreen(screen,width);\n    }\n    \n    private void printScreen(byte[] screen,int width){\n        int w = width/8;\n        for(int i=0; i < screen.length; i++){\n            if(i%w == 0){\n                System.out.println();\n            }\n            for(int j=0; j < 8; j++){\n                if((screen[i] & 1<<j) != 0){\n                    System.out.print(\"*\");\n                }else{\n                    System.out.print(\"+\");\n                }\n            }\n        }\n    }\n    \n    \n    public static void main(String args[]){\n        byte[] screen = {0,0,0,0,0,0,0,0,0};\n        DrawHorizontalLine dwl = new DrawHorizontalLine();\n        dwl.drawFaster(screen, 24,1 , 22, 1);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/FindNumberOccurringOnceOtherNumbers3Times.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.geeksforgeeks.org/find-the-element-that-appears-once/\n */\npublic class FindNumberOccurringOnceOtherNumbers3Times {\n\n    public int getNumberOccurringOnce(int arr[]){\n        int result = 0;\n        for(int i=0; i < 32; i++){\n            int sum = 0;\n            for(int j=0; j < arr.length; j++){\n                sum += (arr[j] & 1<<i)>>i; \n            }\n            result = result | (sum%3)<<i;\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        FindNumberOccurringOnceOtherNumbers3Times fno = new FindNumberOccurringOnceOtherNumbers3Times();\n        int arr[] = {1,1,2,5,6,1,6,6,2,2};\n//      int arr[] = {1,1,1,4,1,1,1};\n        System.out.println(fno.getNumberOccurringOnce(arr));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/GrayCode.java",
    "content": "package com.interview.bits;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Date 03/12/2016\n * @author Tushar Roy\n *\n * Get first n gray code\n * Reference\n * https://leetcode.com/problems/gray-code/\n */\npublic class GrayCode {\n    public List<Integer> grayCode(int n) {\n        List<Integer> result = new LinkedList<>();\n        for (int i = 0; i < 1<<n; i++) {\n            result.add(i ^ i>>1);\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        GrayCode gc = new GrayCode();\n        System.out.println(gc.grayCode(4));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/InsertMintoNiTojBits.java",
    "content": "package com.interview.bits;\n\n/**\n * Exercise 5.1 150 qs\n */\npublic class InsertMintoNiTojBits {\n    \n    public int insert(int M,int N, int i, int j){\n        int  mask = 1<<(j+1) -1;\n        mask = mask<<i;\n        mask = ~mask;\n        \n        N = N & mask;\n        N = N | M << i;\n        return N;\n    }\n    \n    public static void main(String args[]){\n        int N = 0;\n        int M = 35;\n        InsertMintoNiTojBits imn = new InsertMintoNiTojBits();\n        int result = imn.insert(M,N,3,8);\n        System.out.println(result);\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/MaxProductWordLength.java",
    "content": "package com.interview.bits;\n\nimport java.util.Arrays;\n\n/**\n * Date 04/21/2016\n * @author Tushar Roy\n *\n * Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words\n * do not share common letters. You may assume that each word will contain only lower case letters.\n * If no such two words exist, return 0.\n *\n * Space complexity O(n)\n * Time complexity O(n^2)\n *\n * https://leetcode.com/problems/maximum-product-of-word-lengths/\n */\npublic class MaxProductWordLength {\n    public int maxProduct(String[] words) {\n        int max = 0;\n\n        Arrays.sort(words, (a, b) -> b.length() - a.length());\n\n        int[] masks = new int[words.length]; // alphabet masks\n\n        for(int i = 0; i < masks.length; i++){\n            for(char c: words[i].toCharArray()){\n                masks[i] |= 1 << (c - 'a');\n            }\n        }\n\n        for(int i = 0; i < masks.length; i++){\n            if(words[i].length() * words[i].length() <= max) {\n                break; //prunning\n            }\n            for(int j = i + 1; j < masks.length; j++){\n                if((masks[i] & masks[j]) == 0){\n                    max = Math.max(max, words[i].length() * words[j].length());\n                    break; //prunning\n                }\n            }\n        }\n\n        return max;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/MissingNumbers.java",
    "content": "package com.interview.bits;\n\nclass Pair{\n    int x;\n    int y;\n}\n\n/**\n * http://www.geeksforgeeks.org/find-the-two-repeating-elements-in-a-given-array/\n * http://www.geeksforgeeks.org/find-a-repeating-and-a-missing-number/\n */\npublic class MissingNumbers {\n\n    public Pair findMissingAndRepeated(int arr[], int n){\n        int xor = 0;\n        for(int i=0; i < arr.length; i++){\n            xor = xor ^ arr[i];\n        }\n        \n        for(int i=1; i <= n; i++){\n            xor = xor ^ i;\n        }\n        \n        xor = xor & ~(xor-1);\n        int set1 = 0;\n        int set2 = 0;\n        for(int i=0; i < arr.length; i++){\n            if((arr[i] & xor) > 0){\n                set1 ^= arr[i];\n            }else{\n                set2 ^= arr[i];\n            }\n        }\n        Pair p = new Pair();\n        for(int i=1; i <= n; i++){\n            if((i & xor) > 0){\n                set1 ^= i;\n            }else{\n                set2 ^= i;\n            }\n        }\n        p.x = set1;\n        p.y = set2;\n        return p;\n    }\n    \n    public Pair findTwoMissingNumber(int arr[], int n){\n        int xor = 0;\n        for(int i=0; i < arr.length; i++){\n            xor = xor ^ arr[i];\n        }\n        \n        for(int i=1; i <= n; i++){\n            xor = xor ^ i;\n        }\n        \n        xor = xor & ~(xor-1);\n        int set1 = 0;\n        int set2 = 0;\n        for(int i=0; i < arr.length; i++){\n            if((arr[i] & xor) > 0){\n                set1 ^= arr[i];\n            }else{\n                set2 ^= arr[i];\n            }\n        }\n        Pair p = new Pair();\n        for(int i=1; i <= n; i++){\n            if((i & xor) > 0){\n                set1 ^= i;\n            }else{\n                set2 ^= i;\n            }\n        }\n        p.x = set1;\n        p.y = set2;\n        return p;\n    }\n    \n    public static void main(String args[]){\n        MissingNumbers mn = new MissingNumbers();\n        int arr[] = {1,2,3,5,5};\n        Pair p = mn.findMissingAndRepeated(arr, 5);\n        System.out.println(p.x + \" \" + p.y);\n        int arr1[] = {1,5,3,6};\n        p = mn.findMissingAndRepeated(arr1, 6);\n        System.out.println(p.x + \" \" + p.y);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/NextHigherAndNextLowerWithSameNumberBits.java",
    "content": "package com.interview.bits;\n\n/**\n * Exercise 5.3 150 qs\n */\npublic class NextHigherAndNextLowerWithSameNumberBits {\n\n    public int nextHigher(int n){\n        int i = 1;\n        int first1 = 0;\n        //go till you find first 1\n        while((n & i) == 0){\n            i = i << 1;\n            first1++;\n        }\n        //count number of 1s before first 0\n        int count1s = 0;\n        while((n & i) > 0){\n            i = i <<1;\n            count1s++;\n        }\n        count1s--;\n        //change this first 0 after 1 to 1\n        n = n^i;\n        n = n ^ (i>>1);\n        int mask = ~(1<<(first1 + count1s) -1);\n        n = mask & n;\n        n = n | ((1<<count1s) -1);\n        return n;\n    }\n    \n    public int nextLower(int n){\n        if(n ==0){\n            return 0;\n        }\n        int i = 1;\n        int first0 = 0;\n        while((n & i) > 0){\n            i = i << 1;\n            first0++;\n        }\n        int count0s = 0;\n        while((n & i) == 0){\n            i = i <<1;\n            count0s++;\n        }\n        count0s--;\n        //change this first 0 after 1 to 1\n        n = n^i;\n        n = n ^ (i>>1);\n        int mask = (1<<first0) -1;\n        n = n ^ mask;\n        n = n | (mask<<count0s);\n        return n;\n        \n    }\n    public static void main(String args[]){\n        NextHigherAndNextLowerWithSameNumberBits nhn = new NextHigherAndNextLowerWithSameNumberBits();\n        System.out.println(nhn.nextHigher(94));\n        System.out.println(nhn.nextLower(10));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/NextPowerOf2.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.geeksforgeeks.org/next-power-of-2/\n */\npublic class NextPowerOf2 {\n\n    public int nextPowerOf2(int num){\n        if(num ==0){\n            return 1;\n        }\n        if(num > 0 && (num & (num-1)) == 0){\n            return num;\n        }\n        while((num & (num-1)) > 0){\n            num = num & (num-1);\n        }\n        return num<<1;\n    }\n    public static void main(String args[]){\n        NextPowerOf2 np = new NextPowerOf2();\n        System.out.println(np.nextPowerOf2(4));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/NumberOccuringOddTimes.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.geeksforgeeks.org/find-the-number-occurring-odd-number-of-times/\n * http://www.geeksforgeeks.org/find-two-non-repeating-elements-in-an-array-of-repeating-elements/\n */\npublic class NumberOccuringOddTimes {\n\n    public int oneNumberOccuringOddTimes(int arr[]){\n        int r = 0;\n        for(int i=0; i < arr.length; i++){\n            r = r^arr[i];\n        }\n        return r;\n    }\n    \n    class Pair{\n        int a;\n        int b;\n        \n    }\n    \n    public Pair twoNumbersOccuringOddTimes(int arr[]){\n        int r = 0;\n        for(int i=0; i < arr.length; i++){\n            r = r^arr[i];\n        }\n    \n        r = r & ~(r-1);\n        int r1 = 0;\n        int r2 = 0;\n        for(int i=0; i < arr.length; i++){\n            if((r&arr[i]) == 0){\n                r1 = r1^arr[i];\n            }else{\n                r2 = r2^arr[i];\n            }\n        }\n        Pair p = new Pair();\n        p.a = r1;\n        p.b = r2;\n        return p;\n    }\n    \n    public static void main(String args[]){\n        NumberOccuringOddTimes noot = new NumberOccuringOddTimes();\n        int arr[] = {1,2,9,9,2,1,9,7,2,1,9,1};\n        Pair p = noot.twoNumbersOccuringOddTimes(arr);\n        System.out.print(p.a + \" \" + p.b);\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/bits/NumberOfBitsFlipToConvertNToM.java",
    "content": "package com.interview.bits;\n\n/**\n * Exercise 5.5 150 qs\n */\npublic class NumberOfBitsFlipToConvertNToM {\n\n    public int number(int m, int n){\n        int r = n^m;\n        int count = 0;\n        while(r != 0){\n            r = r & (r-1);\n            count++;\n        }\n        return count;\n    }\n    public static void main(String args[]){\n        NumberOfBitsFlipToConvertNToM nb = new NumberOfBitsFlipToConvertNToM();\n        System.out.println(nb.number(31, 14));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/RealNumberToBinary.java",
    "content": "package com.interview.bits;\n\n/**\n * Exercise 5.2 150 qs\n */\npublic class RealNumberToBinary {\n\n    public void print(double num){\n        if(num > 1 || num < 0){\n            System.out.println(\"ERROR\");\n            return;\n        }\n        \n        StringBuilder stringBuilder = new StringBuilder();\n        stringBuilder.append(\"0.\");\n        while(num > 0){\n            num = num*2;\n            int r = (int)num ;\n            stringBuilder.append(r);\n            num = num -r;\n            if(stringBuilder.length() > 32){\n                System.out.println(\"ERROR\");\n                return;\n            }\n        }\n        System.out.println(stringBuilder);\n    }\n    public static void main(String args[]){\n        RealNumberToBinary rnb = new RealNumberToBinary();\n        rnb.print(0.8125);\n        rnb.print(0.72);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/RepeatedDnaSequence.java",
    "content": "package com.interview.bits;\n\nimport java.util.*;\n\n/**\n * Date 03/08/2016\n * @author Tushar Roy\n *\n * Find repeated sequence of length 10 in string consisting of A,C,G,T\n *\n * Time complexity is O(n)\n * Space complexity is O(n)\n *\n * https://leetcode.com/problems/repeated-dna-sequences/\n */\npublic class RepeatedDnaSequence {\n    private static final int mask = 0xFFFFF;\n    private static final int mask1 = 3;\n\n\n    public List<String> findRepeatedDnaSequences(String s) {\n\n        if (s.length() < 10) {\n            return Collections.emptyList();\n        }\n\n        Set<Integer> set = new HashSet<>();\n        int val = 0;\n        for (int i = 0; i < 10; i++) {\n            val = add(val, s.charAt(i));\n        }\n        set.add(val);\n        List<String> result = new ArrayList<>();\n        createString(val);\n\n        Set<Integer> repeatSet = new HashSet<>();\n\n        for (int i = 10; i < s.length(); i++) {\n            val = add(val, s.charAt(i));\n            if (set.contains(val) && !repeatSet.contains(val)) {\n                result.add(createString(val));\n                repeatSet.add(val);\n            } else {\n                set.add(val);\n            }\n        }\n\n        return result;\n    }\n\n    private String createString(int input) {\n        StringBuffer sb = new StringBuffer();\n        for (int i = 9; i >= 0; i--) {\n            sb.append(getChar(input>>(i*2) & mask1));\n        }\n        return sb.toString();\n    }\n\n    private int add(int input, char ch) {\n        int val = getVal(ch);\n        input = input<<2;\n        input = input & mask;\n        return input | val;\n    }\n\n    private int getVal(char ch) {\n        switch(ch) {\n            case 'A':\n                return 0;\n            case 'C':\n                return 1;\n            case 'G':\n                return 2;\n            case 'T':\n                return 3;\n            default:\n                throw new IllegalArgumentException();\n        }\n    }\n\n    private char getChar(int val) {\n        switch (val) {\n            case 0:\n                return 'A';\n            case 1:\n                return 'C';\n            case 2:\n                return 'G';\n            case 3:\n                return 'T';\n            default:\n                throw new IllegalArgumentException();\n        }\n    }\n\n    public static void main(String args[]) {\n        RepeatedDnaSequence rds = new RepeatedDnaSequence();\n        List<String> result = rds.findRepeatedDnaSequences(\"AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT\");\n        System.out.print(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/ReverseBits.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.geeksforgeeks.org/write-an-efficient-c-program-to-reverse-bits-of-a-number/\n */\npublic class ReverseBits {\n\n    public int reverse(int num){\n        //assuming int is 32 bits.\n        int result = 0;\n        int r1 = 1;\n        for(int i=31; i >= 0; i--,r1<<=1){\n            if((num & 1<<i) != 0){\n                result = result | r1;\n            }\n        }\n        return result;\n    }\n    \n    \n    public static void main(String args[]){\n        ReverseBits rb = new ReverseBits();\n        System.out.println(rb.reverse(418));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/SquareOfNumber.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.careercup.com/question?id=5748016728244224\n * Square of number without using * or ^ operation.\n * Test cases\n * How to deal with negative number\n * 0\n * Power of 2 number\n * Regular numbers\n */\npublic class SquareOfNumber {\n\n    public int square(int n){\n        if(n < 0){\n            n = -n;\n        }\n        int result = 0;\n        int k = n;\n        //so we doing 7*7. First lets get rid of 3 from that 7 by below operation.\n        //Once we are left with 4 then it all about using >> and <<\n        while((k & (k-1))!= 0){\n            result += n;\n            k--;\n        }\n        \n        while(k > 1){\n            n = n<<1;\n            k = k>>1;\n        }\n        return result + n;\n    }\n    \n    public int fastSquare(int n){\n        return fastSquareRec(n, n);\n    }\n    /**\n     * Start with 9,9. Then take 1 and keep left shifting 1 till you find number\n     * less than 9 but power of 2. Then shift 9 by that many powers and repeat\n     * the process with whatever is left between that number and 9.\n    */\n    private int fastSquareRec(int n, int leftToMultiply){\n        if(leftToMultiply <= 0){\n            return 0;\n        }\n        int k = 1; \n        int count=0;\n        while(k <= leftToMultiply){\n            k = k<<1;\n            count++;\n        }\n        k = k>>1;\n        count--;\n        return (n<<count) + fastSquareRec(n, leftToMultiply- k);\n    }\n    \n    public static void main(String args[]){\n        SquareOfNumber sn = new SquareOfNumber();\n        System.out.println(sn.square(9) + \" \" + sn.fastSquare(9));\n        System.out.println(sn.square(27) + \" \" + sn.fastSquare(27));\n        System.out.println(sn.square(18) + \" \" + sn.fastSquare(18));\n        System.out.println(sn.square(199) + \" \" + sn.fastSquare(199));\n    }\n}"
  },
  {
    "path": "src/com/interview/bits/SwapOddEvenBits.java",
    "content": "package com.interview.bits;\n\n/**\n * Exercise 5.6 150 qs\n */\npublic class SwapOddEvenBits {\n\n    public int swap(int num){\n        int mask1 = 0xAAAAAAAA;\n        int mask2 = 0x55555555;\n        return (num << 1 & mask1) | ( num >> 1 & mask2);\n    }\n    \n    public static void main(String args[]){\n        SwapOddEvenBits soe = new SwapOddEvenBits();\n        System.out.println(soe.swap(697));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/SwapTwoBits.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.careercup.com/question?id=17542662\n */\npublic class SwapTwoBits {\n\n    public int swap(int num,int i, int j){\n        int t1 = (num & 1<<j) != 0 ? 1 : 0;\n        int t2 = (num & 1<<i) !=0 ? 1 : 0;\n        num = num & ~(1<<j);\n        num = num & ~(1<<i);\n        num = num | t1<<i;\n        num = num | t2<<j;\n        return num;\n    }\n    \n    public int betterSwap(int num,int i,int j){\n        if(((num & 1<<i)>>i ^ (num & 1<<j)>>j)  != 0){\n            num ^= 1<<i;\n            num ^= 1<<j;\n        }\n        return num;\n    }\n    \n    public static void main(String args[]){\n        SwapTwoBits stb = new SwapTwoBits();\n        System.out.println(stb.betterSwap(172, 2, 4));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/bits/WinnerWithBeautifulNumber.java",
    "content": "package com.interview.bits;\n\n/**\n * http://www.careercup.com/question?id=5399897561890816\n * Idea is simple. Count the number of times it takes to swap 0s such that all\n * 1's are at least significant position.\n * e.g 1010 -> 1001 -> 101 -> 11\n *     1010  -> 110 -> 101 -> 11\n *     \n * No matter which route you take it leads to same result so just looking at swaps you can say\n * which player will win\n *     \n */\npublic class WinnerWithBeautifulNumber {\n\n    public int winner(int n){\n        int sum = 0;\n        int i =1;\n        int result = 0;\n        while( i <= n){\n            i = i*2;\n        }\n        i = i/2;\n        while(i > 0){\n            if((n & i) != 0){\n                sum++;\n            }else{\n                result += sum;\n            }\n            i = i/2;\n        }\n        if(result % 2 == 0){\n            return 2;\n        }else{\n            return 1;\n        }\n    }\n    \n    public static void main(String args[]){\n        WinnerWithBeautifulNumber wwb = new WinnerWithBeautifulNumber();\n        System.out.println(wwb.winner(37));\n        System.out.println(wwb.winner(10));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/BitonicSequence.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/dynamic-programming-set-15-longest-bitonic-subsequence/\n */\npublic class BitonicSequence {\n\n    public int longestSequence(int arr[]){\n        int lis[] = new int[arr.length];\n        int lds[] = new int[arr.length];\n        for(int i=0; i < arr.length; i++){\n            lis[i] = 1;\n            lds[i] = 1;\n        }\n        for(int i=1 ; i < arr.length; i++){\n            for(int j=0; j < i ; j++){\n                if(arr[i] > arr[j]){\n                    lis[i] = Math.max(lis[i], lis[j] + 1);\n                }\n            }\n        }\n        \n        for(int i = arr.length-2; i >=0 ; i--){\n            for(int j = arr.length-1; j > i; j--){\n                if(arr[i] > arr[j]){\n                    lds[i] = Math.max(lds[i], lds[j] + 1);\n                }\n            }\n        }\n        int max = 0;\n        for(int i=0; i < arr.length; i++){\n            if(max < lis[i] + lds[i]-1){\n                max = lis[i] + lds[i] -1;\n            }\n        }\n        return max;\n    }\n    \n    public static void main(String args[]){\n        BitonicSequence bs = new BitonicSequence();\n        int[] arr = {1,4,3,7,2,1,8,11,13,0};\n        int r = bs.longestSequence(arr);\n        System.out.print(r);\n    \n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/BoxStacking.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.Arrays;\n\n/**\n * Date 05/09/2015\n * @author tusroy\n * \n * Given different dimensions and unlimited supply of boxes for each dimension, stack boxes\n * on top of each other such that it has maximum height but with caveat that length and width\n * of box on top should be strictly less than length and width of box under it. You can\n * rotate boxes as you like.\n * \n * 1) Create all rotations of boxes such that length is always greater or equal to width\n * 2) Sort boxes by base area in non increasing order (length * width). This is because box\n * with more area will never ever go on top of box with less area.\n * 3) Take T[] and result[] array of same size as total boxes after all rotations are done\n * 4) Apply longest increasing subsequence type of algorithm to get max height.\n * \n * If n number of dimensions are given total boxes after rotation will be 3n.\n * So space complexity is O(n)\n * Time complexity - O(nlogn) to sort boxes. O(n^2) to apply DP on it So really O(n^2)\n *\n * References\n * http://www.geeksforgeeks.org/dynamic-programming-set-21-box-stacking-problem/\n * http://people.cs.clemson.edu/~bcdean/dp_practice/\n */\npublic class BoxStacking {\n\n    public int maxHeight(Dimension[] input) {\n        //get all rotations of box dimension.\n        //e.g if dimension is 1,2,3 rotations will be 2,1,3  3,2,1  3,1,2  . Here length is always greater\n        //or equal to width and we can do that without loss of generality.\n        Dimension[] allRotationInput = new Dimension[input.length * 3];\n        createAllRotation(input, allRotationInput);\n        \n        //sort these boxes in non increasing order by their base area.(length X width)\n        Arrays.sort(allRotationInput);\n\n        //apply longest increasing subsequence kind of algorithm on these sorted boxes.\n        int T[] = new int[allRotationInput.length];\n        int result[] = new int[allRotationInput.length];\n\n        for (int i = 0; i < T.length; i++) {\n            T[i] = allRotationInput[i].height;\n            result[i] = i;\n        }\n\n        for (int i = 1; i < T.length; i++) {\n            for (int j = 0; j < i; j++) {\n                if (allRotationInput[i].length < allRotationInput[j].length\n                        && allRotationInput[i].width < allRotationInput[j].width) {\n                    if( T[j] + allRotationInput[i].height > T[i]){\n                        T[i] = T[j] + allRotationInput[i].height;\n                        result[i] = j;\n                    }\n                }\n            }\n        }\n       \n        //find max in T[] and that will be our max height.\n        //Result can also be found using result[] array.\n        int max = Integer.MIN_VALUE;\n        for(int i=0; i < T.length; i++){\n            if(T[i] > max){\n                max = T[i];\n            }\n        }\n        \n        return max;\n    }\n\n    //create all rotations of boxes, always keeping length greater or equal to width\n    private void createAllRotation(Dimension[] input,\n            Dimension[] allRotationInput) {\n        int index = 0;\n        for (int i = 0; i < input.length; i++) {\n            allRotationInput[index++] = Dimension.createDimension(\n                    input[i].height, input[i].length, input[i].width);\n            allRotationInput[index++] = Dimension.createDimension(\n                    input[i].length, input[i].height, input[i].width);\n            allRotationInput[index++] = Dimension.createDimension(\n                    input[i].width, input[i].length, input[i].height);\n\n        }\n    }\n\n    public static void main(String args[]) {\n        BoxStacking bs = new BoxStacking();\n        Dimension input[] = { new Dimension(3, 2, 5), new Dimension(1, 2, 4) };\n        int maxHeight = bs.maxHeight(input);\n        System.out.println(\"Max height is \" + maxHeight);\n        assert 11 == maxHeight;\n    }\n}\n\n/**\n * Utility class to hold dimensions\n * @author tusroy\n *\n */\nclass Dimension implements Comparable<Dimension> {\n    int height;\n    int length;\n    int width;\n\n    Dimension(int height, int length, int width) {\n        this.height = height;\n        this.length = length;\n        this.width = width;\n    }\n\n    Dimension() {\n    }\n\n    static Dimension createDimension(int height, int side1, int side2) {\n        Dimension d = new Dimension();\n        d.height = height;\n        if (side1 >= side2) {\n            d.length = side1;\n            d.width = side2;\n        } else {\n            d.length = side2;\n            d.width = side1;\n        }\n        return d;\n    }\n\n    /**\n     * Sorts by base area(length X width)\n     */\n    @Override\n    public int compareTo(Dimension d) {\n        if (this.length * this.width >= d.length * d.width) {\n            return -1;\n        } else {\n            return 1;\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Dimension [height=\" + height + \", length=\" + length\n                + \", width=\" + width + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/BreakMultipleWordsWithNoSpaceIntoSpace.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.*;\n\n/**\n * Date 08/01/2014\n * @author tusroy\n * \n * Given a string and a dictionary, split this string into multiple words such that\n * each word belongs in dictionary.\n * \n * e.g peanutbutter -> pea nut butter\n * e.g Iliketoplay -> I like to play\n * \n * Solution \n * DP solution to this problem\n * if( input[i...j] belongs in dictionary) T[i][j] = i\n * else{\n *     T[i][j] = k if T[i][k-1] != -1 && T[k][j] != -1\n *     \n * Test cases\n * 1) Empty string\n * 2) String where entire string is in dictionary\n * 3) String which cannot be split into words which are in dictionary\n * 3) String which can be split into words which are in dictionary    \n *\n */\npublic class BreakMultipleWordsWithNoSpaceIntoSpace {\n\n    \n    /**\n     * Recursive and slow version of breaking word problem.\n     * If no words can be formed it returns null\n     */\n    public String breakWord(char[] str,int low,Set<String> dictionary){\n        StringBuffer buff = new StringBuffer();\n        for(int i= low; i < str.length; i++){\n            buff.append(str[i]);\n            if(dictionary.contains(buff.toString())){\n                String result = breakWord(str, i+1, dictionary);\n                if(result != null){\n                    return buff.toString() + \" \" + result;\n                }\n            }\n        }\n        if(dictionary.contains(buff.toString())){\n            return buff.toString();\n        }\n        return null;\n    }\n    \n    /**\n     * Dynamic programming version for breaking word problem.\n     * It returns null string if string cannot be broken into multipe words\n     * such that each word is in dictionary.\n     * Gives preference to longer words over splits\n     * e.g peanutbutter with dict{pea nut butter peanut} it would result in\n     * peanut butter instead of pea nut butter.\n     */\n    public String breakWordDP(String word, Set<String> dict){\n        int T[][] = new int[word.length()][word.length()];\n        \n        for(int i=0; i < T.length; i++){\n            for(int j=0; j < T[i].length ; j++){\n                T[i][j] = -1; //-1 indicates string between i to j cannot be split\n            }\n        }\n        \n        //fill up the matrix in bottom up manner\n        for(int l = 1; l <= word.length(); l++){\n            for(int i=0; i < word.length() -l + 1 ; i++){\n                int j = i + l-1;\n                String str = word.substring(i,j+1);\n                //if string between i to j is in dictionary T[i][j] is true\n                if(dict.contains(str)){\n                    T[i][j] = i;\n                    continue;\n                }\n                //find a k between i+1 to j such that T[i][k-1] && T[k][j] are both true \n                for(int k=i+1; k <= j; k++){\n                    if(T[i][k-1] != -1 && T[k][j] != -1){\n                        T[i][j] = k;\n                        break;\n                    }\n                }\n            }\n        }\n        if(T[0][word.length()-1] == -1){\n            return null;\n        }\n        \n        //create space separate word from string is possible\n        StringBuffer buffer = new StringBuffer();\n        int i = 0; int j = word.length() -1;\n        while(i < j){\n            int k = T[i][j];\n            if(i == k){\n                buffer.append(word.substring(i, j+1));\n                break;\n            }\n            buffer.append(word.substring(i,k) + \" \");\n            i = k;\n        }\n        \n        return buffer.toString();\n    }\n\n    /**\n     * Prints all the words possible instead of just one combination.\n     * Reference\n     * https://leetcode.com/problems/word-break-ii/\n     */\n    public List<String> wordBreakTopDown(String s, Set<String> wordDict) {\n        Map<Integer, List<String>> dp = new HashMap<>();\n        int max = 0;\n        for (String s1 : wordDict) {\n            max = Math.max(max, s1.length());\n        }\n        return wordBreakUtil(s, wordDict, dp, 0, max);\n    }\n\n    private List<String> wordBreakUtil(String s, Set<String> dict, Map<Integer, List<String>> dp, int start, int max) {\n        if (start == s.length()) {\n            return Collections.singletonList(\"\");\n        }\n\n        if (dp.containsKey(start)) {\n            return dp.get(start);\n        }\n\n        List<String> words = new ArrayList<>();\n        for (int i = start; i < start + max && i < s.length(); i++) {\n            String newWord = s.substring(start, i + 1);\n            if (!dict.contains(newWord)) {\n                continue;\n            }\n            List<String> result = wordBreakUtil(s, dict, dp, i + 1, max);\n            for (String word : result) {\n                String extraSpace = word.length() == 0 ? \"\" : \" \";\n                words.add(newWord + extraSpace + word);\n            }\n        }\n        dp.put(start, words);\n        return words;\n    }\n\n    /**\n     * Check if any one solution exists.\n     * https://leetcode.com/problems/word-break/\n     */\n    public boolean wordBreakTopDownOneSolution(String s, Set<String> wordDict) {\n        Map<Integer, Boolean> dp = new HashMap<>();\n        int max = 0;\n        for (String s1 : wordDict) {\n            max = Math.max(max, s1.length());\n        }\n        return wordBreakTopDownOneSolutionUtil(s, wordDict, 0, max, dp);\n\n    }\n\n    private boolean wordBreakTopDownOneSolutionUtil(String s, Set<String> dict, int start, int max, Map<Integer, Boolean> dp) {\n        if (start == s.length()) {\n            return true;\n        }\n\n        if (dp.containsKey(start)) {\n            return dp.get(start);\n        }\n\n        for (int i = start; i < start + max && i < s.length(); i++) {\n            String newWord = s.substring(start, i + 1);\n            if (!dict.contains(newWord)) {\n                continue;\n            }\n            if (wordBreakTopDownOneSolutionUtil(s, dict, i + 1, max, dp)) {\n                dp.put(start, true);\n                return true;\n            }\n        }\n        dp.put(start, false);\n        return false;\n    }\n\n    public boolean wordBreakBottomUp(String s, List<String> wordList) {\n        boolean[] T = new boolean[s.length() + 1];\n        Set<String> set = new HashSet<>();\n        for (String word : wordList) {\n            set.add(word);\n        }\n        T[0] = true;\n        for (int i = 1; i <= s.length(); i++) {\n            for (int j = 0; j < i; j++) {\n                if(T[j] && set.contains(s.substring(j, i))) {\n                    T[i] = true;\n                    break;\n                }\n            }\n        }\n        return T[s.length()];\n    }\n    \n    public static void main(String args[]){\n        Set<String> dictionary = new HashSet<String>();\n        dictionary.add(\"I\");\n        dictionary.add(\"like\");\n        dictionary.add(\"had\");\n        dictionary.add(\"play\");\n        dictionary.add(\"to\");\n        String str = \"Ihadliketoplay\";\n        BreakMultipleWordsWithNoSpaceIntoSpace bmw = new BreakMultipleWordsWithNoSpaceIntoSpace();\n        String result1 = bmw.breakWordDP(str, dictionary);\n        \n        System.out.print(result1);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/BurstBalloons.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 03/02/2016\n * @author Tushar Roy\n *\n * Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented\n * by array nums. You are asked to burst all the balloons. If the you burst balloon i you will\n * get nums[left] * nums[i] * nums[right] coins. Here left and right are adjacent indices of i. After the burst,\n * the left and right then becomes adjacent.\n * Find the maximum coins you can collect by bursting the balloons wisely.\n *\n * Time complexity O(n^3)\n * Space complexity O(n^2)\n *\n * Reference\n * https://leetcode.com/problems/burst-balloons/\n */\npublic class BurstBalloons {\n\n    /**\n     * Dynamic programming solution.\n     */\n    public int maxCoinsBottomUpDp(int[] nums) {\n\n        int T[][] = new int[nums.length][nums.length];\n\n        for (int len = 1; len <= nums.length; len++) {\n            for (int i = 0; i <= nums.length - len; i++) {\n                int j = i + len - 1;\n                for (int k = i; k <= j; k++) {\n                    //leftValue/rightValue is initially 1. If there is element on\n                    // left/right of k then left/right value will take that value.\n                    int leftValue = 1;\n                    int rightValue = 1;\n                    if (i != 0) {\n                        leftValue = nums[i-1];\n                    }\n                    if (j != nums.length -1) {\n                        rightValue = nums[j+1];\n                    }\n\n                    //before is initially 0. If k is i then before will\n                    //stay 0 otherwise it gets value T[i][k-1]\n                    //after is similarly 0 initially. if k is j then after will\n                    //stay 0 other will get value T[k+1][j]\n                    int before = 0;\n                    int after = 0;\n                    if (i != k) {\n                        before = T[i][k-1];\n                    }\n                    if (j != k) {\n                        after = T[k+1][j];\n                    }\n                    T[i][j] = Math.max(leftValue * nums[k] * rightValue + before + after,\n                            T[i][j]);\n                }\n            }\n        }\n        return T[0][nums.length - 1];\n    }\n\n    /**\n     * Recursive solution.\n     */\n    public int maxCoinsRec(int nums[]) {\n        int[] nums1 = new int[nums.length + 2];\n        nums1[0] = 1;\n        nums1[nums1.length - 1] = 1;\n        for (int i = 0; i < nums.length; i++) {\n            nums1[i+1] = nums[i];\n        }\n        return maxCoinsRecUtil(nums1);\n    }\n\n    private int maxCoinsRecUtil(int[] nums) {\n        if (nums.length == 2) {\n            return 0;\n        }\n\n        int max = 0;\n        for (int i = 1; i < nums.length - 1; i++) {\n            int val = nums[i - 1]*nums[i]*nums[i+1] + maxCoinsRecUtil(formNewArray(nums, i));\n            if (val > max) {\n                max = val;\n            }\n         }\n        return max;\n\n    }\n\n    private int[] formNewArray(int[] input, int doNotIncludeIndex) {\n        int[] newArray = new int[input.length - 1];\n        int index = 0;\n        for (int i = 0; i < input.length; i++) {\n            if (i == doNotIncludeIndex) {\n                continue;\n            }\n            newArray[index++] = input[i];\n        }\n        return newArray;\n    }\n\n\n    public static void main(String args[]) {\n        BurstBalloons bb = new BurstBalloons();\n        int input[] = {2, 4, 3, 5};\n        System.out.print(bb.maxCoinsBottomUpDp(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/CoinChanging.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @Date 08/01/2014\n * @author Tushar Roy\n *\n * Given a total and coins of certain denominations find number of ways total\n * can be formed from coins assuming infinity supply of coins\n *\n * References:\n * http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/\n */\npublic class CoinChanging {\n\n    public int numberOfSolutions(int total, int coins[]){\n        int temp[][] = new int[coins.length+1][total+1];\n        for(int i=0; i <= coins.length; i++){\n            temp[i][0] = 1;\n        }\n        for(int i=1; i <= coins.length; i++){\n            for(int j=1; j <= total ; j++){\n                if(coins[i-1] > j){\n                    temp[i][j] = temp[i-1][j];\n                }\n                else{\n                    temp[i][j] = temp[i][j-coins[i-1]] + temp[i-1][j];\n                }\n            }\n        }\n        return temp[coins.length][total];\n    }\n\n    /**\n     * Space efficient DP solution\n     */\n    public int numberOfSolutionsOnSpace(int total, int arr[]){\n\n        int temp[] = new int[total+1];\n\n        temp[0] = 1;\n        for(int i=0; i < arr.length; i++){\n            for(int j=1; j <= total ; j++){\n                if(j >= arr[i]){\n                    temp[j] += temp[j-arr[i]];\n                }\n            }\n        }\n        return temp[total];\n    }\n\n    /**\n     * This method actually prints all the combination. It takes exponential time.\n     */\n    public void printCoinChangingSolution(int total,int coins[]){\n        List<Integer> result = new ArrayList<>();\n        printActualSolution(result, total, coins, 0);\n    }\n    \n    private void printActualSolution(List<Integer> result,int total,int coins[],int pos){\n        if(total == 0){\n            for(int r : result){\n                System.out.print(r + \" \");\n            }\n            System.out.print(\"\\n\");\n        }\n        for(int i=pos; i < coins.length; i++){\n            if(total >= coins[i]){\n                result.add(coins[i]);\n                printActualSolution(result,total-coins[i],coins,i);\n                result.remove(result.size()-1);\n            }\n        }\n    }\n\n    public static void main(String args[]){\n        CoinChanging cc = new CoinChanging();\n        int total = 15;\n        int coins[] = {3,4,6,7,9};\n        System.out.println(cc.numberOfSolutions(total, coins));\n        System.out.println(cc.numberOfSolutionsOnSpace(total, coins));\n        cc.printCoinChangingSolution(total, coins);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/CoinChangingMinimumCoin.java",
    "content": "package com.interview.dynamic;\n\nimport java.text.Format;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 08/12/2013\n * @author Tushar Roy\n *\n * Given a total and coins of certain denomination with infinite supply, what is the minimum number\n * of coins it takes to form this total.\n *\n * Time complexity - O(coins.size * total)\n * Space complexity - O(coins.size * total)\n *\n * Youtube video -\n * Topdown DP - https://youtu.be/Kf_M7RdHr1M\n * Bottom up DP - https://youtu.be/Y0ZqKpToTic\n */\npublic class CoinChangingMinimumCoin {\n\n    /**\n     * Top down dynamic programing. Using map to store intermediate results.\n     * Returns Integer.MAX_VALUE if total cannot be formed with given coins\n     */\n    public int minimumCoinTopDown(int total, int coins[], Map<Integer, Integer> map) {\n\n        //if total is 0 then there is nothing to do. return 0.\n        if ( total == 0 ) {\n            return 0;\n        }\n\n        //if map contains the result means we calculated it before. Lets return that value.\n        if ( map.containsKey(total) ) {\n            return map.get(total);\n        }\n\n        //iterate through all coins and see which one gives best result.\n        int min = Integer.MAX_VALUE;\n        for ( int i=0; i < coins.length; i++ ) {\n            //if value of coin is greater than total we are looking for just continue.\n            if( coins[i] > total ) {\n                continue;\n            }\n            //recurse with total - coins[i] as new total\n            int val = minimumCoinTopDown(total - coins[i], coins, map);\n\n            //if val we get from picking coins[i] as first coin for current total is less\n            // than value found so far make it minimum.\n            if( val < min ) {\n                min = val;\n            }\n        }\n\n        //if min is MAX_VAL dont change it. Just result it as is. Otherwise add 1 to it.\n        min =  (min == Integer.MAX_VALUE ? min : min + 1);\n\n        //memoize the minimum for current total.\n        map.put(total, min);\n        return min;\n    }\n\n    /**\n     * Bottom up way of solving this problem.\n     * Keep input sorted. Otherwise temp[j-arr[i]) + 1 can become Integer.Max_value + 1 which\n     * can be very low negative number\n     * Returns Integer.MAX_VALUE - 1 if solution is not possible.\n     */\n    public int minimumCoinBottomUp(int total, int coins[]){\n        int T[] = new int[total + 1];\n        int R[] = new int[total + 1];\n        T[0] = 0;\n        for(int i=1; i <= total; i++){\n            T[i] = Integer.MAX_VALUE-1;\n            R[i] = -1;\n        }\n        for(int j=0; j < coins.length; j++){\n            for(int i=1; i <= total; i++){\n                if(i >= coins[j]){\n                    if (T[i - coins[j]] + 1 < T[i]) {\n                        T[i] = 1 + T[i - coins[j]];\n                        R[i] = j;\n                    }\n                }\n            }\n        }\n        printCoinCombination(R, coins);\n        return T[total];\n    }\n\n    private void printCoinCombination(int R[], int coins[]) {\n        if (R[R.length - 1] == -1) {\n            System.out.print(\"No solution is possible\");\n            return;\n        }\n        int start = R.length - 1;\n        System.out.print(\"Coins used to form total \");\n        while ( start != 0 ) {\n            int j = R[start];\n            System.out.print(coins[j] + \" \");\n            start = start - coins[j];\n        }\n        System.out.print(\"\\n\");\n    }\n\n    public static void main ( String args[] ) {\n        int total = 13;\n        int coins[] = {7, 3, 2, 6};\n        CoinChangingMinimumCoin cc = new CoinChangingMinimumCoin();\n        Map<Integer, Integer> map = new HashMap<>();\n        int topDownValue = cc.minimumCoinTopDown(total, coins, map);\n        int bottomUpValue = cc.minimumCoinBottomUp(total, coins);\n\n        System.out.print(String.format(\"Bottom up and top down result %s %s\", bottomUpValue, topDownValue));\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/CountAs.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/how-to-print-maximum-number-of-a-using-given-four-keys/\n * Test cases\n * Negative number\n * Number less than 7\n * Number greater than equal to 7\n */\npublic class CountAs {\n\n    public int countAsRec(int n){\n    \n        if(n < 7){\n            return n;\n        }\n        int max = Integer.MIN_VALUE;\n        int result = 0;\n        for(int b=n-3; b > 0; b--){\n            result = (n-b-1)*countAs(b);\n            if(max < result){\n                max = result;\n            }\n        }\n        return max;\n    }\n \n    public int countAs(int n){\n        if(n < 7){\n            return n;\n        }\n        \n        int T[] = new int[n+1];\n        for(int i=1; i < 7 ; i++){\n            T[i] = i;\n        }\n        for(int i=7; i <= n; i++){\n            for(int b = i-3; b > 0; b--){\n                T[i] = Math.max(T[i], T[b]*(i-b-1));\n            }\n        }\n        return T[n];\n    }\n    \n    public static void main(String args[]){\n        CountAs ca =new CountAs();\n        System.out.println(ca.countAsRec(25));\n        System.out.println(ca.countAs(25));\n              \n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/CountNumberOfBinaryWithoutConsecutive1s.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/count-number-binary-strings-without-consecutive-1s/\n * It is really a straight up fibonacci series with values\n * 1,2,3,5,8,13....\n * Look how we assign a[i] value of a[i-1] + b[i-1] and then b[i] becomes a[i]\n */\npublic class CountNumberOfBinaryWithoutConsecutive1s {\n\n    public int count(int n){\n        int a[] = new int[n];\n        int b[] = new int[n];\n        \n        a[0] = 1;\n        b[0] = 1;\n        \n        for(int i=1; i < n; i++){\n            a[i] = a[i-1] + b[i-1];\n            b[i] = a[i-1];\n        }\n        \n        return a[n-1] + b[n-1];\n    }\n    \n    public int countSimple(int n){\n        int a = 1;\n        int b = 1;\n        \n        for(int i=1; i < n; i++){\n            int tmp = a;\n        \ta = a + b;\n            b = tmp;\n        }\n        \n        return a + b;\n    }\n    \n    public static void main(String args[]){\n        CountNumberOfBinaryWithoutConsecutive1s cnb = new CountNumberOfBinaryWithoutConsecutive1s();\n        System.out.println(cnb.count(5));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/CountNumberOfTreePreorder.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Given a preorder sequence how many unique trees can be created\n * Solution is catalan number. Number of tree is exactly same\n * as number of unique BST create with array of size n\n * \n * The way it works for preorder sequence is as follows\n * \n * Suppose our preorder sequence is 1 2 3 4\n * So we need to compute following things\n * count(3)* 2 (combination of 2,3 and 4 on both side of 1)\n * count(1)*count(2) (combination of 2 on one side and 3, 4 on other side)\n * count(2)*count(1) (combinatino of 2,3 on one side and 4 on other side)\n * count(3)*2 can be broken into count(3)*count(0) + count(0)*count(3)\n * \n * So our final result is\n * count(0)*count(3) + count(1)*count(2) + count(2)*count(1) + count(3)*count(0)\n * which is a catalan number\n */\npublic class CountNumberOfTreePreorder {\n\n    public int count(int num){\n        if(num == 0){\n            return 0;\n        }\n        int T[] = new int[num+1];\n        T[0] = 1;\n        T[1] = 1;\n        for(int i=2; i <= num; i++){\n            int sum = 0;\n            for(int k=0; k < i; k++){\n                sum += T[k]*T[i-k-1];\n            }\n            T[i] = sum;\n        }\n        return T[num];\n    }\n    \n    public int countRec(int num){\n        if(num == 0 || num ==1){\n            return 1;\n        }\n        int sum = 0;\n        for(int i=1; i <= num; i++){\n            sum += countRec(i-1)*countRec(num-i);\n        }\n        return sum;\n    }\n    \n    public static void main(String args[]){\n        CountNumberOfTreePreorder cn = new CountNumberOfTreePreorder();\n        System.out.println(cn.count(3));\n        System.out.println(cn.count(4));\n        System.out.println(cn.count(5));\n        System.out.println(cn.countRec(3));\n        System.out.println(cn.countRec(4));\n        System.out.println(cn.countRec(5));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/CountNumberOfTreesInBST.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/program-nth-catalan-number/\n * Count number of binary search tree created for array of size n\n */\npublic class CountNumberOfTreesInBST {\n\n    int countTreesRec(int numKeys) {\n        if (numKeys <=1) {\n            return(1);\n        }\n        else {\n            int sum = 0;\n            int left, right, root;\n            for (root=1; root<=numKeys; root++) {\n                left = countTreesRec(root - 1);\n                right = countTreesRec(numKeys - root);\n                sum += left*right;\n            }\n            return(sum);\n        }\n    }\n    \n    public int countTrees(int n){\n        int T[] = new int[n+1];\n        T[0] = 1;\n        T[1] = 1;\n        for(int i=2; i <= n; i++){\n            for(int j=0; j <i; j++){\n                T[i] += T[j]*T[i-j-1];\n            }\n        }\n        return T[n];\n    }\n    public static void main(String args[]){\n        CountNumberOfTreesInBST cnt = new CountNumberOfTreesInBST();\n        System.out.println(cnt.countTrees(3));\n        System.out.println(cnt.countTrees(4));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/CutRodToMinimizeCost.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 07/20/2015\n * @author Tushar Roy\n *\n * Given a rod with markings. Cut the rod along markings but reduce the cost of cutting.\n * Cost if cutting is proportional to the length of rod being cut.\n *\n * Solve is using top down dynamic programming. Memoize minimum cost of cutting between marking\n * start to end. To calculate the value try all markings b/w start to end.\n *\n */\npublic class CutRodToMinimizeCost {\n\n\n    public int cutRodToMinimizeCost(int [] markings, int total) {\n        int T[][] = new int[total+1][total+1];\n        for(int i = 0 ; i < T.length; i++) {\n            for(int j=0; j < T[i].length ; j++) {\n                T[i][j] = -1;\n            }\n        }\n        return cutRodToMinimizeCost(markings, 0, total, T);\n    }\n\n    private int cutRodToMinimizeCost(int[] markings, int start, int end, int T[][]){\n\n        if(T[start][end] != -1) {\n            return T[start][end];\n        }\n\n        int i;\n        for(i=0; i < markings.length; i++){\n            if(start < markings[i]) {\n                break;\n            }\n        }\n        if(i == markings.length) {\n            T[start][end] = 0;\n            return 0;\n        }\n        \n        int j;\n        for(j=markings.length -1; j >= 0; j--){\n            if(end > markings[j]) {\n                break;\n            }\n        }\n        if(j == -1) {\n            T[start][end] = 0;\n            return 0;\n        }\n        if(i == j){\n            T[start][end] = end - start;\n            return end - start;\n        }\n        int cost = end - start;\n        int minCost = Integer.MAX_VALUE;\n        for(int k=i; k <= j; k++) {\n            int c1 = cutRodToMinimizeCost(markings, start, markings[k], T);\n            int c2 = cutRodToMinimizeCost(markings, markings[k], end, T);\n            if(c1 == Integer.MAX_VALUE || c2 == Integer.MAX_VALUE) {\n                continue;\n            }\n            if(minCost > c1 + c2){\n                minCost = c1 + c2;\n            }\n        }\n        if(minCost == Integer.MAX_VALUE) {\n            T[start][end] = Integer.MAX_VALUE;\n            return Integer.MAX_VALUE;\n        }\n        T[start][end] = cost + minCost;\n        return cost + minCost;\n    }\n    \n    public static void main(String args[]) {\n        int markings[] = {2,3,6,7};\n        CutRodToMinimizeCost cr = new CutRodToMinimizeCost();\n        int cost = cr.cutRodToMinimizeCost(markings, 8);\n        System.out.println(cost);       \n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/CuttingRod.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/dynamic-programming-set-13-cutting-a-rod/\n */\npublic class CuttingRod {\n\n    public int maxValue(int price[]){\n        int max[] = new int[price.length+1];\n        for(int i=1; i <= price.length; i++){\n            for(int j=i; j <= price.length; j++){\n                max[j] = Math.max(max[j], max[j-i] + price[i-1]);\n            }\n        }\n        return max[price.length];\n    }\n    \n    public int maxValue1(int price[]){\n        int max[] = new int[price.length+1];\n        for(int i=1; i <= price.length; i++){\n            max[i] = price[i-1];\n        }\n        for(int i=1 ; i <= price.length; i++){\n            for(int j=1; j < i ; j++){\n                max[i] = Math.max(max[i], max[i-j] + max[j]);\n            }\n        }\n        return max[price.length];\n    }\n    \n    public int recursiveMaxValue(int price[],int len){\n        if(len <= 0){\n            return 0;\n        }\n        int maxValue = 0;\n        for(int i=0; i < len;i++){\n            int val = price[i] + recursiveMaxValue(price, len-i-1);\n            if(maxValue < val){\n                maxValue = val;\n            }\n        }\n        return maxValue;\n    }\n    public static void main(String args[]){\n        CuttingRod cr =new CuttingRod();\n        int[] price = {3,5,8,9,10,20,22,25};\n        long t1 = System.currentTimeMillis();\n        int r = cr.recursiveMaxValue(price,8);\n        long t2 = System.currentTimeMillis();\n        System.out.println(r);\n        System.out.println(t2 - t1);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/DecodeWays.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * A message containing letters from A-Z is being encoded to numbers using the following mapping:\n * 1 -> A\n * 2 -> B\n * 3 -> C\n * 26-> Z\n * Given an encoded message containing digits, determine the total number of ways to decode it.\n *\n * https://leetcode.com/problems/decode-ways/\n */\npublic class DecodeWays {\n\n    public int numDecodings(String s) {\n        if (s.length() == 0) {\n            return 0;\n        }\n        Map<Integer, Integer> count = new HashMap<>();\n        return numDecodingsUtil(s, 0, count);\n    }\n\n    public int numDecodingsUtil(String s, int start, Map<Integer, Integer> count) {\n        if (s.length() == start) {\n            return 1;\n        }\n        if (count.containsKey(start)) {\n            return count.get(start);\n        }\n        String s1 = s.substring(start, start + 1);\n        if (s1.equals(\"0\")) {\n            count.put(start, 0);\n            return 0;\n        }\n        int c1 = numDecodingsUtil(s, start + 1, count);\n\n        int c2 = 0;\n        if (start < s.length() - 1) {\n            s1 = s.substring(start, start + 2);\n            if (Integer.valueOf(s1) <= 26) {\n                c2 = numDecodingsUtil(s, start + 2, count);\n            }\n        }\n        count.put(start, c1 + c2);\n        return c1 + c2;\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/dynamic/DiceThrowWays.java",
    "content": "package com.interview.dynamic;\n\n/**\n * @author Tushar Roy\n * http://www.geeksforgeeks.org/dice-throw-problem/\n * This solution assumes that 1,2,1 is different from 2,1,1 which is different from 1,1 2\n * so total 3 ways are possible\n */\npublic class DiceThrowWays {\n\n    public int numberOfWays(int n, int f, int k){\n        \n        int T[][] = new int[n+1][k+1];\n        T[0][0] = 1;\n    /*  for(int i=0; i < T.length; i++){\n            T[0][i] = 1;\n        }*/\n        \n        for(int i=1; i <= n; i++){\n            for(int j =1; j <= i*f && j <= k ; j++){\n                if(j == i){\n                    T[i][j] = 1;\n                    continue;\n                }\n                if(j < i){\n                    continue;\n                }\n                for(int l =1; l <=f ;l++){\n                    if(j >= l){\n                        T[i][j] += T[i-1][j-l];\n                    }\n                }\n            }\n        }\n        return T[n][k];\n    }\n    \n    public static void main(String args[]){\n        DiceThrowWays dtw = new DiceThrowWays();\n        System.out.println(dtw.numberOfWays(3, 3, 6));\n    }\n}   \n"
  },
  {
    "path": "src/com/interview/dynamic/DistinctSubsequence.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 03/20/2016\n * @author Tushar Roy\n *\n * Given a string S and a string T, count the number of distinct subsequences of T in S.\n *\n * Time complexity O(n^2)\n * Space complexity O(n^2)\n *\n * https://leetcode.com/problems/distinct-subsequences/\n */\npublic class DistinctSubsequence {\n    public int numDistinct(String s, String t) {\n        if (s.length() == 0 || t.length() == 0) {\n            return 0;\n        }\n        int[][] T = new int[t.length() + 1][s.length() + 1];\n        for (int i = 0; i < T[0].length; i++) {\n            T[0][i] = 1;\n        }\n        for (int i = 1; i < T.length; i++) {\n            for (int j = 1; j < T[0].length; j++) {\n                if (s.charAt(j - 1) == t.charAt(i - 1)) {\n                    T[i][j] = T[i-1][j-1] + T[i][j-1];\n                } else {\n                    T[i][j] = T[i][j-1];\n                }\n            }\n        }\n        return T[t.length()][s.length()];\n    }\n\n    public static void main(String args[]) {\n        DistinctSubsequence ds = new DistinctSubsequence();\n        System.out.println(ds.numDistinct(\"abdacgblc\", \"abc\"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/DungeonGame.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 03/21/2016\n * @author Tushar Roy\n *\n * Minimum life needed for knight to reach princess in 2D matrix.\n * \n * Time complexity O(n^2)\n * Space complexity O(n^2)\n *\n * https://leetcode.com/problems/dungeon-game/\n */\npublic class DungeonGame {\n    public int calculateMinimumHP(int[][] dungeon) {\n        if (dungeon.length == 0 || dungeon[0].length == 0) {\n            return 0;\n        }\n        int[][] health = new int[dungeon.length][dungeon[0].length];\n\n        int m = dungeon.length - 1;\n        int n = dungeon[0].length - 1;\n\n        health[m][n] = Math.max(1 - dungeon[m][n] , 1);\n\n        for (int i = m - 1; i >= 0; i--) {\n            health[i][n] = Math.max(health[i + 1][n] - dungeon[i][n], 1);\n        }\n\n        for (int i = n - 1; i >= 0; i--) {\n            health[m][i] = Math.max(health[m][i+1] - dungeon[m][i], 1);\n        }\n\n        for (int i = m - 1; i >= 0; i--) {\n            for (int j = n - 1; j >= 0; j--) {\n                health[i][j] = Math.min(Math.max(health[i + 1][j] - dungeon[i][j], 1), Math.max(health[i][j + 1] - dungeon[i][j], 1));\n            }\n        }\n\n        return health[0][0];\n    }\n\n    public static void main(String args[]) {\n        DungeonGame dg = new DungeonGame();\n        int[][] dungeon = {{-2, -3, 3}, {-5, -10, 1}, {10, 30, -30}};\n        System.out.print(dg.calculateMinimumHP(dungeon));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/EditDistance.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.List;\n\n/**\n * Date 07/07/2014\n * @author Tushar Roy\n *\n * Given two strings how many minimum edits(update, delete or add) is needed to convert one string to another\n *\n * Time complexity is O(m*n)\n * Space complexity is O(m*n)\n *\n * References:\n * http://www.geeksforgeeks.org/dynamic-programming-set-5-edit-distance/\n * https://en.wikipedia.org/wiki/Edit_distance\n */\npublic class EditDistance {\n\n    /**\n     * Uses recursion to find minimum edits\n     */\n    public int recEditDistance(char[]  str1, char str2[], int len1,int len2){\n        \n        if(len1 == str1.length){\n            return str2.length - len2;\n        }\n        if(len2 == str2.length){\n            return str1.length - len1;\n        }\n        return min(recEditDistance(str1, str2, len1 + 1, len2 + 1) + str1[len1] == str2[len2] ? 0 : 1, recEditDistance(str1, str2, len1, len2 + 1) + 1, recEditDistance(str1, str2, len1 + 1, len2) + 1);\n    }\n    \n    /**\n     * Uses bottom up DP to find the edit distance\n     */\n    public int dynamicEditDistance(char[] str1, char[] str2){\n        int temp[][] = new int[str1.length+1][str2.length+1];\n        \n        for(int i=0; i < temp[0].length; i++){\n            temp[0][i] = i;\n        }\n        \n        for(int i=0; i < temp.length; i++){\n            temp[i][0] = i;\n        }\n        \n        for(int i=1;i <=str1.length; i++){\n            for(int j=1; j <= str2.length; j++){\n                if(str1[i-1] == str2[j-1]){\n                    temp[i][j] = temp[i-1][j-1];\n                }else{\n                    temp[i][j] = 1 + min(temp[i-1][j-1], temp[i-1][j], temp[i][j-1]);\n                }\n            }\n        }\n        printActualEdits(temp, str1, str2);\n        return temp[str1.length][str2.length];\n        \n    }\n\n    /**\n     * Prints the actual edits which needs to be done.\n     */\n    public void printActualEdits(int T[][], char[] str1, char[] str2) {\n        int i = T.length - 1;\n        int j = T[0].length - 1;\n        while(true) {\n            if (i == 0 || j == 0) {\n                break;\n            }\n            if (str1[i-1] == str2[j-1]) {\n                i = i-1;\n                j = j-1;\n            } else if (T[i][j] == T[i-1][j-1] + 1){\n                System.out.println(\"Edit \" + str2[j-1] + \" in string2 to \" + str1[i-1] + \" in string1\");\n                i = i-1;\n                j = j-1;\n            } else if (T[i][j] == T[i-1][j] + 1) {\n                System.out.println(\"Delete in string1 \" + str1[i-1]);\n                i = i-1;\n            } else if (T[i][j] == T[i][j-1] + 1){\n                System.out.println(\"Delete in string2 \" + str2[j-1]);\n                j = j -1;\n            } else {\n                throw new IllegalArgumentException(\"Some wrong with given data\");\n            }\n\n        }\n    }\n\n    private int min(int a,int b, int c){\n        int l = Math.min(a, b);\n        return Math.min(l, c);\n    }\n\n    public static void main(String args[]){\n        String str1 = \"azced\";\n        String str2 = \"abcdef\";\n        EditDistance editDistance = new EditDistance();\n        int result = editDistance.dynamicEditDistance(str1.toCharArray(), str2.toCharArray());\n        System.out.print(result);\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/EggDropping.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/dynamic-programming-set-11-egg-dropping-puzzle/\n */\npublic class EggDropping {\n\n    public int calculate(int eggs, int floors){\n        \n        int T[][] = new int[eggs+1][floors+1];\n        int c =0;\n        for(int i=0; i <= floors; i++){\n            T[1][i] = i;\n        }\n        \n        for(int e = 2; e <= eggs; e++){\n            for(int f = 1; f <=floors; f++){\n                T[e][f] = Integer.MAX_VALUE;\n                for(int k = 1; k <=f ; k++){\n                    c = 1 + Math.max(T[e-1][k-1], T[e][f-k]);\n                    if(c < T[e][f]){\n                        T[e][f] = c;\n                    }\n                }\n            }\n        }\n        return T[eggs][floors];\n    }\n    \n    public int calculateRecursive(int eggs, int floors){\n        if(eggs == 1){\n            return floors;\n        }\n        if(floors == 0){\n            return 0;\n        }\n        int min = 1000;\n        for(int i=1; i <= floors; i++){\n            int val = 1 + Math.max(calculateRecursive(eggs-1, i-1),calculateRecursive(eggs, floors-i));\n            if(val < min){\n                min = val;\n            }\n        }\n        return min;\n    }\n    \n    public static void main(String args[]){\n        EggDropping ed = new EggDropping();\n        int r = ed.calculate(3,100);\n        System.out.println(r);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/ExpressionEvaluation.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Date 01/07/2016\n * @author Tushar Roy\n *\n * Given an expression with +, -, * and / operators. Tell if expression can evaluate to given result with different\n * parenthesis combination.\n * e.g expresson is 2*3-1 and result is 4, function should return true since 2*(3-1) evaluate to 4.\n *\n * Time complexity is O(n^5)\n * Space complexity is O(n^3)\n */\npublic class ExpressionEvaluation {\n\n    public boolean evaluate(char[] expression, int result) {\n        int operands[] = new int[expression.length/2 + 1];\n        char operators[] = new char[expression.length/2];\n\n        int index1 = 0;\n        int index2 = 0;\n        operands[index1++] = expression[0] - '0';\n        for (int i = 1; i < expression.length; i += 2 ) {\n            operators[index2++] = expression[i];\n            operands[index1++] = expression[i+1] - '0';\n        }\n\n        Holder T[][] = new Holder[operands.length][operands.length];\n\n        for (int i = 0; i < T.length; i++) {\n            for (int j = 0; j < T.length; j++) {\n                T[i][j] = new Holder();\n            }\n        }\n\n        for (int i = 0; i < operands.length; i++) {\n            T[i][i].add(operands[i]);\n        }\n\n        for (int l = 2; l <= T.length; l++) {\n            for (int i = 0; i <= T.length - l; i++) {\n                int j = i + l - 1;\n                for (int k = i; k < j; k++) {\n                    for (int x : T[i][k].values()) {\n                        for (int y : T[k + 1][j].values()) {\n                            if (operators[k] == '/' && y == 0) {\n                                continue;\n                            }\n                            T[i][j].add(operate(operators[k], x, y));\n                        }\n                    }\n                }\n            }\n        }\n\n        T[0][T.length-1].values().forEach((i -> System.out.print(i + \" \")));\n\n        for (int i : T[0][T.length - 1].values()) {\n            if ( i == result) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    private int operate(char operator, int x, int y) {\n        switch (operator) {\n            case '+':\n                return x + y;\n            case '-':\n                return x - y;\n            case '*':\n                return x*y;\n            case '/':\n                return x/y;\n            default:\n                throw new IllegalArgumentException();\n        }\n    }\n    static class Holder {\n        private Set<Integer> valueHolder = new HashSet<>();\n        void add(Integer ch) {\n            valueHolder.add(ch);\n        }\n        Set<Integer> values() {\n            return valueHolder;\n        }\n    }\n\n    public static void main(String args[]) {\n        ExpressionEvaluation ee = new ExpressionEvaluation();\n        System.out.println(ee.evaluate(\"9*3+1/7\".toCharArray(), 0));\n    }\n}\n\n\n"
  },
  {
    "path": "src/com/interview/dynamic/FibonacciSeries.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 03/28/2015\n * @author tusroy\n * \n * Fibonacci series\n * Given a number find the fibonacci series value for that number\n * e.g n = 3 -> 3\n *     n = 4 -> 5\n *     n = 5 -> 8\n *  \n * Solution\n * Recursively it can calculated very easily by f(n) = f(n-1) + f(n-2)\n * For Dp version we do not recalculate f(n-1) and f(n-2) but keep it in a and b\n * \n * Test cases\n * 1) Negative number\n * 2) 0 \n * 3) 1\n * 4) Very high number\n * \n */\npublic class FibonacciSeries {\n\n\t /**\n     * DP version where we do not recalculate values but just keep last 2\n     * calculate values\n     */\n    public int fibonacciSeries(int n){\n        int n1 = 0, n2 = 1;\n        int sum;\n\n        if (n == n1 || n == n2) {\n            return n;\n        }\n\n        for(int i=2; i <= n; i++){\n            sum = n1 + n2;\n            n1 = n2;\n            n2 = sum;\n        }\n        return n2;\n    }\n    \n   \n    /**\n     * Recursive and slow version. Recalculates same value over and over again.\n     * Chokes for n greater than 60\n     */\n    public int fibonacciSeriesRecursive(int n){\n        if(n == 1 || n == 0){\n            return n;\n        }\n        return fibonacciSeriesRecursive(n-1) + fibonacciSeriesRecursive(n-2);\n    }\n    \n    public static void main(String args[]){\n        FibonacciSeries fs = new FibonacciSeries();\n        System.out.println(fs.fibonacciSeries(15));\n        System.out.println(fs.fibonacciSeriesRecursive(15));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/Immutable2DSumRangeQuery.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 03/11/2016\n * @author Tushar Roy\n *\n * Given a 2D array find the sum in given range defining a rectangle.\n *\n * Time complexity construction O(n*m)\n * Time complexity of query O(1)\n * Space complexity is O(n*m)\n * \n * Reference\n * https://leetcode.com/problems/range-sum-query-2d-immutable/\n */\npublic class Immutable2DSumRangeQuery {\n    private int[][] T;\n\n    public Immutable2DSumRangeQuery(int[][] matrix) {\n        int row = 0;\n        int col = 0;\n        if (matrix.length != 0) {\n            row = matrix.length;\n            col = matrix[0].length;\n        }\n        T = new int[row + 1][col + 1];\n        for (int i = 1; i < T.length; i++) {\n            for (int j = 1; j < T[0].length; j++) {\n                T[i][j] = T[i - 1][j] + T[i][j - 1] + matrix[i - 1][j - 1] - T[i - 1][j - 1];\n            }\n        }\n   }\n\n    public int sumQuery(int row1, int col1, int row2, int col2) {\n        row1++;\n        col1++;\n        row2++;\n        col2++;\n        return T[row2][col2] - T[row1 - 1][col2] - T[row2][col1 - 1] + T[row1 - 1][col1 - 1];\n    }\n\n    public static void main(String args[]) {\n        int[][] input = {{3, 0, 1, 4, 2},\n                        {5, 6, 3, 2, 1},\n                        {1, 2, 0, 1, 5},\n                        {4, 1, 0, 1, 7},\n                        {1, 0, 3, 0, 5}};\n\n        int[][] input1 = {{2,0,-3,4}, {6, 3, 2, -1}, {5, 4, 7, 3}, {2, -6, 8, 1}};\n        Immutable2DSumRangeQuery isr = new Immutable2DSumRangeQuery(input1);\n        System.out.println(isr.sumQuery(1, 1, 2, 2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/Knapsack01.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 04/04/2014\n * @author Tushar Roy\n *\n * 0/1 Knapsack Problem - Given items of certain weights/values and maximum allowed weight\n * how to pick items to pick items from this set to maximize sum of value of items such that\n * sum of weights is less than or equal to maximum allowed weight.\n *\n * Time complexity - O(W*total items)\n *\n * Youtube link\n * Topdown DP - https://youtu.be/149WSzQ4E1g\n * Bottomup DP - https://youtu.be/8LusJS5-AGo\n *\n * References -\n * http://www.geeksforgeeks.org/dynamic-programming-set-10-0-1-knapsack-problem/\n * https://en.wikipedia.org/wiki/Knapsack_problem\n */\npublic class Knapsack01 {\n\n    /**\n     * Solves 0/1 knapsack in bottom up dynamic programming\n     */\n    public int bottomUpDP(int val[], int wt[], int W){\n        int K[][] = new int[val.length+1][W+1];\n        for(int i=0; i <= val.length; i++){\n            for(int j=0; j <= W; j++){\n                if(i == 0 || j == 0){\n                    K[i][j] = 0;\n                    continue;\n                }\n                if(j - wt[i-1] >= 0){\n                    K[i][j] = Math.max(K[i-1][j], K[i-1][j-wt[i-1]] + val[i-1]);\n                }else{\n                    K[i][j] = K[i-1][j];\n                }\n            }\n        }\n        return K[val.length][W];\n    }\n\n    /**\n     * Key for memoization\n     */\n    class Index {\n        int remainingWeight;\n        int remainingItems;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Index index = (Index) o;\n\n            if (remainingWeight != index.remainingWeight) return false;\n            return remainingItems == index.remainingItems;\n\n        }\n\n        @Override\n        public int hashCode() {\n            int result = remainingWeight;\n            result = 31 * result + remainingItems;\n            return result;\n        }\n    }\n\n    /**\n     * Solves 0/1 knapsack in top down DP\n     */\n    public int topDownRecursive(int values[], int weights[], int W) {\n        //map of key(remainingWeight, remainingCount) to maximumValue they can get.\n        Map<Index, Integer> map = new HashMap<>();\n        return topDownRecursiveUtil(values, weights, W, values.length, 0, map);\n    }\n\n    public int topDownRecursiveUtil(int values[], int weights[], int remainingWeight, int totalItems, int currentItem, Map<Index, Integer> map) {\n        //if currentItem exceeds total item count or remainingWeight is less than 0 then\n        //just return with 0;\n        if(currentItem >= totalItems || remainingWeight <= 0) {\n            return 0;\n        }\n\n        //fom a key based on remainingWeight and remainingCount\n        Index key = new Index();\n        key.remainingItems = totalItems - currentItem -1;\n        key.remainingWeight = remainingWeight;\n\n        //see if key exists in map. If so then return the maximumValue for key stored in map.\n        if(map.containsKey(key)) {\n            return map.get(key);\n        }\n        int maxValue;\n        //if weight of item is more than remainingWeight then try next item by skipping current item\n        if(remainingWeight < weights[currentItem]) {\n            maxValue = topDownRecursiveUtil(values, weights, remainingWeight, totalItems, currentItem + 1, map);\n        } else {\n            //try to get maximumValue of either by picking the currentItem or not picking currentItem\n            maxValue = Math.max(values[currentItem] + topDownRecursiveUtil(values, weights, remainingWeight - weights[currentItem], totalItems, currentItem + 1, map),\n                    topDownRecursiveUtil(values, weights, remainingWeight, totalItems, currentItem + 1, map));\n        }\n        //memoize the key with maxValue found to avoid recalculation\n        map.put(key, maxValue);\n        return maxValue;\n\n    }\n\n    public static void main(String args[]){\n        Knapsack01 k = new Knapsack01();\n        int val[] = {22, 20, 15, 30, 24, 54, 21, 32, 18, 25};\n        int wt[] = {4, 2, 3, 5, 5, 6, 9, 7, 8, 10};\n        int r = k.bottomUpDP(val, wt, 30);\n        int r1 = k.topDownRecursive(val, wt, 30);\n        System.out.println(r);\n        System.out.println(r1);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/LongestCommonSubsequence.java",
    "content": "package com.interview.dynamic;\n\n/**\n http://www.geeksforgeeks.org/dynamic-programming-set-4-longest-common-subsequence/\n */\npublic class LongestCommonSubsequence {\n\n    public int lcs(char str1[],char str2[],int len1, int len2){\n        \n        if(len1 == str1.length || len2 == str2.length){\n            return 0;\n        }\n        if(str1[len1] == str2[len2]){\n            return 1 + lcs(str1,str2,len1+1,len2+1);\n        }\n        else{\n            return Math.max(lcs(str1,str2,len1+1,len2),lcs(str1,str2,len1,len2+1));\n        }\n    }\n\n    public int lcsDynamic(char str1[],char str2[]){\n    \n        int temp[][] = new int[str1.length + 1][str2.length + 1];\n        int max = 0;\n        for(int i=1; i < temp.length; i++){\n            for(int j=1; j < temp[i].length; j++){\n                if(str1[i-1] == str2[j-1]) {\n                    temp[i][j] = temp[i - 1][j - 1] + 1;\n                }\n                else\n                {\n                    temp[i][j] = Math.max(temp[i][j-1],temp[i-1][j]);\n                }\n                if(temp[i][j] > max){\n                    max = temp[i][j];\n                }\n            }\n        }\n        return max;\n    \n    }\n    \n    public static void main(String args[]){\n        LongestCommonSubsequence lcs = new LongestCommonSubsequence();\n        String str1 = \"ABCDGHLQR\";\n        String str2 = \"AEDPHR\";\n        \n        int result = lcs.lcsDynamic(str1.toCharArray(), str2.toCharArray());\n        System.out.print(result);\n    }\n    \n    \n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/LongestCommonSubstring.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://en.wikipedia.org/wiki/Longest_common_substring_problem\n */\npublic class LongestCommonSubstring {\n\n    /**\n     * Dynamic way of calculating lcs\n     */\n    public int longestCommonSubstring(char str1[], char str2[]){\n        int T[][] = new int[str1.length+1][str2.length+1];\n        \n        int max = 0;\n        for(int i=1; i <= str1.length; i++){\n            for(int j=1; j <= str2.length; j++){\n                if(str1[i-1] == str2[j-1]){\n                    T[i][j] = T[i-1][j-1] +1;\n                    if(max < T[i][j]){\n                        max = T[i][j];\n                    }\n                }\n            }\n        }\n        return max;\n    }\n    \n    /**\n     * Recursive way of calculating lcs\n     */\n    public int longestCommonSubstringRec(char str1[], char str2[], int pos1, int pos2, boolean checkEqual){\n        if(pos1 == -1 || pos2 == -1){\n            return 0;\n        }\n        if(checkEqual){\n            if(str1[pos1] == str2[pos2]){\n                return 1 + longestCommonSubstringRec(str1, str2, pos1-1, pos2-1, true);\n            }else{\n                return 0;\n            }\n        }\n        int r1 = 0;\n        if(str1[pos1] == str2[pos2]){\n            r1 = 1 + longestCommonSubstringRec(str1, str2, pos1-1, pos2-1, true);\n        }\n        return Math.max(r1,Math.max(longestCommonSubstringRec(str1, str2, pos1-1, pos2, false), longestCommonSubstringRec(str1, str2, pos1, pos2-1,false)));\n    }\n    \n    public static void main(String args[]){\n        LongestCommonSubstring lcs = new LongestCommonSubstring();\n        char str1[] = \"abcdef\".toCharArray();\n        char str2[] = \"zcdemf\".toCharArray();\n        System.out.println(lcs.longestCommonSubstring(str1, str2));\n        System.out.println(lcs.longestCommonSubstringRec(str1, str2,str1.length-1, str2.length-1,false));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/LongestEvenLengthSubstringOfEqualHalf.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/longest-even-length-substring-sum-first-second-half/\n * Test cases\n * Even length string\n * odd length string\n * 0 length string\n */\npublic class LongestEvenLengthSubstringOfEqualHalf {\n    \n    public int findMaxLength(int input[]){\n        assert input != null;\n        int T[][] = new int[input.length][input.length];\n        \n        for(int i=0; i < T.length; i++){\n            T[i][i] = input[i];\n        }\n        int max = 0;\n        for(int len = 2; len <= input.length; len++){\n            for(int i=0; i < input.length - len+1; i++){\n                int j = i + len-1;\n                //updating sum for each lenght\n                T[i][j] = T[i][j-1] + input[j];\n                \n                if(len % 2 == 0){\n                    int k = (i + j)/2;\n                    if(T[i][k] == T[k+1][j]){\n                        if(max < len){\n                            max = len;\n                        }\n                    }\n                }\n            }\n        }\n        return max;\n    }\n    \n    public static void main(String args[]){\n        int input[] = {1,5,3,8,0,2,14,9};\n        LongestEvenLengthSubstringOfEqualHalf lel = new LongestEvenLengthSubstringOfEqualHalf();\n        System.out.println(lel.findMaxLength(input));\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/LongestIncreasingPath.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 03/10/2016\n * @author Tushar Roy\n *\n * Given a 2D matrix find longest increasing path length in this matrix.\n *\n * Time complexity is O(n*m)\n * Space complexity is O(n*m)\n *\n * Reference\n * https://leetcode.com/problems/longest-increasing-path-in-a-matrix/\n */\npublic class LongestIncreasingPath {\n\n    public int longestIncreasingPath(int[][] matrix) {\n        if (matrix.length == 0 || matrix[0].length == 0) {\n            return 0;\n        }\n        int[][] distance = new int[matrix.length][matrix[0].length];\n        int max = 1;\n        for (int i = 0; i < matrix.length; i++) {\n            for (int j = 0; j < matrix[0].length; j++) {\n                int r = dfs(matrix, i, j, distance, Integer.MIN_VALUE);\n                if (r > max) {\n                    max = r;\n                }\n            }\n        }\n        return max;\n    }\n\n    int dfs(int[][] matrix, int i, int j, int[][] distance, int prev) {\n        if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[i].length) {\n            return 0;\n        }\n\n        if (matrix[i][j] <= prev) {\n            return 0;\n        }\n\n        if (distance[i][j] != 0) {\n            return distance[i][j];\n        }\n\n        int v1 = dfs(matrix, i - 1, j, distance, matrix[i][j]);\n        int v2 = dfs(matrix, i, j - 1, distance, matrix[i][j]);\n        int v3 = dfs(matrix, i + 1, j, distance, matrix[i][j]);\n        int v4 = dfs(matrix, i, j + 1, distance, matrix[i][j]);\n        distance[i][j] = 1 + Math.max(Math.max(v1, v2), Math.max(v3, v4));\n        return distance[i][j];\n    }\n\n    public static void main(String args[]) {\n        LongestIncreasingPath lip = new LongestIncreasingPath();\n        int[][] input = {{9, 9, 4},{6, 6, 8},{2, 1, 1}};\n        int[][] input1 = {{3, 4, 5}, {3, 2, 6}, {2, 2, 1}};\n        System.out.println(lip.longestIncreasingPath(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/LongestIncreasingSubsequence.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 05/02/2014\n * @author tusroy\n * \n * Youtube link - https://youtu.be/CE2b_-XfVDk\n * \n * Find a subsequence in given array in which the subsequence's elements are \n * in sorted order, lowest to highest, and in which the subsequence is as long as possible\n * \n * Solution : \n * Dynamic Programming is used to solve this question. DP equation is \n * if(arr[i] > arr[j]) { T[i] = max(T[i], T[j] + 1 }\n * \n * Time complexity is O(n^2).\n * Space complexity is O(n)\n * \n * Reference \n * http://en.wikipedia.org/wiki/Longest_increasing_subsequence\n * http://www.geeksforgeeks.org/dynamic-programming-set-3-longest-increasing-subsequence/\n */\npublic class LongestIncreasingSubsequence {\n\n    /**\n     * DP way of solving LIS\n     */\n    public int longestSubsequenceWithActualSolution(int arr[]){\n        int T[] = new int[arr.length];\n        int actualSolution[] = new int[arr.length];\n        for(int i=0; i < arr.length; i++){\n            T[i] = 1;\n            actualSolution[i] = i;\n        }\n        \n        for(int i=1; i < arr.length; i++){\n            for(int j=0; j < i; j++){\n                if(arr[i] > arr[j]){\n                    if(T[j] + 1 > T[i]){\n                        T[i] = T[j] + 1;\n                        //set the actualSolution to point to guy before me\n                        actualSolution[i] = j;\n                    }\n                }\n            }\n        }\n        \n        //find the index of max number in T \n        int maxIndex = 0;\n        for(int i=0; i < T.length; i++){\n            if(T[i] > T[maxIndex]){\n                maxIndex = i;\n            }\n        }\n        \n        //lets print the actual solution\n        int t = maxIndex;\n        int newT = maxIndex;\n        do{\n            t = newT;\n            System.out.print(arr[t] + \" \");\n            newT = actualSolution[t];\n        }while(t != newT);\n        System.out.println();\n \n        return T[maxIndex];\n    }\n    \n    /**\n     * Recursive way of solving LIS\n     */\n    public int longestSubsequenceRecursive(int arr[]){\n        int maxLen = 0;\n        for(int i=0; i < arr.length-1; i++){\n            int len = longestSubsequenceRecursive(arr,i+1,arr[i]);\n            if(len > maxLen){\n                maxLen = len;\n            }\n        }\n        return maxLen + 1;\n    }\n    \n    private int longestSubsequenceRecursive(int arr[], int pos, int lastNum){\n        if(pos == arr.length){\n            return 0;\n        }\n        int t1 = 0;\n        if(arr[pos] > lastNum){\n            t1 = 1 + longestSubsequenceRecursive(arr, pos+1, arr[pos]);\n        }\n        int t2 = longestSubsequenceRecursive(arr, pos+1, lastNum);\n        return Math.max(t1, t2);\n    }\n    \n    public static void main(String args[]){\n        LongestIncreasingSubsequence lis = new LongestIncreasingSubsequence();\n        int arr[] = {23,10,22,5,33,8,9,21,50,41,60,80,99, 22,23,24,25,26,27};\n        int result = lis.longestSubsequenceWithActualSolution(arr);\n        int result1 = lis.longestSubsequenceRecursive(arr);\n        System.out.println(result);\n        System.out.println(result1);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/LongestPalindromicSubsequence.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 08/01/2014\n * @author Tushar Roy\n *\n * Given a string find longest palindromic subsequence in this string.\n *\n * Time complexity - O(n2)\n * Space complexity - O(n2\n *\n * Youtube link - https://youtu.be/_nCsPn7_OgI\n *\n * References\n * http://www.geeksforgeeks.org/dynamic-programming-set-12-longest-palindromic-subsequence/\n */\npublic class LongestPalindromicSubsequence {\n\n    public int calculate1(char []str){\n        int T[][] = new int[str.length][str.length];\n        for(int i=0; i < str.length; i++){\n            T[i][i] = 1;\n        }\n        for(int l = 2; l <= str.length; l++){\n            for(int i = 0; i < str.length-l + 1; i++){\n                int j = i + l - 1;\n                if(l == 2 && str[i] == str[j]){\n                    T[i][j] = 2;\n                }else if(str[i] == str[j]){\n                    T[i][j] = T[i + 1][j-1] + 2;\n                }else{\n                    T[i][j] = Math.max(T[i + 1][j], T[i][j - 1]);\n                }\n            }\n        }\n        return T[0][str.length-1];\n    }\n\n\n    public int calculateRecursive(char str[],int start,int len){\n        if(len == 1){\n            return 1;\n        }\n        if(len ==0){\n            return 0;\n        }\n        if(str[start] == str[start+len-1]){\n            return 2 + calculateRecursive(str,start+1,len-2);\n        }else{\n            return Math.max(calculateRecursive(str, start+1, len-1), calculateRecursive(str, start, len-1));\n        }\n    }\n    \n    public static void main(String args[]){\n        LongestPalindromicSubsequence lps = new LongestPalindromicSubsequence();\n        String str = \"agbdba\";\n        int r1 = lps.calculateRecursive(str.toCharArray(), 0, str.length());\n        int r2 = lps.calculate1(str.toCharArray());\n        System.out.print(r1 + \" \" + r2);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MatrixMultiplicationCost.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/dynamic-programming-set-8-matrix-chain-multiplication/\n */\npublic class MatrixMultiplicationCost {\n\n    public int findCost(int arr[]){\n        int temp[][] = new int[arr.length][arr.length];\n        int q = 0;\n        for(int l=2; l < arr.length; l++){\n            for(int i=0; i < arr.length - l; i++){\n                int j = i + l;\n                temp[i][j] = 1000000;\n                for(int k=i+1; k < j; k++){\n                    q = temp[i][k] + temp[k][j] + arr[i]*arr[k]*arr[j];\n                    if(q < temp[i][j]){\n                        temp[i][j] = q;\n                    }\n                }\n            }\n        }\n        return temp[0][arr.length-1];\n    }\n    \n    public static void main(String args[]){\n        MatrixMultiplicationCost mmc = new MatrixMultiplicationCost();\n        int arr[] = {4,2,3,5,3};\n        int cost = mmc.findCost(arr);\n        System.out.print(cost);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MaxSumForNonAdjacentElements.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 11/03/2016\n * @author Tushar Roy\n *\n * Find maximum sum for non adjacent elements.\n * Variation is finding maximum sum non adjacent elements assuming its a circular array.\n * So first element cannot be with last element.\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * https://leetcode.com/problems/house-robber/\n * https://leetcode.com/problems/house-robber-ii/\n */\npublic class MaxSumForNonAdjacentElements {\n\n    /**\n     * Fast DP solution.\n     */\n    public int maxSum(int arr[]) {\n        int excl = 0;\n        int incl = arr[0];\n        for (int i = 1; i < arr.length; i++) {\n            int temp = incl;\n            incl = Math.max(excl + arr[i], incl);\n            excl = temp;\n        }\n        return incl;\n    }\n\n    /**\n     * Recursive slow solution.\n     */\n    public int maxSum(int arr[], int index) {\n        if (index == 0) {\n            return arr[0];\n        } else if (index == 1) {\n            return Math.max(arr[0], arr[1]);\n        }\n        return Math.max(this.maxSum(arr, index - 2) + arr[index], this.maxSum(arr, index - 1));\n    }\n\n    /**\n     * Find maximum sum from left to right ignoring first element.\n     * Find maximum sum from right to left ignoring last element.\n     * Maximum of two will be the answer. It gurantees that both first and last element\n     * will be not selected together.\n     */\n    public int maxSumCircularArray(int[] nums) {\n        if (nums.length == 0) {\n            return 0;\n        }\n        if (nums.length == 1) {\n            return nums[0];\n        }\n        int with = nums[1];\n        int without = 0;\n        for (int i = 2; i < nums.length; i++) {\n            int newWith = without + nums[i];\n            without = with;\n            with = Math.max(with, newWith);\n        }\n\n        int with1 = nums[nums.length - 2];\n        int without1 = 0;\n        for (int i = nums.length - 3; i >= 0; i--) {\n            int newWith1 = without1 + nums[i];\n            without1 = with1;\n            with1 = Math.max(with1, newWith1);\n        }\n        return Math.max(with, with1);\n    }\n\n    public static void main(String args[]) {\n        MaxSumForNonAdjacentElements msn = new MaxSumForNonAdjacentElements();\n        int arr[] = { 2, 10, 13, 4, 2, 15, 10 };\n        System.out.println(msn.maxSum(arr));\n        System.out.println(msn.maxSum(arr, arr.length-1));\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MaximizeSkiGates.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 11/23/2015\n * @author Tushar Roy\n *\n * Given starting line and right barrier which is perpendicular to starting line. There are\n * n gates at certain distinct distance from right barrier. Starting from start line how do you ski\n * such that you can cover maximum number of gates. Changing direction is expensive so you can\n * only do limited number of direction changes.\n *\n * Idea at every gate is to either select this gate or not select this gate. Another decision to make\n * is to either change or not change direction at every gate(provided you have remainingDirectionChanges > 0).\n * Do recursion and apply memoization to make it top down recursive solution.\n */\npublic class MaximizeSkiGates {\n    class Index {\n        int remainingChanges;\n        int current;\n        boolean isRight;\n        int prevItem;\n\n        Index(int remainingChanges, int current, boolean isRight, int prevItem) {\n            this.remainingChanges = remainingChanges;\n            this.current = current;\n            this.isRight = isRight;\n            this.prevItem = prevItem;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Index index = (Index) o;\n\n            if (remainingChanges != index.remainingChanges) return false;\n            if (current != index.current) return false;\n            if (isRight != index.isRight) return false;\n            return prevItem == index.prevItem;\n\n        }\n\n        @Override\n        public int hashCode() {\n            int result = remainingChanges;\n            result = 31 * result + current;\n            result = 31 * result + (isRight ? 1 : 0);\n            result = 31 * result + prevItem;\n            return result;\n        }\n    }\n\n    public int solution(int gates[], int totalDirectionChanges) {\n        Map<Index, Integer> dpMap = new HashMap<>();\n        return solution(gates, totalDirectionChanges, 0, false, -1, dpMap);\n    }\n\n    public int solution(int gates[], int remainingDirectionChanges, int current, boolean isRight, int prevItem, Map<Index, Integer> dpMap) {\n        if(current >= gates.length) {\n            return 0;\n        }\n\n        Index index = new Index(remainingDirectionChanges, current, isRight, prevItem);\n        if(dpMap.containsKey(index)) {\n            return dpMap.get(index);\n        }\n\n        int val1 = 0, val2 = 0;\n        //if current gate is picked.\n        if((isRight && gates[current] < prevItem) || (!isRight && gates[current] > prevItem)) {\n            //if we decide to continue in same direction.\n            val1 = 1 + solution(gates, remainingDirectionChanges, current + 1, isRight, gates[current], dpMap);\n            if(remainingDirectionChanges > 0) {\n                //if we flip direction. We can only do that if remainingDirectionChanges > 0\n                val2 = 1 + solution(gates, remainingDirectionChanges - 1, current + 1, !isRight, gates[current], dpMap);\n            }\n        }\n\n        //if current gate is not picked\n        int val3 = solution(gates, remainingDirectionChanges, current + 1, isRight, prevItem, dpMap);\n\n        //max of all 3 possibilities\n        int max = Math.max(Math.max(val1, val2), val3);\n        dpMap.put(index, max);\n        return max;\n    }\n\n    public static void main(String args[]) {\n        int input[] = {15, 13, 5, 7, 4, 10, 12, 8, 2, 11, 6, 9 , 3};\n        MaximizeSkiGates sg = new MaximizeSkiGates();\n        System.out.println(sg.solution(input, 2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MaximumLengthChainPair.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.Arrays;\n\n/**\n * http://www.geeksforgeeks.org/dynamic-programming-set-20-maximum-length-chain-of-pairs/\n */\npublic class MaximumLengthChainPair {\n\n    static class Pair implements Comparable<Pair>{\n        public Pair(int a,int b){\n            this.a = a;\n            this.b = b;\n        }\n        int a;\n        int b;\n        @Override\n        public int compareTo(Pair o) {\n            if(this.a <= o.a){\n                return -1;\n            }else{\n                return 1;\n            }\n        }\n    }\n    \n    public int maxLength(Pair[] arr){\n        Arrays.sort(arr);\n        \n        int T[] = new int[arr.length+1];\n        for(int i=0; i < T.length; i++){\n            T[i] = 1;\n        }\n        for(int i=2; i < T.length; i++){\n            for(int j=1; j < i; j++){\n                if(arr[j-1].b < arr[i-1].a){\n                    T[i] = Math.max(T[j] + 1, T[i]);\n                }\n            }\n        }\n        \n        int max =0 ;\n        for(int i=1; i <T.length; i++){\n            if(max < T[i]){\n                max = T[i];\n            }\n        }\n        return max;\n    }\n    \n    public static void main(String args[]){\n        Pair p = new Pair(5,7);\n        Pair p1 = new Pair(2,3);\n        Pair p2 = new Pair(2,6);\n        Pair p3 = new Pair(9,11);\n        Pair p4 = new Pair(8,10);\n        Pair p5 = new Pair(11,14);\n        \n        Pair[] arr = {p,p1,p2,p3,p4,p5};\n        MaximumLengthChainPair mlcp = new MaximumLengthChainPair();\n        int r = mlcp.maxLength(arr);\n        System.out.print(r);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MaximumProductCutting.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/dynamic-programming-set-36-cut-a-rope-to-maximize-product/\n */\npublic class MaximumProductCutting {\n\n    public int maxProduct(int num){\n        int T[] = new int[num+1];\n        T[0] = 1;\n        for(int i=1; i <= num; i++){\n            T[i] = i;\n        }\n        for(int i=2; i <= num; i++){\n            for(int j=1; j <= i; j++){\n                T[i] = Math.max(T[i],T[j]*T[i-j]);\n            }\n        }\n        return T[num];\n    }\n    \n    public static void main(String args[]){\n        MaximumProductCutting mpc = new MaximumProductCutting();\n        System.out.println(mpc.maxProduct(13));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MaximumRectangularSubmatrixOf1s.java",
    "content": "package com.interview.dynamic;\n\nimport com.interview.stackqueue.MaximumHistogram;\n\n\n/**\n * Date 06/23/2014\n * @author tusroy\n * \n * Video link - https://youtu.be/2xvJ41-hsoE\n * \n * Given a 2D matrix of 0s and 1s. Find largest rectangle of all 1s\n * in this matrix.\n * \n * Maintain a temp array of same size as number of columns. \n * Copy first row to this temp array and find largest rectangular area\n * for histogram. Then keep adding elements of next row to this temp\n * array if they are not zero. If they are zero then put zero there.\n * Every time calculate max area in histogram.\n * \n * Time complexity - O(rows*cols)\n * Space complexity - O(cols) - if number of cols is way higher than rows\n * then do this process for rows and not columns.\n * \n * References:\n * http://www.careercup.com/question?id=6299074475065344\n */\npublic class MaximumRectangularSubmatrixOf1s {\n\n    public int maximum(int input[][]){\n        int temp[] = new int[input[0].length];\n        MaximumHistogram mh = new MaximumHistogram();\n        int maxArea = 0;\n        int area = 0;\n        for(int i=0; i < input.length; i++){\n            for(int j=0; j < temp.length; j++){\n                if(input[i][j] == 0){\n                    temp[j] = 0;\n                }else{\n                    temp[j] += input[i][j];\n                }\n            }\n            area = mh.maxHistogram(temp);\n            if(area > maxArea){\n                maxArea = area;\n            }\n        }\n        return maxArea;\n    }\n    \n    public static void main(String args[]){\n        int input[][] = {{1,1,1,0},\n                         {1,1,1,1},\n                         {0,1,1,0},\n                         {0,1,1,1},\n                         {1,0,0,1},\n                         {1,1,1,1}};\n        MaximumRectangularSubmatrixOf1s mrs = new MaximumRectangularSubmatrixOf1s();\n        int maxRectangle = mrs.maximum(input);\n        //System.out.println(\"Max rectangle is of size \" + maxRectangle);\n        assert maxRectangle == 8;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MaximumSizeSubMatrix.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/maximum-size-sub-matrix-with-all-1s-in-a-binary-matrix/\n */\npublic class MaximumSizeSubMatrix {\n\n    private int min(int a,int b, int c){\n        int l = Math.min(a, b);\n        return Math.min(l, c);\n    }\n    \n    public int maxSize(int arr[][]){\n        \n        int result[][] = new int[arr.length][arr[0].length];\n        int max = 0;\n        for(int i=0; i < arr.length; i++){\n            result[i][0] = arr[i][0];\n            if (result[i][0] == 1)\n            {\n                max = 1;\n            }\n        }\n        \n        for(int i=0; i < arr[0].length; i++){\n            result[0][i] = arr[0][i];\n            if (result[0][i] == 1)\n            {\n                max = 1;\n            }\n            \n        }\n        \n        \n        for(int i=1; i < arr.length; i++){\n            for(int j=1; j < arr[i].length; j++){\n                if(arr[i][j] == 0){\n                    continue;\n                }\n                int t = min(result[i-1][j],result[i-1][j-1],result[i][j-1]);\n                result[i][j] =  t +1;\n                if(result[i][j] > max){\n                    max = result[i][j];\n                }\n            }\n        }\n        return max;\n    }\n    \n    \n    public static void main(String args[]){\n        \n        int arr[][] = {{0,1,1,0,1},{1,1,1,0,0},{1,1,1,1,0},{1,1,1,0,1}};\n        MaximumSizeSubMatrix mssm = new MaximumSizeSubMatrix();\n        int result = mssm.maxSize(arr);\n        System.out.print(result);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MaximumSumSubsequence.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Problem Statement:\n *\n * Given an array of n positive integers. Write a program to find the sum of maximum sum subsequence of the given array\n * such that the integers in the subsequence are in increasing order.\n *\n *\n * Video: https://youtu.be/99ssGWhLPUE\n *\n * Reference:\n * http://www.geeksforgeeks.org/dynamic-programming-set-14-maximum-sum-increasing-subsequence/\n */\npublic class MaximumSumSubsequence {\n\n    public int maxSum(int arr[]){\n        int T[] = new int[arr.length];\n\n        for (int i = 0; i < T.length; i++) {\n            T[i] = arr[i];\n        }\n\n        for(int i=1; i < T.length; i++){\n            for(int j = 0; j < i; j++){\n                if(arr[j] < arr[i]){\n                    T[i] = Math.max(T[i], T[j] + arr[i]);\n                }\n            }\n        }\n\n        int max = T[0];\n        for (int i=1; i < T.length; i++){\n            if(T[i] > max){\n                max = T[i];\n            }\n        }\n        return max;\n    }\n    \n    public static void main(String args[]){\n        MaximumSumSubsequence mss = new MaximumSumSubsequence();\n        int arr[] = {1, 101, 10, 2, 3, 100,4};\n        int r = mss.maxSum(arr);\n        System.out.print(r);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MinCostPath.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/dynamic-programming-set-6-min-cost-path/\n */\npublic class MinCostPath {\n\n    public int minCost(int [][]cost,int m,int n){\n        \n        int temp[][] = new int[m+1][n+1];\n        int sum = 0;\n        for(int i=0; i <= n; i++){\n            temp[0][i] = sum + cost[0][i];\n            sum = temp[0][i];\n        }\n        sum = 0;\n        for(int i=0; i <= m; i++){\n            temp[i][0] = sum + cost[i][0];\n            sum = temp[i][0];\n        }\n        \n        for(int i=1; i <= m; i++){\n            for(int j=1; j <= n; j++){\n                temp[i][j] = cost[i][j] + min(temp[i-1][j-1], temp[i-1][j],temp[i][j-1]);\n            }\n        }\n        return temp[m][n];\n    }\n    \n    public int minCostRec(int cost[][], int m, int n){\n        return minCostRec(cost, m, n, 0 , 0);\n    }\n    \n    public int minCostRec(int cost[][], int m, int n, int x, int y){\n        if(x > m || y > n){\n            return Integer.MAX_VALUE;\n        }\n        if(x == m && y == n){\n            return cost[m][n];\n        }\n        \n        int t1 = minCostRec(cost, m , n, x+1, y);\n        int t2 = minCostRec(cost, m , n, x+1, y+1);\n        int t3 = minCostRec(cost, m , n, x, y+1);\n        \n        return cost[x][y] + min(t1,t2,t3);\n    }\n    \n    private int min(int a,int b, int c){\n        int l = Math.min(a, b);\n        return Math.min(l, c);\n    }\n    \n    public static void main(String args[]){\n        MinCostPath mcp = new MinCostPath();\n        int cost[][] = {{1,2,3},{4,8,2},{1,5,3},{6,2,9}};\n        int result = mcp.minCost(cost, 3, 2);\n        int result1 = mcp.minCostRec(cost, 3, 2);\n        System.out.println(result);\n        System.out.println(result1);\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MinJumpToReachEnd.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.Arrays;\n\n/**\n * Date 06/12/2014 \n * @author tusroy\n * \n * Given an array of non negative integers where each element represents the max \n * number of steps that can be made forward from that element. Write a function to \n * return the minimum number of jumps to reach the end of the array from first element\n * \n * Solution \n * Have 2 for loop. j trails i. If arr[j] + j >= i then you calculate new jump\n * and result.\n * \n * Space complexity O(n) to maintain result and min jumps\n * Time complexity O(n^2)\n * \n * Reference\n * http://www.geeksforgeeks.org/minimum-number-of-jumps-to-reach-end-of-a-given-array/\n */\npublic class MinJumpToReachEnd {\n\n    public int minJump(int arr[],int result[]){\n        \n        int []jump = new int[arr.length];\n        jump[0] = 0;\n        for(int i=1; i < arr.length ; i++){\n            jump[i] = Integer.MAX_VALUE-1;\n        }\n        \n        for(int i=1; i < arr.length; i++){\n            for(int j=0; j < i; j++){\n                if(arr[j] + j >= i){\n                    if(jump[i] > jump[j] + 1){\n                        result[i] = j;\n                        jump[i] = jump[j] + 1;\n                    }\n                }\n            }\n        }\n        \n        return jump[jump.length-1];\n    }\n\n    /**\n     * https://leetcode.com/problems/jump-game-ii/\n     */\n    public int jump(int[] nums) {\n        if (nums.length == 1) {\n            return 0;\n        }\n        int count = 0;\n        int i = 0;\n        while (i + nums[i] < nums.length - 1) {\n            int maxVal = 0;\n            int maxValIndex = 0;\n            for (int j = 1; j <= nums[i]; j++) {\n                if (nums[j + i] + j > maxVal) {\n                    maxVal = nums[j + i] + j;\n                    maxValIndex = i + j;\n                }\n            }\n            i = maxValIndex;\n            count++;\n        }\n        return count + 1;\n    }\n    \n    public static void main(String args[]){\n        MinJumpToReachEnd mj = new MinJumpToReachEnd();\n        int arr[] = {1,3,5,3,2,2,6,1,6,8,9};\n        int r[] = new int[arr.length];\n        int result = mj.minJump(arr,r);\n        System.out.println(result);\n        int i = arr.length-1;\n        Arrays.toString(r);\n        int arr1[] = {2,3,1,1,4};\n        System.out.print(mj.jump(arr));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MinimumCostTrainTicket.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/find-the-minimum-cost-to-reach-a-destination-where-every-station-is-connected-in-one-direction/\n */\npublic class MinimumCostTrainTicket {\n\n    public int minCost(int ticket[][]){\n        assert ticket != null && ticket.length > 0 && ticket.length == ticket[0].length;\n        int T[] = new int[ticket.length];\n        int T1[] = new int[ticket.length];\n        T1[0] = -1;\n        for(int i=1; i < T.length; i++){\n            T[i] = ticket[0][i];\n            T1[i] = i-1;\n        }\n        \n        for(int i=1; i < T.length; i++){\n            for(int j=i+1; j < T.length; j++){\n                if(T[j] > T[i] + ticket[i][j]){\n                    T[j] = T[i] + ticket[i][j];\n                    T1[j] = i;\n                }\n            }\n        }\n        \n        //printing actual stations\n        int i = ticket.length-1;\n        while(i != -1){\n            System.out.print(i + \" \");\n            i = T1[i];\n        }\n        System.out.println();\n        return T[ticket.length-1];\n    }\n    \n    public static void main(String args[]){\n        int input[][] = {{0, 15, 80, 90},\n                         {-1, 0,  40, 50},\n                         {-1, -1,  0,  70},\n                         {-1, -1,  -1,  0}};\n        MinimumCostTrainTicket mctt = new MinimumCostTrainTicket();\n        System.out.println(mctt.minCost(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MinimumNumberOfPerfectSquares.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.*;\n\n/**\n * Date 10/19/2016\n * @author Tushar Roy\n *\n * Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.\n * For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.\n *\n * Solution 1 - Using DP similar to coin change problem with infinite supply\n * Solution 2 - Using a BFS. Put all perfect squares in queue. Then considering each as a node try adding\n * another perfect square and see if we can get n. Keep doing this in BFS fashion till you hit the number.\n *\n * https://leetcode.com/problems/perfect-squares/\n */\npublic class MinimumNumberOfPerfectSquares {\n    public int numSquaresUsingDP(int n) {\n        int count = (int)Math.ceil(Math.sqrt(n));\n\n        int[] T = new int[n + 1];\n\n        T[0] = 0;\n\n        for (int i = 1; i < T.length; i++) {\n            T[i] = Integer.MAX_VALUE;\n            for (int j = 1; j <= count; j++) {\n                if (i < j*j) {\n                    break;\n                }\n                T[i] = Math.min(T[i], T[i - j*j] + 1);\n            }\n        }\n        return T[n];\n    }\n\n    public int numSquaresUsingBFS(int n) {\n        List<Integer> perfectSquares = new ArrayList<>();\n        int i = 1;\n        Queue<Integer> queue = new LinkedList<>();\n        Set<Integer> visited = new HashSet<>();\n        while (true) {\n            int square = i * i;\n            if (square == n) {\n                return 1;\n            }\n            if (square > n) {\n                break;\n            }\n            perfectSquares.add(square);\n            queue.offer(square);\n            visited.add(square);\n            i++;\n        }\n        int distance = 1;\n        while (!queue.isEmpty()) {\n            int size = queue.size();\n            distance++;\n            for (int j = 0; j < size; j++) {\n                int node = queue.poll();\n                for (int square : perfectSquares) {\n                    int sum = node + square;\n                    if (sum == n) {\n                        return distance;\n                    } else if (!visited.contains(sum)) {\n                        visited.add(sum);\n                        queue.add(sum);\n                    } else if (sum > n) {\n                        break;\n                    }\n                }\n            }\n        }\n        return distance;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/MinimumTriangleSum.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.List;\n\n/**\n * Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on\n * the row below.\n * https://leetcode.com/problems/triangle/\n */\npublic class MinimumTriangleSum {\n    public int minimumTotal(List<List<Integer>> triangle) {\n        int n = triangle.size();\n        int[] dp = new int[n];\n\n        for (int i = 0; i < triangle.get(n - 1).size(); i++) {\n            dp[i] = triangle.get(n - 1).get(i);\n        }\n\n        for (int i = triangle.size() - 2; i >= 0; i--) {\n            for (int j = 0; j < triangle.get(i).size(); j++) {\n                dp[j] = triangle.get(i).get(j) + Math.min(dp[j], dp[j + 1]);\n            }\n        }\n        return dp[0];\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/NPotGold.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.glassdoor.com/Interview/N-pots-each-with-some-number-of-gold-coins-are-arranged-in-a-line-You-are-playing-a-game-against-another-player-You-tak-QTN_350584.htm\n * @author tusroy\n * @author Z. Berkay Celik\n */\npublic class NPotGold {\n\n    static class Pair{\n        int first, second;\n        int pick=0;\n        public String toString(){\n            return first + \" \" + second + \" \" + pick;\n        }\n    }\n    public Pair[][] findMoves(int pots[]){\n        \n        Pair[][] moves = new Pair[pots.length][pots.length];\n        \n        for(int i=0; i < moves.length; i++){\n            for(int j=0; j < moves[i].length; j++){\n                moves[i][j] = new Pair();\n            }\n        }\n        \n        for(int i=0; i < pots.length; i++){\n            moves[i][i].first = pots[i];\n            //to track the sequence of moves\n            moves[i][i].pick = i;\n        }\n        \n        for(int l = 2; l <= pots.length; l++){\n            for(int i=0; i <= pots.length - l; i++){\n                int j = i + l -1;\n                if(pots[i] + moves[i+1][j].second > moves[i][j-1].second + pots[j]){\n                    moves[i][j].first = pots[i] + moves[i+1][j].second;\n                    moves[i][j].second = moves[i+1][j].first;\n                    moves[i][j].pick = i;\n                }else{\n                    moves[i][j].first = pots[j] + moves[i][j-1].second;\n                    moves[i][j].second = moves[i][j-1].first;\n                    moves[i][j].pick =j;\n                }\n            }\n        }\n        \n        return moves;\n    }\n    //prints the sequence of values and indexes\n    public void printSequence(int pots[], Pair moves[][]){\n        int i = 0;\n        int j = pots.length - 1;\n        int step;\n        for (int k = 0; k < pots.length; k++) {\n            step = moves[i][j].pick;\n            //this is the value of pick and its index\n            System.out.print(\"value: \" + pots[step] + \" \" + \"index: \" + step + \" \");\n            if (step <= i) {\n                i = i + 1;\n            } else {\n                j = j - 1;\n            }\n        }\n    }\n    public static void main(String args[]){\n        NPotGold npg = new NPotGold();\n        int pots[] = {3,1,5,6,2,9,3};\n        Pair[][] moves = npg.findMoves(pots);\n        for(int i=0; i < moves.length; i++){\n            for(int j=0; j < moves[i].length; j++){\n                System.out.print(moves[i][j] + \"  \");\n            }\n            System.out.print(\"\\n\");\n        }\n        System.out.println(\"The moves by first player and second player:\");\n        npg.printSequence(pots, moves);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/NumberOfPathsInMxNMatrix.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/\n */\npublic class NumberOfPathsInMxNMatrix {\n\n    public int countPathsRecursive(int n, int m){\n        if(n == 1 || m == 1){\n            return 1;\n        }\n        return countPathsRecursive(n-1, m) + countPathsRecursive(n, m-1);\n    }\n    \n    public int countPaths(int n,int m){\n        int T[][] = new int[n][m];\n        for(int i=0; i < n; i++){\n            T[i][0] = 1;\n        }\n        \n        for(int i=0; i < m; i++){\n            T[0][i] = 1;\n        }\n        for(int i=1; i < n; i++){\n            for(int j=1; j < m; j++){\n                T[i][j] = T[i-1][j] + T[i][j-1];\n            }\n        }\n        return T[n-1][m-1];\n    }\n    \n    public static void main(String args[]){\n        NumberOfPathsInMxNMatrix nop = new NumberOfPathsInMxNMatrix();\n        System.out.print(nop.countPathsRecursive(3,3));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/NumberOfWaysToScorePoints.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Finding the number of ways a given score could be reached for a game with 3 different ways of scoring (e.g. 3, 5 and 10 points).\n *test case\n *what happens if total can't be formed with given values\n *what if numbers are 0 or negative\n */\npublic class NumberOfWaysToScorePoints {\n\n    //in this version to make 3 - 1,2 is same as 2,1.\n    //This is similar to coin changing problem\n    public int version1(int score[],int total){\n        int T[] = new int[total+1];\n        T[0] = 1;\n        for(int i=0; i < score.length; i++){\n            for(int j=1; j <= total; j++){\n                if(score[i] <= j){\n                    T[j] += T[j-score[i]];\n                }\n            }\n        }\n        return T[total];\n    } \n    \n    //in this version to make 3 - 1,2 and 2,1 are counted different.\n    //This is same as fibo series only that fibo series looks at last 2 numbers and here we look back k values\n    public int version2(int score[],int total){\n        int T[] = new int[total+1];\n        T[0] = 1;\n        for(int i=1; i <= total ; i++){\n            for(int j=0; j < score.length; j++){\n                if(score[j] <= i){\n                    T[i] += T[i-score[j]];\n                }\n            }\n        }\n        return T[total];\n    }\n    \n    public static void main(String args[]){\n        int score[] = {1,2,3};\n        NumberOfWaysToScorePoints now = new NumberOfWaysToScorePoints();\n        System.out.println(now.version1(score, 4));\n        System.out.println(now.version2(score, 4));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/OptimalTreeSearch.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/dynamic-programming-set-24-optimal-binary-search-tree/\n */\npublic class OptimalTreeSearch {\n\n    public int minCostRec(int input[],int freq[]){\n        \n        return minCostRec(input,freq,0,input.length-1,1);\n    }\n    \n    private int minCostRec(int input[],int freq[],int low,int high,int level){\n        if(low > high){\n            return 0;\n        }\n        \n        int min = Integer.MAX_VALUE;\n        for(int i=low; i <= high; i++){\n            int val = minCostRec(input,freq,low,i-1,level+1) + \n                    minCostRec(input,freq,i+1,high,level+1)\n                    + level*freq[i];\n            if(val < min){\n                min = val;\n            }\n        }\n        return min;\n    }\n    \n    public int minCost(int input[], int freq[]){\n        int T[][] = new int[input.length][input.length];\n        \n        for(int i=0; i < T.length; i++){\n            T[i][i] = freq[i];\n        }\n        \n        for(int l = 2; l <= input.length; l++){\n            for(int i=0; i <= input.length-l; i++){\n                int j = i + l -1;\n                T[i][j] = Integer.MAX_VALUE;\n                int sum = getSum(freq, i, j);\n                \n                for(int k=i; k <= j; k++){\n                     int val = sum + (k-1 < i ? 0 : T[i][k-1]) +\n                            (k+1 > j ? 0 : T[k+1][j]) ;\n                     if(val < T[i][j]){\n                         T[i][j] = val;\n                     }\n                }\n            }\n        }\n        return T[0][input.length-1];\n    }\n    \n    private int getSum(int freq[], int i, int j){\n        int sum = 0;\n        for(int x = i; x <= j; x++){\n            sum += freq[x];\n        }\n        return sum;\n    }\n \n    \n    public static void main(String args[]){\n        int input[] = {10,12,20,35,46};\n        int freq[] = {34,8,50,21,16};\n        OptimalTreeSearch ots = new OptimalTreeSearch();\n        System.out.println(ots.minCost(input, freq));\n        System.out.println(ots.minCostRec(input, freq));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/PaintHouse.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Paint House\n * https://leetcode.com/problems/paint-house/\n * https://leetcode.com/problems/paint-house-ii/\n */\npublic class PaintHouse {\n\n    public int minCostTopDownPainHouse1or2(int[][] costs) {\n        if (costs.length == 0) {\n            return 0;\n        }\n        int[][] dp = new int[costs.length][3];\n        return minCostUtil(costs, 0, -1, 3, dp);\n    }\n\n    private int minCostUtil(int[][] costs, int house, int prevColor, int k, int[][] dp) {\n        if (house == costs.length) {\n            return 0;\n        }\n        int min = Integer.MAX_VALUE;\n        for (int i = 0; i < k; i++) {\n            if (i == prevColor) {\n                continue;\n            }\n            int val;\n            if (dp[house][i] != 0) {\n                val = dp[house][i];\n            } else {\n                val = costs[house][i] + minCostUtil(costs, house + 1, i, k, dp);\n                dp[house][i] = val;\n            }\n            min = Math.min(min, val);\n        }\n        return min;\n    }\n\n    public int minCostBottomUpPaintHouse2(int[][] costs) {\n        if (costs.length == 0 || costs[0].length == 0) {\n            return 0;\n        }\n        int[][] dp = new int[costs.length][costs[0].length];\n        for (int i = 0; i < costs[0].length; i++) {\n            dp[0][i] = costs[0][i];\n        }\n\n        for (int i = 1; i < costs.length; i++) {\n            Pair p = findMinSecondMin(dp[i - 1]);\n            for (int j = 0; j < costs[0].length; j++) {\n                dp[i][j] = costs[i][j];\n                if (j == p.minIndex) {\n                    dp[i][j] += dp[i-1][p.secondMinIndex];\n                } else {\n                    dp[i][j] += dp[i-1][p.minIndex];\n                }\n            }\n        }\n        int min = Integer.MAX_VALUE;\n        for (int i = 0; i < dp[0].length; i++) {\n            min = Math.min(min, dp[dp.length - 1][i]);\n        }\n        return min;\n    }\n\n    class Pair {\n        int minIndex;\n        int secondMinIndex;\n    }\n\n    private Pair findMinSecondMin(int[] input) {\n        int minIndex;\n        int secondMinIndex;\n        if (input[0] < input[1]) {\n            minIndex = 0;\n            secondMinIndex = 1;\n        } else {\n            minIndex = 1;\n            secondMinIndex = 0;\n        }\n        for (int i = 2; i < input.length; i++) {\n            if (input[i] < input[minIndex]) {\n                secondMinIndex = minIndex;\n                minIndex = i;\n            } else if (input[i] < input[secondMinIndex]) {\n                secondMinIndex = i;\n            }\n        }\n        Pair p = new Pair();\n        p.minIndex = minIndex;\n        p.secondMinIndex = secondMinIndex;\n        return p;\n    }\n\n    public static void main(String args[]) {\n        PaintHouse ph = new PaintHouse();\n        int[][] input = {{1, 2, 1}, {1, 4, 5}, {2, 6, 1}, {3, 3, 2}};\n        System.out.println(ph.minCostBottomUpPaintHouse2(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/PalindromePartition.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.*;\n\n/**\n * Date 04/03/2016\n * @author Tushar Roy\n *\n * Partitioning the string into palindromes.\n *\n * https://leetcode.com/problems/palindrome-partitioning/\n * https://leetcode.com/problems/palindrome-partitioning-ii/\n */\npublic class PalindromePartition {\n\n    /*\n     * Given a string s, partition s such that every substring of the partition is a palindrome.\n     * Return the minimum cuts needed for a palindrome partitioning of s.\n     * https://leetcode.com/problems/palindrome-partitioning-ii/\n     */\n    public int minCut(String str){\n        if (str.length() == 0) {\n            return 0;\n        }\n\n        int[] cut = new int[str.length()];\n        boolean isPal[][] = new boolean[str.length()][str.length()];\n        for (int i = 1; i < str.length(); i++) {\n            int min = i;\n            for (int j = 0; j <= i; j++) {\n                if (str.charAt(i) == str.charAt(j) && (i <= j + 1 || isPal[i - 1][j + 1])) {\n                    isPal[i][j] = true;\n                    min = Math.min(min, j == 0 ? 0 : 1 + cut[j - 1]);\n                }\n            }\n            cut[i] = min;\n        }\n        return cut[str.length() - 1];\n    }\n\n    /**\n     * Given a string s, partition s such that every substring of the partition is a palindrome.\n     * https://leetcode.com/problems/palindrome-partitioning/\n     */\n    public List<List<String>> partition(String s) {\n        Map<Integer, List<List<String>>> dp = new HashMap<>();\n        List<List<String>> result =  partitionUtil(s, dp, 0);\n        List<List<String>> r = new ArrayList<>();\n        for (List<String> l : result) {\n            r.add(l);\n        }\n        return r;\n    }\n\n    private List<List<String>> partitionUtil(String s, Map<Integer, List<List<String>>> dp, int start) {\n        if (start == s.length()) {\n            List<String> r = new ArrayList<>();\n            return Collections.singletonList(r);\n        }\n\n        if (dp.containsKey(start)) {\n            return dp.get(start);\n        }\n\n        List<List<String>> words = new ArrayList<>();\n        for (int i = start; i < s.length(); i++) {\n            if (!isPalindrome(s, start, i) ) {\n                continue;\n            }\n            String newWord = s.substring(start, i + 1);\n            List<List<String>> result = partitionUtil(s, dp, i + 1);\n            for (List l : result) {\n                List<String> l1 = new ArrayList<>();\n                l1.add(newWord);\n                l1.addAll(l);\n                words.add(l1);\n            }\n        }\n        dp.put(start, words);\n        return words;\n    }\n\n    private  boolean isPalindrome(String str, int r, int t) {\n        while(r < t) {\n            if (str.charAt(r) != str.charAt(t)) {\n                return false;\n            }\n            r++;\n            t--;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/PhoneDialNumberOfCombinationOfSizeK.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Given the mobile numeric keypad. You can only press buttons that are\n * up,left,right or down to the current button.You are not allowed to press\n * bottom row corner buttons (i.e. * and # ).Given a N find out the number of\n * numbers possible of given length.\n * \n * The idea is that to calculate for i all you have to do is add up i-1 values of all the neighbors.\n * e.g for i =2 and at 0 you need find i=1s of all neighbors including 0 and add them up.\n */\npublic class PhoneDialNumberOfCombinationOfSizeK {\n\n\t/**\n\t * -1 in the input means don't use that position\n\t * \n\t * @param k\n\t * @param input\n\t * @return\n\t */\n\tpublic int numberOfCombination(int k, int input[][]) {\n\t\tif (input == null || input.length == 0) {\n\t\t\tthrow new IllegalArgumentException();\n\t\t}\n\t\tMap<Integer, Integer> t = new HashMap<Integer, Integer>();\n\t\tMap<Integer, Integer> t1 = new HashMap<Integer, Integer>();\n\n\t\tfor (int i = 0; i < input.length; i++) {\n\t\t\tfor (int j = 0; j < input[i].length; j++) {\n\t\t\t\tif (input[i][j] < 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tt1.put(input[i][j], 1);\n\t\t\t}\n\t\t}\n\n\t\tfor (int x = 1; x < k; x++) {\n\t\t\tfor (int i = 0; i < input.length; i++) {\n\t\t\t\tfor (int j = 0; j < input[i].length; j++) {\n\t\t\t\t\tif (input[i][j] < 0) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tfindNeighborsAndPopulateMap(i, j, input, t, t1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcopyMap(t, t1);\n\t\t\tt.clear();\n\t\t}\n\t\tint count = 0;\n\t\tfor (int i : t1.keySet()) {\n\t\t\tcount += t1.get(i);\n\t\t}\n\t\treturn count;\n\t}\n\n\tprivate void copyMap(Map<Integer, Integer> t, Map<Integer, Integer> t1) {\n\t\tfor (Integer i : t.keySet()) {\n\t\t\tint c = t.get(i);\n\t\t\tt1.put(i, c);\n\t\t}\n\t}\n\n\tprivate void findNeighborsAndPopulateMap(int x, int y, int input[][],\n\t\t\tMap<Integer, Integer> t, Map<Integer, Integer> t1) {\n\t\tupdateMap(input, x, y, x - 1, y, t, t1);\n\t\tupdateMap(input, x, y, x, y - 1, t, t1);\n\t\tupdateMap(input, x, y, x, y, t, t1);\n\t\tupdateMap(input, x, y, x, y + 1, t, t1);\n\t\tupdateMap(input, x, y, x + 1, y, t, t1);\n\t}\n\n\tprivate void updateMap(int input[][], int x, int y, int i, int j,\n\t\t\tMap<Integer, Integer> t, Map<Integer, Integer> t1) {\n\t\tif (i < 0 || i >= input.length || j < 0 || j >= input[x].length\n\t\t\t\t|| input[i][j] < 0) {\n\t\t\treturn;\n\t\t}\n\t\tInteger c = t.get(input[x][y]);\n\t\tif (c == null) {\n\t\t\tc = 0;\n\t\t}\n\t\tc += t1.get(input[i][j]);\n\t\tt.put(input[x][y], c);\n\t}\n\n\tpublic static void main(String args[]) {\n\t\tint input[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { -1, 0, -1 } };\n\t\tPhoneDialNumberOfCombinationOfSizeK pdn = new PhoneDialNumberOfCombinationOfSizeK();\n\t\tSystem.out.println(pdn.numberOfCombination(3, input));\n\t}\n\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/RegexMatching.java",
    "content": "package com.interview.dynamic;\n/**\n * Date 06/24/2015\n * @author Tushar Roy\n * \n * Write a program to perform regex matching with * an . \n * \n * References : http://leetcode.com/2011/09/regular-expression-matching.html\n */\npublic class RegexMatching {\n\n    public boolean matchRegexRecursive(char[] str, char[] pattern){\n        return matchRegexRecursive(str,pattern,0,0);\n    }\n    \n    private boolean matchRegexRecursive(char text[], char pattern[], int pos1, int pos2){\n        //if pos2 has reached end of pattern means pos2 should also reach end of text for match\n        //to happen\n        if(pos2 == pattern.length) { \n            return pos1 == text.length;\n        } \n      \n        //if next character is not * means either current value at pattern and text should be same\n        //or current value at pattern should be . in which case you can skip one character of text\n        if(pos2 == pattern.length - 1 || pattern[pos2+1] != '*') {\n            return (pos1 < text.length && (text[pos1] == pattern[pos2] || pattern[pos2] == '.')) && matchRegexRecursive(text, pattern, pos1+1, pos2+1);\n        }\n  \n        //if we have case like abc and ad*bc so here we totally skip d*\n        if(matchRegexRecursive(text, pattern, pos1, pos2+2)){\n            return true;\n        }\n  \n        //For case like abbc and ab*c match first b with b* and then next b to c. If that does not work out\n        //then try next b with b* and then c with c and so on.\n        //if pattern current val is . then skip one character at time from text till we either reach end of text\n        //or a match is found\n        while(pos1 < text.length && (text[pos1] == pattern[pos2] || pattern[pos2] == '.')){\n            if( matchRegexRecursive(text, pattern, pos1+1, pos2+2)){\n                return true;\n            }\n            pos1++;\n        }\n        return false;\n    }\n\n    /**\n     * Dynamic programming technique for regex matching.\n     */\n    public boolean matchRegex(char[] text, char[] pattern) {\n        boolean T[][] = new boolean[text.length + 1][pattern.length + 1];\n\n        T[0][0] = true;\n        //Deals with patterns like a* or a*b* or a*b*c*\n        for (int i = 1; i < T[0].length; i++) {\n            if (pattern[i-1] == '*') {\n                T[0][i] = T[0][i - 2];\n            }\n        }\n\n        for (int i = 1; i < T.length; i++) {\n            for (int j = 1; j < T[0].length; j++) {\n                if (pattern[j - 1] == '.' || pattern[j - 1] == text[i - 1]) {\n                    T[i][j] = T[i-1][j-1];\n                } else if (pattern[j - 1] == '*')  {\n                    T[i][j] = T[i][j - 2];\n                    if (pattern[j-2] == '.' || pattern[j - 2] == text[i - 1]) {\n                        T[i][j] = T[i][j] | T[i - 1][j];\n                    }\n                } else {\n                    T[i][j] = false;\n                }\n            }\n        }\n        return T[text.length][pattern.length];\n    }\n\n    public static void main(String args[]){\n        RegexMatching rm = new RegexMatching();\n        System.out.println(rm.matchRegexRecursive(\"Tushar\".toCharArray(),\"Tushar\".toCharArray()));\n        System.out.println(rm.matchRegexRecursive(\"Tusha\".toCharArray(),\"Tushar*a*b*\".toCharArray()));\n        System.out.println(rm.matchRegexRecursive(\"\".toCharArray(),\"a*b*\".toCharArray()));\n        System.out.println(rm.matchRegexRecursive(\"abbbbccc\".toCharArray(),\"a*ab*bbbbc*\".toCharArray()));\n        System.out.println(rm.matchRegexRecursive(\"abbbbccc\".toCharArray(),\"aa*bbb*bbbc*\".toCharArray()));\n        System.out.println(rm.matchRegexRecursive(\"abbbbccc\".toCharArray(),\".*bcc\".toCharArray()));\n        System.out.println(rm.matchRegexRecursive(\"abbbbccc\".toCharArray(),\".*bcc*\".toCharArray()));\n        System.out.println(rm.matchRegexRecursive(\"abbbbccc\".toCharArray(),\".*bcc*\".toCharArray()));\n        System.out.println(rm.matchRegexRecursive(\"aaa\".toCharArray(),\"ab*a*c*a\".toCharArray()));\n\n        System.out.println(rm.matchRegex(\"aa\".toCharArray(), \"a*\".toCharArray()));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/RemoveFromEndToMake2IntoMinGreaterThanMax.java",
    "content": "package com.interview.dynamic;\n\n/**\n * http://www.geeksforgeeks.org/remove-minimum-elements-either-side-2min-max/\n */\npublic class RemoveFromEndToMake2IntoMinGreaterThanMax {\n\n    public int removeFromEnd(int input[]){\n        return removeFromEnd(input,0,input.length-1);\n    }\n    \n    private int removeFromEnd(int input[],int low,int high){\n        if(low > high){\n            return input.length;\n        }\n        int min = min(input,low,high);\n        int max = max(input,low,high);\n        if(2*min > max){\n            return 0;\n        }\n\n        return Math.min(removeFromEnd(input,low,high-1), removeFromEnd(input,low+1,high)) +1;\n    }\n    \n    private int min(int input[],int low,int high){\n        int min = Integer.MAX_VALUE;\n        for(int i=low; i <=high; i++){\n            if(min > input[i]){\n                min = input[i];\n            }\n        }\n        return min;\n    }\n    private int max(int input[],int low,int high){\n        int max = Integer.MIN_VALUE;\n        for(int i=low; i <=high; i++){\n            if(max < input[i]){\n                max = input[i];\n            }\n        }\n        return max;\n    }\n    \n    public int removeFromEndDynamic(int input[]){\n        int T[][] = new int[input.length][input.length];\n        for(int l=1; l <= input.length; l++){\n            for(int i=0, j = i + l-1; i < input.length-l+1; i++,j++){\n                int min = min(input,i,j);\n                int max = max(input,i,j);\n                if(2*min > max){\n                    T[i][j] = 0;\n                }else{\n                    T[i][j] = Math.min(T[i+1][j] , T[i][j-1]) +1;\n                }\n            }\n        }\n        return T[0][input.length-1];\n    }\n    public static void main(String args[]){\n        int input[] = {5,1,3,1,3,8,3};\n        RemoveFromEndToMake2IntoMinGreaterThanMax rme = new RemoveFromEndToMake2IntoMinGreaterThanMax();\n        System.out.println(rme.removeFromEnd(input));\n        System.out.println(rme.removeFromEndDynamic(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/ScrambledString.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Read question at https://leetcode.com/problems/scramble-string/\n */\npublic class ScrambledString {\n\n    /**\n     * Index for memoization.\n     */\n    private static class Index {\n        int start1;\n        int end1;\n        int start2;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Index index = (Index) o;\n\n            if (start1 != index.start1) return false;\n            if (end1 != index.end1) return false;\n            if (start2 != index.start2) return false;\n            return end2 == index.end2;\n\n        }\n\n        @Override\n        public int hashCode() {\n            int result = start1;\n            result = 31 * result + end1;\n            result = 31 * result + start2;\n            result = 31 * result + end2;\n            return result;\n        }\n\n        int end2;\n    }\n\n    boolean isScrambled(char input1[], char input2[], int start1, int end1, int start2, int end2, Map<Index, Boolean> memMap) {\n\n        //return false conditions\n        if(start1 > end1 || start2 > end2) {\n            return false;\n        }\n        if(end1 - start1 != end2 - start2) {\n            return false;\n        }\n\n        Index index = new Index();\n        index.start1 = start1;\n        index.end1 = end1;\n        index.start2 = start2;\n        index.end2 = end2;\n\n        //if we have already calculated value for index then lets use it instead of recalculating again.\n        if(memMap.containsKey(index)) {\n            return memMap.get(index);\n        }\n\n        //if both input from their respective start to end are same then return true.\n        boolean isSame = true;\n        for(int i= start1, j = start2; i <= end1 && j <= end2; i++, j++) {\n            if(input1[i] != input2[j]) {\n                isSame = false;\n                break;\n            }\n        }\n\n        if(isSame) {\n            memMap.put(index, true);\n            return true;\n        }\n\n\n        //check if both input from their respective start to end have same characters. If not then return false.\n        Map<Character, Integer> countMap = new HashMap<>();\n        for(int i= start1; i <= end1; i++) {\n            countMap.compute(input1[i], (ch, val) -> {\n                    if(val == null) {\n                        return 1;\n                    } else {\n                        return val + 1;\n                    }\n            });\n        }\n\n        for(int i= start2; i <= end2; i++) {\n            countMap.compute(input2[i], (ch, val) -> {\n                if(val == null) {\n                    return -1;\n                } else {\n                    return val - 1;\n                }\n            });\n        }\n\n        //all values in map should have value 0 otherwise there is character mismatch. Return false in that case.\n        long nonZeroCount = countMap.values().stream().filter(val -> val !=0 ).count();\n        if(nonZeroCount > 0) {\n            memMap.put(index, false);\n            return false;\n        }\n\n        //for values from input range try splitting into 2 and check recursively if they match or not.\n        for(int len = 0; len < end1 - start1; len++) {\n            //e.g great gtear so match g ,g and reat, tear\n            if(isScrambled(input1, input2, start1, start1 + len, start2, start2 + len, memMap) &&\n                    isScrambled(input1, input2, start1 + len +1, end1, start2 + len + 1, end2, memMap)) {\n                memMap.put(index, true);\n                return true;\n            }\n            //e.g great reatg so match g,g and reat,reat\n            if(isScrambled(input1, input2, start1, start1 + len, end2 - len, end2, memMap) &&\n                    isScrambled(input1, input2, start1 + len +1, end1, start2, end2 - len -1, memMap)) {\n                memMap.put(index, true);\n                return true;\n            }\n       }\n       memMap.put(index, false);\n       return false;\n    }\n\n    public static void main(String args[]) {\n        ScrambledString ss = new ScrambledString();\n        String str1 = \"great\";\n        String str2 = \"rgtae\";\n        Map<Index, Boolean> memMap = new HashMap<>();\n        boolean result = ss.isScrambled(str1.toCharArray(), str2.toCharArray(), 0, str1.length() - 1, 0, str2.length() -1, memMap);\n        System.out.println(result);\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/StockBuySellKTransactions.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * Date 12/22/2015\n * @author Tushar Roy\n *\n * Given stockc prices for certain days and at most k transactions how to buy and sell\n * to maximize profit.\n *\n * Time complexity - O(number of transactions * number of days)\n * Space complexity - O(number of transcations * number of days)\n *\n * https://leetcode.com/discuss/15153/a-clean-dp-solution-which-generalizes-to-k-transactions\n */\npublic class StockBuySellKTransactions {\n\n    /**\n     * Below solution is accepted by leetcode and runs in space proportional to prices length.\n     */\n    public int maxProfitLinearSpace(int k, int[] prices) {\n        if (k == 0 || prices.length == 0) {\n            return 0;\n        }\n\n        if (k >= prices.length) {\n            return allTimeProfit(prices);\n        }\n        int[] T = new int[prices.length];\n        int[] prev = new int[prices.length];\n        for (int i = 1; i <= k; i++) {\n            int maxDiff = -prices[0];\n            for (int j = 1; j < prices.length; j++) {\n                T[j] = Math.max(T[j - 1], maxDiff + prices[j]);\n                maxDiff = Math.max(maxDiff, prev[j] - prices[j]);\n            }\n            for (int j = 1; j < prices.length; j++) {\n                prev[j] = T[j];\n            }\n        }\n        return T[T.length - 1];\n    }\n\n    public int allTimeProfit(int arr[]){\n        int profit = 0;\n        int localMin = arr[0];\n        for(int i=1; i < arr.length;i++){\n            if(arr[i-1] >= arr[i]){\n                localMin = arr[i];\n            }else{\n                profit += arr[i] - localMin;\n                localMin = arr[i];\n            }\n\n        }\n        return profit;\n    }\n\n    /**\n     * This is faster method which does optimization on slower method\n     * Time complexity here is O(K * number of days)\n     *\n     * Formula is\n     * T[i][j] = max(T[i][j-1], prices[j] + maxDiff)\n     * maxDiff = max(maxDiff, T[i-1][j] - prices[j])\n     */\n    public int maxProfit(int prices[], int K) {\n        if (K == 0 || prices.length == 0) {\n            return 0;\n        }\n        int T[][] = new int[K+1][prices.length];\n\n        for (int i = 1; i < T.length; i++) {\n            int maxDiff = -prices[0];\n            for (int j = 1; j < T[0].length; j++) {\n                T[i][j] = Math.max(T[i][j-1], prices[j] + maxDiff);\n                maxDiff = Math.max(maxDiff, T[i-1][j] - prices[j]);\n            }\n        }\n        printActualSolution(T, prices);\n        return T[K][prices.length-1];\n    }\n\n    /**\n     * This is slow method but easier to understand.\n     * Time complexity is O(k * number of days ^ 2)\n     * T[i][j] = max(T[i][j-1], max(prices[j] - prices[m] + T[i-1][m])) where m is 0...j-1\n     */\n    public int maxProfitSlowSolution(int prices[], int K) {\n        if (K == 0 || prices.length == 0) {\n            return 0;\n        }\n        int T[][] = new int[K+1][prices.length];\n\n        for (int i = 1; i < T.length; i++) {\n            for (int j = 1; j < T[0].length; j++) {\n                int maxVal = 0;\n                for (int m = 0; m < j; m++) {\n                    maxVal = Math.max(maxVal, prices[j] - prices[m] + T[i-1][m]);\n                }\n                T[i][j] = Math.max(T[i][j-1], maxVal);\n            }\n        }\n        printActualSolution(T, prices);\n        return T[K][prices.length - 1];\n    }\n\n    public void printActualSolution(int T[][], int prices[]) {\n        int i = T.length - 1;\n        int j = T[0].length - 1;\n\n        Deque<Integer> stack = new LinkedList<>();\n        while(true) {\n            if(i == 0 || j == 0) {\n                break;\n            }\n            if (T[i][j] == T[i][j-1]) {\n                j = j - 1;\n            } else {\n                stack.addFirst(j);\n                int maxDiff = T[i][j] - prices[j];\n                for (int k = j-1; k >= 0; k--) {\n                    if (T[i-1][k] - prices[k] == maxDiff) {\n                        i = i - 1;\n                        j = k;\n                        stack.addFirst(j);\n                        break;\n                    }\n                }\n            }\n        }\n\n        while(!stack.isEmpty()) {\n            System.out.println(\"Buy at price \" + prices[stack.pollFirst()]);\n            System.out.println(\"Sell at price \" + prices[stack.pollFirst()]);\n        }\n\n    }\n\n    public static void main(String args[]) {\n        StockBuySellKTransactions sbt = new StockBuySellKTransactions();\n        int prices[] = {2, 5, 7, 1, 4, 3, 1, 3};\n\n        System.out.println(\"Max profit fast solution \" + sbt.maxProfit(prices, 3));\n        System.out.println(\"Max profit slow solution \" + sbt.maxProfitSlowSolution(prices, 3));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/SubRectangularMatrixWithMaximumSum.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 07/31/2014\n * @author tusroy\n * \n * Write a program to find maximum sum rectangle in give 2D matrix.\n * Assume there is at least one positive number in the 2D matrix.\n * \n * Solution:\n * Keep temp array with size as number of rows. Start left and right from 0\n * and keep adding values for each row and maintain them in this temp array.\n * Run Kadane's algorithm to find max sum subarray in temp. Now increment right by\n * 1. When right reaches last column reset right to 1 and left to 1.\n * \n * Space complexity of this algorithm is O(row)\n * Time complexity of this algorithm is O(row*col*col)\n * \n * References\n * http://www.geeksforgeeks.org/dynamic-programming-set-27-max-sum-rectangle-in-a-2d-matrix/\n */\npublic class SubRectangularMatrixWithMaximumSum {\n\n    class Result{\n        int maxSum;\n        int leftBound;\n        int rightBound;\n        int upBound;\n        int lowBound;\n        @Override\n        public String toString() {\n            return \"Result [maxSum=\" + maxSum + \", leftBound=\" + leftBound\n                    + \", rightBound=\" + rightBound + \", upBound=\" + upBound\n                    + \", lowBound=\" + lowBound + \"]\";\n        }\n        \n    }\n    \n    public Result maxSum(int input[][]){\n        int rows = input.length;\n        int cols = input[0].length;\n        int temp[] = new int[rows];\n        Result result = new Result();\n        for(int left = 0; left < cols ; left++){\n            for(int i=0; i < rows; i++){\n                temp[i] = 0;\n            }\n            for(int right = left; right < cols; right++){\n                for(int i=0; i < rows; i++){\n                    temp[i] += input[i][right];\n                }\n                KadaneResult kadaneResult = kadane(temp);\n                if(kadaneResult.maxSum > result.maxSum){\n                    result.maxSum = kadaneResult.maxSum;\n                    result.leftBound = left;\n                    result.rightBound = right;\n                    result.upBound = kadaneResult.start;\n                    result.lowBound = kadaneResult.end;\n                }\n            }\n        }\n        return result;\n    }\n    \n    class KadaneResult{\n        int maxSum;\n        int start;\n        int end;\n        public KadaneResult(int maxSum, int start, int end) {\n            this.maxSum = maxSum;\n            this.start = start;\n            this.end = end;\n        }\n    }\n    \n    private KadaneResult kadane(int arr[]){\n        int max = 0;\n        int maxStart = -1;\n        int maxEnd = -1;\n        int currentStart = 0;\n        int maxSoFar = 0;\n        for(int i=0; i < arr.length; i++){\n            maxSoFar += arr[i];\n            if(maxSoFar < 0){\n                maxSoFar = 0;\n                currentStart = i+1;\n            }\n            if(max < maxSoFar){\n                maxStart = currentStart;\n                maxEnd = i;\n                max = maxSoFar;\n            }\n        }\n        return new KadaneResult(max, maxStart, maxEnd);\n    }\n    \n    \n    public static void main(String args[]){\n        int input[][] = {{ 2,  1, -3, -4,  5},\n                         { 0,  6,  3,  4,  1},\n                         { 2, -2, -1,  4, -5},\n                         {-3,  3,  1,  0,  3}};\n        SubRectangularMatrixWithMaximumSum saw = new SubRectangularMatrixWithMaximumSum();\n        System.out.println(saw.maxSum(input));\n    }       \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/SubsetSum.java",
    "content": "package com.interview.dynamic;\n/*\n * Date 09/23/2014\n * @author Tushar Roy\n *\n * Given an array of non negative numbers and a total, is there subset of numbers in this array which adds up\n * to given total. Another variation is given an array is it possible to split it up into 2 equal\n * sum partitions. Partition need not be equal sized. Just equal sum.\n *\n * Time complexity - O(input.size * total_sum)\n * Space complexity - O(input.size*total_sum)\n *\n * Youtube video - https://youtu.be/s6FhG--P7z0\n */\npublic class SubsetSum {\n\n    public boolean subsetSum(int input[], int total) {\n\n        boolean T[][] = new boolean[input.length + 1][total + 1];\n        for (int i = 0; i <= input.length; i++) {\n            T[i][0] = true;\n        }\n\n        for (int i = 1; i <= input.length; i++) {\n            for (int j = 1; j <= total; j++) {\n                if (j - input[i - 1] >= 0) {\n                    T[i][j] = T[i - 1][j] || T[i - 1][j - input[i - 1]];\n                } else {\n                    T[i][j] = T[i-1][j];\n                }\n            }\n        }\n        return T[input.length][total];\n\n    }\n\n    public boolean partition(int arr[]) {\n        int sum = 0;\n        for (int i = 0; i < arr.length; i++) {\n            sum += arr[i];\n        }\n\n        if (sum % 2 != 0) {\n            return false;\n        }\n        sum = sum / 2;\n        boolean[][] T = new boolean[arr.length + 1][sum + 1];\n\n        for (int i = 0; i <= arr.length; i++) {\n            T[i][0] = true;\n        }\n\n        for (int i = 1; i <= arr.length; i++) {\n            for (int j = 1; j <= sum; j++) {\n                if (j - arr[i - 1] >= 0) {\n                    T[i][j] = T[i - 1][j - arr[i - 1]] || T[i - 1][j];\n                } else {\n                    T[i][j] = T[i-1][j];\n                }\n            }\n        }\n        return T[arr.length][sum];\n    }\n\n    public static void main(String args[]) {\n        SubsetSum ss = new SubsetSum();\n        int arr[] = {1, 3, 5, 5, 2, 1, 1, 6};\n        System.out.println(ss.partition(arr));\n\n        int arr1[] = {2, 3, 7, 8};\n        System.out.print(ss.subsetSum(arr1, 11));\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/SubsquareSurrounedByXs.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 09/15/2014\n * @author tusroy\n * \n * Find maximum subsquare in a matrix made up of Xs and Os such that all four sides of subsquare are Xs. It does not matter what is inside\n * the subsquare. All 4 sides should be made up entirely of Xs\n * \n * e.g \n * 0 0 0 0 0 X         0,0  0,0  0,0  0,0  0,0  1,1\n * 0 X 0 X X X         0,0  1,1  0,0  1,1  1,2  2,3 \n * 0 X 0 X 0 X         0,0  2,1  0,0  2,1  0,0  3,1\n * 0 X X X X X         0,0  3,1  1,2  3,3  1,4  4,5\n * 0 0 0 0 0 0         0,0  0,0  0,0  0,0  0,0  0,0   \n * \n * Output of above program should be 3\n * \n * Solution\n * Have another matrix which is capable of holding 2 values hori and ver. \n * Ver stores how far vertically you can see Xs. Hori stores how far horizontally you can see Xs.\n * Once this matrix is build look for biggest subsquare by getting min of hori and ver at each point and checking\n * if subsquare can be formed from value min to 1.\n * \n * Test cases:\n * Matrix entirely made up of Xs\n * Matrix entirely made up of Os\n * Matrix with Xs and Os but maximum subsquare is length 1\n */\npublic class SubsquareSurrounedByXs {\n\n    class Cell{\n        int ver;\n        int hori;\n    }\n    public int findSubSquare(char input[][]){\n        Cell T[][] = new Cell[input.length][input[0].length];\n        for(int i=0; i < T.length; i++){\n            for(int j=0; j < T[0].length; j++){\n                T[i][j] = new Cell();\n            }\n        }\n    \n        for(int i=0; i < input.length; i++){\n            for(int j=0; j < input[0].length; j++){\n                if(input[i][j] == 'X'){\n                    if(i == 0 && j == 0){\n                        T[i][j].hori = 1;\n                        T[i][j].ver = 1;\n                    }\n                    else if(i == 0){\n                        T[i][j].hori = T[i][j-1].hori + 1;\n                        T[i][j].ver = 1;\n                    }else if(j == 0){\n                        T[i][j].ver = T[i-1][j].ver +1;\n                        T[i][j].hori = 1;\n                    }else{\n                        T[i][j].hori = T[i][j-1].hori +1;\n                        T[i][j].ver = T[i-1][j].ver + 1;\n                    }\n                }\n            }\n        }\n        for(int i=0; i < T.length; i++){\n            for(int j=0; j < T[0].length; j++){\n                System.out.print(T[i][j].ver + \",\" + T[i][j].hori+ \"  \");\n            }\n            System.out.println();\n        }\n        \n        //start iterating from bottom right corner and find min of hori or ver at every cell.\n        //If this is greater than 1 then see if you can find a number between this min and 1\n        //such that on left's ver and top's hori is greater greater than or equal to k.\n        int max = 1;\n        for(int i=T.length -1; i >=0 ; i--){\n            for(int j= T[0].length-1 ; j >=0; j--){\n                if(T[i][j].ver == 0 || T[i][j].ver == 1 || T[i][j].hori ==1 ){\n                    continue;\n                }\n                int min = Math.min(T[i][j].ver, T[i][j].hori);\n                int k = 0;\n                for(k=min; k > 1; k--){\n                    if(T[i][j-k+1].ver >= k && T[i-k+1][j].hori >= k){\n                        break;\n                    }\n                }\n                if(max < k){\n                    max = k;\n                }\n            }\n        }\n        \n        return max;\n    }\n    \n    public static void main(String args[]){\n        char[][] input = {{'X','O','O','O','O','O'},\n                          {'O','O','O','O','O','O'},\n                          {'X','X','X','X','O','O'},\n                          {'X','X','X','X','X','O'},\n                          {'X','O','O','X','X','O'},\n                          {'X','O','X','X','X','O'}};\n        \n        char [][] input1 = {{'O', 'O', 'O', 'O', 'O', 'X'},\n                            {'O', 'X', 'O', 'X', 'X', 'X'},\n                            {'O', 'X', 'O', 'X', 'O', 'X'},\n                            {'O', 'X', 'X', 'X', 'X', 'X'},\n                            {'O', 'O', 'O', 'O', 'O', 'O'},\n        };\n        \n        char [][] input2 = {{'O', 'O', 'X', 'O', 'X'},\n                            {'O', 'X', 'X', 'O', 'X'},\n                            {'O', 'X', 'O', 'X', 'X'},\n                            {'X', 'X', 'X', 'X', 'X'},\n                            {'O', 'X', 'X', 'X', 'O'},\n                           };\n\n        SubsquareSurrounedByXs ss = new SubsquareSurrounedByXs();\n        System.out.println(ss.findSubSquare(input));\n        System.out.println(ss.findSubSquare(input1));\n        System.out.println(ss.findSubSquare(input2));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/SymbolExpressionEvaluation.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Date 01/06/2016\n * @author Tushar Roy\n * Let there be a binary operation for 3 symbols a, b, c and result of these binary operation given in a table.\n * Given an expression of these 3 symbols and a final result, tell if this expression can be parenthesize in certain\n * way to produce the final result.\n *\n * Time complexity is O(n^4)\n * Space complexity is O(n^3)\n */\npublic class SymbolExpressionEvaluation {\n\n    public boolean evaluateExpression(char input[][], Map<Character, Integer> index, char[] expression, char result) {\n        Holder[][] T = new Holder[expression.length][expression.length];\n        for (int i = 0; i < T.length; i++) {\n            for (int j = 0; j < T.length; j++) {\n                T[i][j] = new Holder();\n            }\n        }\n\n        for (int i = 0; i < expression.length; i++) {\n            T[i][i].add(expression[i]);\n        }\n\n        for (int l = 2; l <= T.length; l++) {\n            for (int i = 0; i <= T.length - l; i++) {\n                int j = i + l - 1;\n                for (int k = i; k < j; k++) {\n                    for (char ch : T[i][k].values()) {\n                        for (char ch1: T[k+1][j].values()) {\n                            T[i][j].add(input[index.get(ch)][index.get(ch1)]);\n                        }\n                    }\n                }\n            }\n        }\n\n        for (char ch : T[0][T.length-1].values()) {\n            if ( result == ch) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public static void main(String args[]) {\n        Map<Character, Integer> index = new HashMap<>();\n        index.put('a', 0);\n        index.put('b', 1);\n        index.put('c', 2);\n\n        char input[][] = {{'b', 'b', 'a'}, {'c', 'b', 'a'}, {'a', 'c', 'c'}};\n        SymbolExpressionEvaluation sbe = new SymbolExpressionEvaluation();\n        System.out.println(sbe.evaluateExpression(input, index, \"bbbbac\".toCharArray(), 'a'));\n    }\n\n}\n\nclass Holder {\n    private Set<Character> valueHolder = new HashSet<>();\n    void add(Character ch) {\n        valueHolder.add(ch);\n    }\n    Set<Character> values() {\n        return valueHolder;\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/dynamic/TextJustification.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 05/07/2015\n * @author tusroy\n * \n * Video link - https://youtu.be/RORuwHiblPc\n * \n * Given a sequence of words, and a limit on the number of characters that can be put \n * in one line (line width). Put line breaks in the given sequence such that the \n * lines are printed neatly\n * \n * Solution:\n * Badness - We define badness has square of empty spaces in every line. So 2 empty space\n * on one line gets penalized as 4 (2^2) while 1 each empty space on 2 lines gets\n * penalized as 2(1 + 1). So we prefer 1 empty space on different lines over 2 empty space on\n * one line.\n * \n * For every range i,j(words from i to j) find the cost of putting them on one line. If words \n * from i to j cannot fit in one line cost will be infinite. Cost is calculated as square of\n * empty space left in line after fitting words from i to j.\n * \n * Then apply this formula to get places where words need to be going on new line.\n * minCost[i] = minCost[j] + cost[i][j-1]\n * Above formula will try every value of j from i to len and see which one gives minimum \n * cost to split words from i to len.\n * \n * Space complexity is O(n^2)\n * Time complexity is O(n^2)\n * \n * References:\n * http://www.geeksforgeeks.org/dynamic-programming-set-18-word-wrap/\n */\npublic class TextJustification {\n\n    public String justify(String words[], int width) {\n        \n        int cost[][] = new int[words.length][words.length];\n        \n        //next 2 for loop is used to calculate cost of putting words from\n        //i to j in one line. If words don't fit in one line then we put\n        //Integer.MAX_VALUE there.\n        for(int i=0 ; i < words.length; i++){\n            cost[i][i] = width - words[i].length();\n            for(int j=i+1; j < words.length; j++){\n                cost[i][j] = cost[i][j-1] - words[j].length() - 1; \n            }\n        }\n        \n        for(int i=0; i < words.length; i++){\n            for(int j=i; j < words.length; j++){\n                if(cost[i][j] < 0){\n                    cost[i][j] = Integer.MAX_VALUE;\n                }else{\n                    cost[i][j] = (int)Math.pow(cost[i][j], 2);\n                }\n            }\n        }\n        \n        //minCost from i to len is found by trying\n        //j between i to len and checking which\n        //one has min value\n        int minCost[] = new int[words.length];\n        int result[] = new int[words.length];\n        for(int i = words.length-1; i >= 0 ; i--){\n            minCost[i] = cost[i][words.length-1];\n            result[i] = words.length;\n            for(int j=words.length-1; j > i; j--){\n                if(cost[i][j-1] == Integer.MAX_VALUE){\n                    continue;\n                }\n                if(minCost[i] > minCost[j] + cost[i][j-1]){\n                    minCost[i] = minCost[j] + cost[i][j-1];\n                    result[i] = j;\n                }\n            }\n        }\n        int i = 0;\n        int j;\n        \n        System.out.println(\"Minimum cost is \" + minCost[0]);\n        System.out.println(\"\\n\");\n        //finally put all words with new line added in \n        //string buffer and print it.\n        StringBuilder builder = new StringBuilder();\n        do{\n            j = result[i];\n            for(int k=i; k < j; k++){\n                builder.append(words[k] + \" \");\n            }\n            builder.append(\"\\n\");\n            i = j;\n        }while(j < words.length);\n        \n        return builder.toString();\n    }\n    \n    public static void main(String args[]){\n        String words1[] = {\"Tushar\",\"likes\",\"to\",\"write\",\"code\",\"at\", \"free\", \"time\"};\n        TextJustification awl = new TextJustification();\n        System.out.println(awl.justify(words1, 12));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/TwoStringInterleavingToFormThird.java",
    "content": "package com.interview.dynamic;\n\n/**\n *\n * http://www.geeksforgeeks.org/check-whether-a-given-string-is-an-interleaving-of-two-other-given-strings-set-2/\n */\npublic class TwoStringInterleavingToFormThird {\n\n    public boolean isInterleavedRecursive(char str1[], char str2[], char str3[],int pos1, int pos2, int pos3){\n        if(pos1 == str1.length && pos2 == str2.length && pos3 == str3.length){\n            return true;\n        }\n        \n        if(pos3 == str3.length){\n            return false;\n        }\n        \n        return (pos1 < str1.length && str1[pos1] == str3[pos3] && isInterleavedRecursive(str1, str2, str3, pos1+1, pos2, pos3+1))\n                || (pos2 < str2.length && str2[pos2] == str3[pos3] && isInterleavedRecursive(str1, str2, str3, pos1, pos2+1, pos3+1));\n        \n    }\n    \n    public boolean isInterleaved(char str1[], char str2[], char str3[]){\n        boolean T[][] = new boolean[str1.length +1][str2.length +1];\n        \n        if(str1.length + str2.length != str3.length){\n            return false;\n        }\n        \n        for(int i=0; i < T.length; i++){\n            for(int j=0; j < T[i].length; j++){\n                int l = i + j -1;\n                if(i == 0 && j == 0){\n                    T[i][j] = true;\n                }\n                else if(i == 0){\n                    if(str3[l] == str2[j-1]){\n                        T[i][j] = T[i][j-1];\n                    }\n                }\n                else if(j == 0){\n                    if(str1[i-1] == str3[l]){\n                        T[i][j] = T[i-1][j];\n                    }\n                }\n                else{\n                    T[i][j] = (str1[i-1] == str3[l] ? T[i-1][j] : false) || (str2[j-1] == str3[l] ? T[i][j-1] : false);\n                }\n            }\n        }\n        return T[str1.length][str2.length];\n    }\n    \n    public static void main(String args[]){\n        String str1 = \"XXYM\";\n        String str2 = \"XXZT\";\n        String str3 = \"XXXZXYTM\";\n        TwoStringInterleavingToFormThird sti = new TwoStringInterleavingToFormThird();\n        System.out.println(sti.isInterleaved(str1.toCharArray(), str2.toCharArray(), str3.toCharArray()));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/UglyNumbers.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.PriorityQueue;\n\n/**\n * Date 03/08/2016\n * @author Tushar Roy\n *\n * Find nth ugly number.\n *\n * https://leetcode.com/problems/ugly-number-ii/\n * https://leetcode.com/problems/super-ugly-number/\n * http://www.geeksforgeeks.org/ugly-numbers/\n */\npublic class UglyNumbers {\n\n    static class Node implements Comparable<Node> {\n        int inputIndex;\n        int index;\n        int val;\n        Node (int inputIndex, int index, int val) {\n            this.index = index;\n            this.val = val;\n            this.inputIndex = inputIndex;\n        }\n\n        @Override\n        public int compareTo(Node other) {\n            return this.val - other.val;\n        }\n    }\n\n    public int nthSuperUglyNumber1(int n, int[] primes) {\n\n        PriorityQueue<Node> pq = new PriorityQueue<>();\n        for (int i = 0; i < primes.length; i++) {\n            pq.offer(new Node(i, 0, primes[i]));\n        }\n        int[] val = new int[n];\n        val[0] = 1;\n        for (int i = 1; i < n; ) {\n            Node node = pq.poll();\n            if (val[i-1] != node.val) {\n                val[i] = node.val;\n                i++;\n            }\n            node.index = node.index + 1;\n            node.val = primes[node.inputIndex]*val[node.index];\n            pq.offer(node);\n        }\n        return val[n - 1];\n    }\n\n    int ugly(int n){\n        int arr[] = new int[n];\n        int count = 1;\n        arr[0] = 1;\n        int i2 = 0;\n        int i3 = 0;\n        int i5 = 0;\n        while(count < n){\n            int minNumber = min(arr[i2] * 2, arr[i3] * 3, arr[i5] * 5);\n            if(minNumber == arr[i2]*2){\n                i2++;\n            }\n            if(minNumber == arr[i3]*3){\n                i3++;\n            }\n            if(minNumber == arr[i5]*5){\n                i5++;\n            }\n            arr[count++] = minNumber;\n        }\n        \n        return arr[n-1];\n    }\n    \n    private int min(int a,int b, int c){\n        int l = Math.min(a, b);\n        return Math.min(l, c);\n    }\n    \n    public static void main(String args[]) {\n        UglyNumbers ugly = new UglyNumbers();\n        int result = ugly.ugly(150);\n        System.out.println(result);\n        int[] primes = {2, 3, 7, 11};\n        System.out.print(ugly.nthSuperUglyNumber1(17, primes));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/dynamic/WeightedJobSchedulingMaximumProfit.java",
    "content": "package com.interview.dynamic;\n\nimport java.util.Arrays;\nimport java.util.Comparator;\n\nclass Job{\n    int start;\n    int end;\n    int profit;\n    Job(int start,int end,int profit){\n        this.start= start;\n        this.end = end;\n        this.profit= profit;\n    }\n}\n\nclass FinishTimeComparator implements Comparator<Job>{\n\n    @Override\n    public int compare(Job arg0, Job arg1) {\n        if(arg0.end <= arg1.end){\n            return -1;\n        }else{\n            return 1;\n        }\n    }\n    \n}\n\n/**\n * http://www.cs.princeton.edu/courses/archive/spr05/cos423/lectures/06dynamic-programming.pdf\n * Given set of jobs with start and end interval and profit, how to maximize profit such that \n * jobs in subset do not overlap.\n */\npublic class WeightedJobSchedulingMaximumProfit {\n\n    /**\n     * Sort the jobs by finish time.\n     * For every job find the first job which does not overlap with this job\n     * and see if this job profit plus profit till last non overlapping job is greater\n     * than profit till last job.\n     * @param jobs\n     * @return\n     */\n    public int maximum(Job[] jobs){\n        int T[] = new int[jobs.length];\n        FinishTimeComparator comparator = new FinishTimeComparator();\n        Arrays.sort(jobs, comparator);\n        \n        T[0] = jobs[0].profit;\n        for(int i=1; i < jobs.length; i++){\n            T[i] = Math.max(jobs[i].profit, T[i-1]);\n            for(int j=i-1; j >=0; j--){\n                if(jobs[j].end <= jobs[i].start){\n                    T[i] = Math.max(T[i], jobs[i].profit + T[j]);\n                    break;\n                }\n            }\n        }\n        int maxVal = Integer.MIN_VALUE;\n        for (int val : T) {\n            if (maxVal < val) {\n                maxVal = val;\n            }\n        }\n        return maxVal;\n    }\n    \n    public static void main(String args[]){\n        Job jobs[] = new Job[6];\n        jobs[0] = new Job(1,3,5);\n        jobs[1] = new Job(2,5,6);\n        jobs[2] = new Job(4,6,5);\n        jobs[3] = new Job(6,7,4);\n        jobs[4] = new Job(5,8,11);\n        jobs[5] = new Job(7,9,2);\n        WeightedJobSchedulingMaximumProfit mp = new WeightedJobSchedulingMaximumProfit();\n        System.out.println(mp.maximum(jobs));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/dynamic/WildCardMatching.java",
    "content": "package com.interview.dynamic;\n\n/**\n * Date 02/11/2016\n * @author Tushar Roy\n *\n * Wild car matching with ? and *\n *\n * Reference\n * https://leetcode.com/problems/wildcard-matching/\n */\npublic class WildCardMatching {\n    public boolean isMatch(String s, String p) {\n        char[] str = s.toCharArray();\n        char[] pattern = p.toCharArray();\n\n        //replace multiple * with one *\n        //e.g a**b***c --> a*b*c\n        int writeIndex = 0;\n        boolean isFirst = true;\n        for ( int i = 0 ; i < pattern.length; i++) {\n            if (pattern[i] == '*') {\n                if (isFirst) {\n                    pattern[writeIndex++] = pattern[i];\n                    isFirst = false;\n                }\n            } else {\n                pattern[writeIndex++] = pattern[i];\n                isFirst = true;\n            }\n        }\n\n        boolean T[][] = new boolean[str.length + 1][writeIndex + 1];\n\n        if (writeIndex > 0 && pattern[0] == '*') {\n            T[0][1] = true;\n        }\n\n        T[0][0] = true;\n\n        for (int i = 1; i < T.length; i++) {\n            for (int j = 1; j < T[0].length; j++) {\n                if (pattern[j-1] == '?' || str[i-1] == pattern[j-1]) {\n                    T[i][j] = T[i-1][j-1];\n                } else if (pattern[j-1] == '*'){\n                    T[i][j] = T[i-1][j] || T[i][j-1];\n                }\n            }\n        }\n\n        return T[str.length][writeIndex];\n    }\n\n\n    /**\n     * Recursive and slow version of wild card matching.\n     */\n    public boolean isMatchRecursive(String s, String p) {\n        return isMatchRecursiveUtil(s.toCharArray(), p.toCharArray(), 0, 0);\n    }\n\n    private boolean isMatchRecursiveUtil(char[] text, char[] pattern, int pos1, int pos2) {\n        if (pos2 == pattern.length) {\n            return text.length == pos1;\n        }\n\n        if (pattern[pos2] != '*') {\n            if (pos1 < text.length && (text[pos1] == pattern[pos2]) || pattern[pos2] == '?') {\n                return isMatchRecursiveUtil(text, pattern, pos1 + 1, pos2 + 1);\n            } else {\n                return false;\n            }\n        } else {\n            //if we have a***b then skip to the last *\n            while (pos2 < pattern.length - 1 && pattern[pos2 + 1] == '*') {\n                pos2++;\n            }\n            pos1--;\n            while (pos1 < text.length) {\n                if (isMatchRecursiveUtil(text, pattern, pos1 + 1, pos2 + 1)) {\n                    return true;\n                }\n                pos1++;\n            }\n            return false;\n        }\n    }\n\n    public static void main(String args[]) {\n        WildCardMatching wcm = new WildCardMatching();\n        System.out.println(wcm.isMatch(\"xbylmz\", \"x?y*z\"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/geometry/ClosestPairOfPoints.java",
    "content": "package com.interview.geometry;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.List;\n\n/**\n * http://www.geeksforgeeks.org/closest-pair-of-points-onlogn-implementation/\n * https://www.youtube.com/watch?v=_pSl90jq-m0 another good explanation\n * Given coordinates of points find closest pair points distance.\n * \n * Test cases:\n * Number of points should be more than 1\n * Test along positive and negative axis\n * \n * The way it works is\n * 1) Sort by x coordinate\n * 2) Recursively divide into two halves.\n * 3) Find min distance between points in each half. Say this distance is d.\n * 4) Find points which are in either half and closer than d. To find this point sort by y\n * axis and find distance to next 6 points. Magic about 6 points is we can create a rectangular\n * area and only 6 points can fit in that rectangular area. So we need to check only 7 points\n * for each point in rectangular area.\n * @author tusroy\n */\n\n\nclass Point{\n    int x;\n    int y;\n    Point(int x, int y){\n        this.x = x;\n        this.y = y;\n    }\n}\n\nclass XCoordinatorSorter implements Comparator<Point>{\n    @Override\n    public int compare(Point o1, Point o2) {\n        if(o1.x < o2.x){\n            return -1;\n        }else{\n            return 1;\n        }\n    }\n}\n\nclass YCoordinatorSorter implements Comparator<Point>{\n    @Override\n    public int compare(Point o1, Point o2) {\n        if(o1.y < o2.y){\n            return -1;\n        }else{\n            return 1;\n        }\n    }\n}\n\npublic class ClosestPairOfPoints {\n\n    private static final int SIZE = 7;\n    public double closestPairOfPoints(Point[] points){\n        if(points.length < 2){\n            throw new IllegalArgumentException();\n        }\n        Point[] px = new Point[points.length];\n        Point[] py = new Point[points.length];\n        int i=0;\n        for(Point point : points){\n            px[i++] = point;\n        }\n        i=0;\n        for(Point point : points){\n            py[i++] = point;\n        }\n        XCoordinatorSorter xSorter = new XCoordinatorSorter();\n        YCoordinatorSorter ySorter = new YCoordinatorSorter();\n        Arrays.sort(px, xSorter);\n        Arrays.sort(py, ySorter);\n        int minDistance = closestPairOfPoints(px, py, 0, points.length-1);\n        return Math.sqrt(minDistance);\n    }\n    \n    private int closestPairOfPoints(Point[] px, Point[] py,int start, int end){\n        if(end - start < 3){\n            return computeMinDistance(px, start, end);\n        }\n        \n        int mid = (start + end)/2;\n        Point[] pyLeft = new Point[mid-start+1];\n        Point[] pyRight = new Point[end-mid];\n        int i=0, j=0;\n        for(Point p : px){\n            if(p.x <= px[mid].x){\n                pyLeft[i++] = p;\n            }else{\n                pyRight[j++] = p;\n            }\n        }\n        int d1 = closestPairOfPoints(px,pyLeft,start,mid);\n        int d2 = closestPairOfPoints(px, pyRight, mid+1, end);\n        int d = Math.min(d1, d2);\n        \n        List<Point> deltaPoints = new ArrayList<Point>();\n        for(Point p : px){\n            if(Math.sqrt(distance(p,px[mid])) < Math.sqrt(d)){\n                deltaPoints.add(p);\n            }\n        }\n        int d3 = closest(deltaPoints);\n        return Math.min(d3, d);\n    }\n    \n    private int closest(List<Point> deltaPoints){\n        int minDistance = Integer.MAX_VALUE;\n        for(int i=0; i < deltaPoints.size(); i++){\n            for(int j=i+1; j <= i + SIZE && j < deltaPoints.size() ; j++){\n                int distance = distance(deltaPoints.get(i), deltaPoints.get(j));\n                if(minDistance < distance){\n                    minDistance = distance;\n                }\n            }\n        }\n        return minDistance;\n    }\n    \n    private int distance(Point p1, Point p2){\n        return (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y);\n    }\n    \n    private int computeMinDistance(Point[] points, int start, int end){\n        if(end - start == 1){\n            Point p1 = points[start];\n            Point p2 = points[end];\n            return (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y);\n        }else if(end - start == 2){\n            Point p1 = points[start];\n            Point p2 = points[end-1];\n            Point p3 = points[end];\n            return Math.min(Math.min((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y),\n                    (p1.x - p3.x)*(p1.x - p3.x) + (p1.y - p3.y)*(p1.y - p3.y)),\n                    (p2.x - p3.x)*(p2.x - p3.x) + (p2.y - p3.y)*(p2.y - p3.y));\n        }else{\n            throw new IllegalArgumentException();\n        }\n    }\n    \n    public static void main(String args[]){\n        ClosestPairOfPoints cpp = new ClosestPairOfPoints();\n        Point[] points = {new Point(6,2),new Point(4,6),new Point(5,4),new Point(-8,2),new Point(0,2)};\n        double minDistance = cpp.closestPairOfPoints(points);\n        System.out.println(minDistance);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/geometry/GrahamScanConvexHull.java",
    "content": "package com.interview.geometry;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Stack;\n\n/**\n * @author Tushar Roy\n * Date 10/11/2107\n *\n * Convex hull or convex envelope of a set X of points in the Euclidean plane or in a Euclidean space\n * (or, more generally, in an affine space over the reals) is the smallest convex set that contains X.\n *\n * Graham scan finds all vertices of the convex hull ordered along its boundary.\n *\n * Time complexity O(nlogn)\n * Space complexity O(n)\n *\n * References\n * https://leetcode.com/problems/erect-the-fence/description/\n * https://en.wikipedia.org/wiki/Convex_hull\n * https://en.wikipedia.org/wiki/Graham_scan\n * https://discuss.leetcode.com/topic/89336/java-graham-scan-with-adapted-sorting-to-deal-with-collinear-points\n */\npublic class GrahamScanConvexHull {\n\n    static class Point{\n        int x;\n        int y;\n        Point(int x, int y){\n            this.x = x;\n            this.y = y;\n        }\n    }\n\n    public List<Point> findConvexHull(Point[] points) {\n        if (points.length < 2) {\n            return Arrays.asList(points);\n        }\n\n        //find the lowest point in the plane. If there are multiple lowest points\n        //then pick the leftmost one.\n        Point start = points[0];\n        for (int i = 1; i < points.length; i++) {\n            if (start.y > points[i].y) {\n                start = points[i];\n            } else if (start.y == points[i].y && start.x > points[i].x) {\n                start = points[i];\n            }\n        }\n\n        sortToHandleCollinear(points, start);\n\n        Stack<Point> stack = new Stack<>();\n        stack.push(points[0]);\n        stack.push(points[1]);\n        for (int i = 2; i < points.length; i++) {\n            Point top = stack.pop();\n            //second point will always be in answer so this will never cause empty stack exception.\n            //as long as points[i] is on right of vector stack.peek() -> top keep getting rid of top of stack.\n            while (crossProduct(stack.peek(), top, points[i]) < 0) {\n                top = stack.pop();\n            }\n            stack.push(top);\n            stack.push(points[i]);\n        }\n        return new ArrayList<>(stack);\n    }\n\n    private void sortToHandleCollinear(Point[] points, Point start) {\n        Arrays.sort(points, (p1, p2) -> {\n            if (p1 == start) {\n                return -1;\n            }\n            if (p2 == start) {\n                return 1;\n            }\n            int cp = crossProduct(start, p1, p2);\n            if (cp == 0) {\n                return distance(start, p1, p2);\n            } else {\n                return -cp;\n            }\n        });\n\n        //make sure last collinear points are in reverse order of distance.\n        Point p = points[0], q = points[points.length - 1];\n        int i = points.length - 2;\n        while (i >= 0 && crossProduct(p, q, points[i]) == 0) {\n            i--;\n        }\n\n        // reverse sort order of collinear points in the end positions\n        for (int l = i + 1, h = points.length - 1; l < h; l++, h--) {\n            Point tmp = points[l];\n            points[l] = points[h];\n            points[h] = tmp;\n        }\n    }\n\n    /**\n     * Returns < 0 if 'b' is closer to 'a' compared to 'c', == 0 if 'b' and 'c' are same distance from 'a'\n     * or > 0 if 'c' is closer to 'a' compared to 'b'.\n     */\n    private int distance(Point a, Point b, Point c) {\n        int y1 = a.y - b.y;\n        int y2 = a.y - c.y;\n        int x1 = a.x - b.x;\n        int x2 = a.x - c.x;\n        return Integer.compare(y1 * y1 + x1 * x1, y2 * y2 + x2 * x2);\n    }\n\n    /**\n     * Cross product to find where c belongs in reference to vector ab.\n     * If result > 0 it means 'c' is on left of ab\n     *    result == 0 it means 'a','b' and 'c' are collinear\n     *    result < 0  it means 'c' is on right of ab\n     */\n    private int crossProduct(Point a, Point b, Point c) {\n        int y1 = a.y - b.y;\n        int y2 = a.y - c.y;\n        int x1 = a.x - b.x;\n        int x2 = a.x - c.x;\n        return y2 * x1 - y1 * x2;\n    }\n\n    public static void main(String[] args) {\n        GrahamScanConvexHull grahamScanConvexHull = new GrahamScanConvexHull();\n        //int[][] input = new int[][]{{0,0},{0,1},{0,2},{1,2},{2,2},{3,2},{3,1},{3,0},{2,0},{1,0},{1,1},{4,3}};\n        int[][] input = new int[][] {{1,1},{2,2},{2,0},{2,4},{3,3},{4,2}};\n        Point[] points = new Point[input.length];\n        int index = 0;\n        for (int[] i : input) {\n            points[index++] = new Point(i[0], i[1]);\n        }\n        System.out.println(grahamScanConvexHull.findConvexHull(points));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/geometry/JarvisMarchConvexHull.java",
    "content": "package com.interview.geometry;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * @author Tushar Roy\n * Date 10/11/2107\n *\n * Convex hull or convex envelope of a set X of points in the Euclidean plane or in a Euclidean space\n * (or, more generally, in an affine space over the reals) is the smallest convex set that contains X.\n *\n * Jarvis March is finding convex or gift wrapping algorithm.\n *\n * Time complexity O(nh)\n *    n - number of points\n *    h - number of points on the boundary.\n *    Worst case O(n^2)\n *\n * Space complexity O(n^2)\n *\n * Reference\n * https://leetcode.com/problems/erect-the-fence/description/\n * https://en.wikipedia.org/wiki/Convex_hull\n * https://en.wikipedia.org/wiki/Gift_wrapping_algorithm\n */\npublic class JarvisMarchConvexHull {\n\n    class Point{\n        int x;\n        int y;\n        Point(int x, int y){\n            this.x = x;\n            this.y = y;\n        }\n    }\n\n    public List<Point> findConvexHull(Point[] points) {\n        //first find leftmost point to start the march.\n        Point start = points[0];\n        for (int i = 1; i < points.length; i++) {\n            if (points[i].x < start.x) {\n                start = points[i];\n            }\n        }\n        Point current = start;\n        //use set because this algorithm might try to insert duplicate point.\n        Set<Point> result = new HashSet<>();\n        result.add(start);\n        List<Point> collinearPoints = new ArrayList<>();\n        while (true) {\n            Point nextTarget = points[0];\n            for (int i = 1; i < points.length; i++) {\n                if (points[i] == current) {\n                    continue;\n                }\n                int val = crossProduct(current, nextTarget, points[i]);\n                //if val > 0 it means points[i] is on left of current -> nextTarget. Make him the nextTarget.\n                if (val > 0) {\n                    nextTarget = points[i];\n                    //reset collinear points because we now have a new nextTarget.\n                    collinearPoints = new ArrayList<>();\n                } else if (val == 0) { //if val is 0 then collinear current, nextTarget and points[i] are collinear.\n                    //if its collinear point then pick the further one but add closer one to list of collinear points.\n                    if (distance(current, nextTarget, points[i]) < 0) {\n                        collinearPoints.add(nextTarget);\n                        nextTarget = points[i];\n                    } else { //just add points[i] to collinearPoints list. If nextTarget indeed is the next point on\n                        //convex then all points in collinear points will be also on boundary.\n                        collinearPoints.add(points[i]);\n                    }\n                }\n                //else if val < 0 then nothing to do since points[i] is on right side of current -> nextTarget.\n            }\n\n            //add all points in collinearPoints to result.\n            for (Point p : collinearPoints) {\n                result.add(p);\n            }\n            //if nextTarget is same as start it means we have formed an envelope and its done.\n            if (nextTarget == start) {\n                break;\n            }\n            //add nextTarget to result and set current to nextTarget.\n            result.add(nextTarget);\n            current = nextTarget;\n        }\n        return new ArrayList<>(result);\n    }\n\n    /**\n     * Returns < 0 if 'b' is closer to 'a' compared to 'c', == 0 if 'b' and 'c' are same distance from 'a'\n     * or > 0 if 'c' is closer to 'a' compared to 'b'.\n     */\n    private int distance(Point a, Point b, Point c) {\n        int y1 = a.y - b.y;\n        int y2 = a.y - c.y;\n        int x1 = a.x - b.x;\n        int x2 = a.x - c.x;\n        return Integer.compare(y1 * y1 + x1 * x1, y2 * y2 + x2 * x2);\n    }\n\n    /**\n     * Cross product to find where c belongs in reference to vector ab.\n     * If result > 0 it means 'c' is on left of ab\n     *    result == 0 it means 'a','b' and 'c' are collinear\n     *    result < 0  it means 'c' is on right of ab\n     */\n    private int crossProduct(Point a, Point b, Point c) {\n        int y1 = a.y - b.y;\n        int y2 = a.y - c.y;\n        int x1 = a.x - b.x;\n        int x2 = a.x - c.x;\n        return y2 * x1 - y1 * x2;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/geometry/MaximumPointsOnSameLine.java",
    "content": "package com.interview.geometry;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 03/21/2016\n * @author Tushar Roy\n *\n * Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.\n *\n * Time complexity O(n^2) \n * Space complexity O(n)\n *\n * https://leetcode.com/problems/max-points-on-a-line/\n */\npublic class MaximumPointsOnSameLine {\n\n    static class Point {\n        int x;\n        int y;\n        Point() { x = 0; y = 0; }\n        Point(int a, int b) { x = a; y = b; }\n    }\n\n    class Pair {\n        int a;\n        int b;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Pair pair = (Pair) o;\n\n            if (a != pair.a) return false;\n            return b == pair.b;\n\n        }\n\n        @Override\n        public int hashCode() {\n            int result = a;\n            result = 31 * result + b;\n            return result;\n        }\n    }\n\n    public int maxPoints(Point[] points) {\n        int result = 0;\n        for (int i = 0; i < points.length; i++) {\n            Map<Pair, Integer> map = new HashMap<>();\n            int verticalLine = 1;\n            int onePointMax = 1;\n            int samePoint = 0;\n            for (int j = i + 1; j < points.length; j++) {\n                //same point repeated again. Just increment samePoint count\n                if (points[i].x == points[j].x && points[i].y == points[j].y) {\n                    samePoint++;\n                } else if (points[i].x == points[j].x) { //vertical line\n                    verticalLine++;\n                    onePointMax = Math.max(onePointMax, verticalLine);\n                } else {\n                    int gcd = gcd(points[i].y - points[j].y, points[i].x - points[j].x);\n                    Pair p = new Pair();\n                    p.a = (points[i].y - points[j].y)/gcd;\n                    p.b = (points[i].x - points[j].x)/gcd;\n                    int count = 2;\n                    if (map.containsKey(p)) {\n                        count = map.get(p);\n                        count++;\n                        map.put(p, count);\n                    } else {\n                        map.put(p, count);\n                    }\n                    onePointMax = Math.max(onePointMax, count);\n                }\n            }\n            result = Math.max(result, onePointMax + samePoint);\n        }\n        return result;\n    }\n\n    int gcd(int a, int b) {\n        if(b==0) return a;\n        else return gcd(b, a % b);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/geometry/SkylineDrawing.java",
    "content": "package com.interview.geometry;\n\nimport java.util.*;\n\n/**\n * Date 01/07/2016\n * @author Tushar Roy\n *\n * Given skyline of a city merge the buildings\n *\n * Time complexity is O(nlogn)\n * Space complexity is O(n)\n *\n * References\n * https://leetcode.com/problems/the-skyline-problem/\n * https://leetcode.com/discuss/67091/once-for-all-explanation-with-clean-java-code-nlog-time-space\n */\npublic class SkylineDrawing {\n\n    /**\n     * Represents either start or end of building\n     */\n    static class BuildingPoint implements Comparable<BuildingPoint> {\n        int x;\n        boolean isStart;\n        int height;\n\n        @Override\n        public int compareTo(BuildingPoint o) {\n            //first compare by x.\n            //If they are same then use this logic\n            //if two starts are compared then higher height building should be picked first\n            //if two ends are compared then lower height building should be picked first\n            //if one start and end is compared then start should appear before end\n            if (this.x != o.x) {\n                return this.x - o.x;\n            } else {\n                return (this.isStart ? -this.height : this.height) - (o.isStart ? -o.height : o.height);\n            }\n        }\n     }\n\n    public List<int[]> getSkyline(int[][] buildings) {\n\n        //for all start and end of building put them into List of BuildingPoint\n        BuildingPoint[] buildingPoints = new BuildingPoint[buildings.length*2];\n        int index = 0;\n        for(int building[] : buildings) {\n            buildingPoints[index] = new BuildingPoint();\n            buildingPoints[index].x = building[0];\n            buildingPoints[index].isStart = true;\n            buildingPoints[index].height = building[2];\n\n            buildingPoints[index + 1] = new BuildingPoint();\n            buildingPoints[index + 1].x = building[1];\n            buildingPoints[index + 1].isStart = false;\n            buildingPoints[index + 1].height = building[2];\n            index += 2;\n        }\n        Arrays.sort(buildingPoints);\n\n        //using TreeMap because it gives log time performance.\n        //PriorityQueue in java does not support remove(object) operation in log time.\n        TreeMap<Integer, Integer> queue = new TreeMap<>();\n        //PriorityQueue<Integer> queue1 = new PriorityQueue<>(Collections.reverseOrder());\n        queue.put(0, 1);\n        //queue1.add(0);\n        int prevMaxHeight = 0;\n        List<int[]> result = new ArrayList<>();\n        for(BuildingPoint buildingPoint : buildingPoints) {\n            //if it is start of building then add the height to map. If height already exists then increment\n            //the value\n            if (buildingPoint.isStart) {\n                queue.compute(buildingPoint.height, (key, value) -> {\n                    if (value != null) {\n                        return value + 1;\n                    }\n                    return 1;\n                });\n              //  queue1.add(cp.height);\n            } else { //if it is end of building then decrement or remove the height from map.\n                queue.compute(buildingPoint.height, (key, value) -> {\n                    if (value == 1) {\n                        return null;\n                    }\n                    return value - 1;\n                });\n               // queue1.remove(cp.height);\n            }\n            //peek the current height after addition or removal of building x.\n            int currentMaxHeight = queue.lastKey();\n            //int currentMaxHeight = queue1.peek();\n            //if height changes from previous height then this building x becomes critcal x.\n            // So add it to the result.\n            if (prevMaxHeight != currentMaxHeight) {\n                result.add(new int[]{buildingPoint.x, currentMaxHeight});\n                prevMaxHeight = currentMaxHeight;\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        int [][] buildings = {{1,3,4},{3,4,4},{2,6,2},{8,11,4}, {7,9,3},{10,11,2}};\n        SkylineDrawing sd = new SkylineDrawing();\n        List<int[]> criticalPoints = sd.getSkyline(buildings);\n        criticalPoints.forEach(cp -> System.out.println(cp[0] + \" \" + cp[1]));\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/AlientDictionary.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * There is a new alien language which uses the latin alphabet. However, the order among letters\n * are unknown to you. You receive a list of words from the dictionary, where words are sorted\n * lexicographically by the rules of this new language. Derive the order of letters in this language.\n * \n * https://leetcode.com/problems/alien-dictionary/\n */\npublic class AlientDictionary {\n    public String alienOrder(String[] words) {\n        Set<Character> allCharacters = new HashSet<>();\n        Map<Character, Set<Character>> graph = buildGraph(words, new HashMap<>(), allCharacters);\n        Deque<Character> stack = new LinkedList<>();\n        Set<Character> visited = new HashSet<>();\n        Set<Character> dfs = new HashSet<>();\n\n        for (char ch : allCharacters) {\n            if (topSortUtil(ch, stack, visited, dfs, graph)) {\n                return \"\";\n            }\n        }\n\n        StringBuffer buff = new StringBuffer();\n        while (!stack.isEmpty()) {\n            buff.append(stack.pollFirst());\n        }\n        return buff.toString();\n    }\n\n    private boolean topSortUtil(char vertex, Deque<Character> stack, Set<Character> visited, Set<Character> dfs, Map<Character, Set<Character>> graph) {\n        if (visited.contains(vertex)) {\n            return false;\n        }\n        visited.add(vertex);\n        dfs.add(vertex);\n        Set<Character> set = graph.get(vertex);\n        if (set != null) {\n            for (char neighbor : set) {\n                if (dfs.contains(neighbor)) {\n                    return true;\n                }\n                if (topSortUtil(neighbor, stack, visited, dfs, graph)) {\n                    return true;\n                }\n            }\n        }\n        dfs.remove(vertex);\n        stack.offerFirst(vertex);\n        return false;\n    }\n\n    /**\n     * degree is only used for BFS. Not for DFS.\n     */\n    private Map<Character, Set<Character>> buildGraph(String words[], Map<Character, Integer> degree, Set<Character> allCharacters) {\n        getAllChars(words, degree, allCharacters);\n        Set<Character> all = new HashSet<>(allCharacters);\n        Map<Character, Set<Character>> graph = new HashMap<>();\n        for (int i = 0; i < words.length - 1; i++) {\n            String nextWord = words[i + 1];\n            for (int k = 0; k < Math.min(words[i].length(), nextWord.length()); k++) {\n                if (words[i].charAt(k) != nextWord.charAt((k))) {\n                    all.remove(words[i].charAt(k));\n                    Set<Character> set = graph.get(words[i].charAt(k));\n                    if (set == null) {\n                        set = new HashSet<>();\n                        graph.put(words[i].charAt(k), set);\n                    }\n                    set.add(nextWord.charAt(k));\n                    degree.compute(nextWord.charAt(k), (key, count) -> count + 1);\n                    break;\n                }\n            }\n        }\n        for (char ch : all) {\n            graph.put(ch, null);\n        }\n        return graph;\n    }\n\n    private void getAllChars(String words[], Map<Character, Integer> degree, Set<Character> allCharacters) {\n        for (String word : words) {\n            for (char ch : word.toCharArray()) {\n                allCharacters.add(ch);\n                degree.computeIfAbsent(ch, key -> 0);\n            }\n        }\n    }\n\n    public String alienOrder1(String words[]) {\n        Map<Character, Integer> degree = new HashMap<>();\n        Map<Character, Set<Character>> graph = buildGraph(words, degree, new HashSet<>());\n\n        Queue<Character> zeroDegreeNodes = new LinkedList<>();\n        for (Map.Entry<Character, Integer> entry : degree.entrySet()) {\n            if (entry.getValue() == 0) {\n                zeroDegreeNodes.offer(entry.getKey());\n            }\n        }\n\n        StringBuilder result = new StringBuilder();\n\n        while (!zeroDegreeNodes.isEmpty()) {\n            char vertex = zeroDegreeNodes.poll();\n            result.append(vertex);\n            Set<Character> neighbors = graph.get(vertex);\n            if (neighbors != null) {\n                for (char neighbor : graph.get(vertex)) {\n                    int count = degree.get(neighbor);\n                    count--;\n                    if (count == 0) {\n                        zeroDegreeNodes.offer(neighbor);\n                    } else {\n                        degree.put(neighbor, count);\n                    }\n                }\n            }\n            graph.remove(vertex);\n        }\n\n        return graph.size() > 0 ? \"\" : result.toString();\n    }\n\n    public static void main(String args[]) {\n        AlientDictionary ad =  new AlientDictionary();\n        String[] words1 = {\"zy\",\"zx\"};\n        String[] words = {\"wrt\", \"wrf\", \"er\", \"ett\", \"rftt\"};\n        String[] words2 = {\"wrtkj\",\"wrt\"};\n        String result = ad.alienOrder1(words2);\n        System.out.print(result);\n\n\n        //w -> e\n        // e -> r\n        //t -> f\n        //r -> t\n        //\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/AllCyclesInDirectedGraphJohnson.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Date 11/16/2015\n * @author Tushar Roy\n *\n * Find all cycles in directed graph using Johnson's algorithm\n *\n * Time complexity - O(E + V).(c+1) where c is number of cycles found\n * Space complexity - O(E + V + s) where s is sum of length of all cycles.\n *\n * Link to youtube video - https://youtu.be/johyrWospv0\n *\n * References\n * https://github.com/jgrapht/jgrapht/blob/master/jgrapht-core/src/main/java/org/jgrapht/alg/cycle/JohnsonSimpleCycles.java\n */\npublic class AllCyclesInDirectedGraphJohnson {\n    Set<Vertex<Integer>> blockedSet;\n    Map<Vertex<Integer>, Set<Vertex<Integer>>> blockedMap;\n    Deque<Vertex<Integer>> stack;\n    List<List<Vertex<Integer>>> allCycles;\n\n    /**\n     * Main function to find all cycles\n     */\n    public List<List<Vertex<Integer>>> simpleCyles(Graph<Integer> graph) {\n\n        blockedSet = new HashSet<>();\n        blockedMap = new HashMap<>();\n        stack = new LinkedList<>();\n        allCycles = new ArrayList<>();\n        long startIndex = 1;\n        TarjanStronglyConnectedComponent tarjan = new TarjanStronglyConnectedComponent();\n        while(startIndex <= graph.getAllVertex().size()) {\n            Graph<Integer> subGraph = createSubGraph(startIndex, graph);\n            List<Set<Vertex<Integer>>> sccs = tarjan.scc(subGraph);\n            //this creates graph consisting of strongly connected components only and then returns the\n            //least indexed vertex among all the strongly connected component graph.\n            //it also ignore one vertex graph since it wont have any cycle.\n            Optional<Vertex<Integer>> maybeLeastVertex = leastIndexSCC(sccs, subGraph);\n            if(maybeLeastVertex.isPresent()) {\n                Vertex<Integer> leastVertex = maybeLeastVertex.get();\n                blockedSet.clear();\n                blockedMap.clear();\n                findCyclesInSCG(leastVertex, leastVertex);\n                startIndex = leastVertex.getId() + 1;\n            } else {\n                break;\n            }\n        }\n        return allCycles;\n    }\n\n   private Optional<Vertex<Integer>> leastIndexSCC(List<Set<Vertex<Integer>>> sccs, Graph<Integer> subGraph) {\n        long min = Integer.MAX_VALUE;\n        Vertex<Integer> minVertex = null;\n        Set<Vertex<Integer>> minScc = null;\n        for(Set<Vertex<Integer>> scc : sccs) {\n            if(scc.size() == 1) {\n                continue;\n            }\n            for(Vertex<Integer> vertex : scc) {\n                if(vertex.getId() < min) {\n                    min = vertex.getId();\n                    minVertex = vertex;\n                    minScc = scc;\n                }\n            }\n        }\n\n        if(minVertex == null) {\n            return Optional.empty();\n        }\n        Graph<Integer> graphScc = new Graph<>(true);\n        for(Edge<Integer> edge : subGraph.getAllEdges()) {\n            if(minScc.contains(edge.getVertex1()) && minScc.contains(edge.getVertex2())) {\n                graphScc.addEdge(edge.getVertex1().getId(), edge.getVertex2().getId());\n            }\n        }\n        return Optional.of(graphScc.getVertex(minVertex.getId()));\n    }\n\n    private void unblock(Vertex<Integer> u) {\n        blockedSet.remove(u);\n        if(blockedMap.get(u) != null) {\n            blockedMap.get(u).forEach( v -> {\n                if(blockedSet.contains(v)) {\n                    unblock(v);\n                }\n            });\n            blockedMap.remove(u);\n        }\n    }\n\n    private boolean findCyclesInSCG(\n            Vertex<Integer> startVertex,\n            Vertex<Integer> currentVertex) {\n        boolean foundCycle = false;\n        stack.push(currentVertex);\n        blockedSet.add(currentVertex);\n\n        for (Edge<Integer> e : currentVertex.getEdges()) {\n            Vertex<Integer> neighbor = e.getVertex2();\n            //if neighbor is same as start vertex means cycle is found.\n            //Store contents of stack in final result.\n            if (neighbor == startVertex) {\n                List<Vertex<Integer>> cycle = new ArrayList<>();\n                stack.push(startVertex);\n                cycle.addAll(stack);\n                Collections.reverse(cycle);\n                stack.pop();\n                allCycles.add(cycle);\n                foundCycle = true;\n            } //explore this neighbor only if it is not in blockedSet.\n            else if (!blockedSet.contains(neighbor)) {\n                boolean gotCycle =\n                        findCyclesInSCG(startVertex, neighbor);\n                foundCycle = foundCycle || gotCycle;\n            }\n        }\n        //if cycle is found with current vertex then recursively unblock vertex and all vertices which are dependent on this vertex.\n        if (foundCycle) {\n            //remove from blockedSet  and then remove all the other vertices dependent on this vertex from blockedSet\n            unblock(currentVertex);\n        } else {\n            //if no cycle is found with current vertex then don't unblock it. But find all its neighbors and add this\n            //vertex to their blockedMap. If any of those neighbors ever get unblocked then unblock current vertex as well.\n            for (Edge<Integer> e : currentVertex.getEdges()) {\n                Vertex<Integer> w = e.getVertex2();\n                Set<Vertex<Integer>> bSet = getBSet(w);\n                bSet.add(currentVertex);\n            }\n        }\n        //remove vertex from the stack.\n        stack.pop();\n        return foundCycle;\n    }\n\n    private Set<Vertex<Integer>> getBSet(Vertex<Integer> v) {\n        return blockedMap.computeIfAbsent(v, (key) ->\n            new HashSet<>() );\n    }\n\n    private Graph createSubGraph(long startVertex, Graph<Integer> graph) {\n        Graph<Integer> subGraph = new Graph<>(true);\n        for(Edge<Integer> edge : graph.getAllEdges()) {\n            if(edge.getVertex1().getId() >= startVertex && edge.getVertex2().getId() >= startVertex) {\n                subGraph.addEdge(edge.getVertex1().getId(), edge.getVertex2().getId());\n            }\n        }\n        return subGraph;\n    }\n\n    public static void main(String args[]) {\n        AllCyclesInDirectedGraphJohnson johnson = new AllCyclesInDirectedGraphJohnson();\n        Graph<Integer> graph = new Graph<>(true);\n        graph.addEdge(1, 2);\n        graph.addEdge(1, 8);\n        graph.addEdge(1, 5);\n        graph.addEdge(2, 9);\n        graph.addEdge(2, 7);\n        graph.addEdge(2, 3);\n        graph.addEdge(3, 1);\n        graph.addEdge(3, 2);\n        graph.addEdge(3, 6);\n        graph.addEdge(3, 4);\n        graph.addEdge(6, 4);\n        graph.addEdge(4, 5);\n        graph.addEdge(5, 2);\n        graph.addEdge(8, 9);\n        graph.addEdge(9, 8);\n\n        List<List<Vertex<Integer>>> allCycles = johnson.simpleCyles(graph);\n        allCycles.forEach(cycle -> {\n            StringJoiner joiner = new StringJoiner(\"->\");\n            cycle.forEach(vertex -> joiner.add(String.valueOf(vertex.getId())));\n            System.out.println(joiner);\n        });\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/graph/AllCyclesInDirectedGraphTarjan.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Find all simple cycles in a directed graph using Tarjan's algorithm.\n *\n * Space complexity - O(E + V + S) where S is length of all cycles\n * Time complexity - O(E*V(C+1) where C is total number of cycles\n *\n * Reference - https://ecommons.cornell.edu/handle/1813/5941\n * https://github.com/jgrapht/jgrapht/tree/master/jgrapht-core/src/main/java/org/jgrapht/alg/cycle\n */\npublic class AllCyclesInDirectedGraphTarjan {\n\n    private Set<Vertex<Integer>> visited;\n    private Deque<Vertex<Integer>> pointStack;\n    private Deque<Vertex<Integer>> markedStack;\n    private Set<Vertex<Integer>> markedSet;\n\n    public AllCyclesInDirectedGraphTarjan() {\n        reset();\n    }\n\n    private void reset() {\n        visited = new HashSet<>();\n        pointStack = new LinkedList<>();\n        markedStack = new LinkedList<>();\n        markedSet = new HashSet<>();\n    }\n\n    public List<List<Vertex<Integer>>> findAllSimpleCycles(Graph<Integer> graph) {\n        reset();\n        List<List<Vertex<Integer>>> result = new ArrayList<>();\n        for(Vertex<Integer> vertex : graph.getAllVertex()) {\n            findAllSimpleCycles(vertex, vertex, result);\n            visited.add(vertex);\n            while(!markedStack.isEmpty()) {\n                markedSet.remove(markedStack.pollFirst());\n            }\n        }\n        return result;\n    }\n\n    private boolean findAllSimpleCycles(Vertex start, Vertex<Integer> current,List<List<Vertex<Integer>>> result) {\n        boolean hasCycle = false;\n        pointStack.offerFirst(current);\n        markedSet.add(current);\n        markedStack.offerFirst(current);\n\n        for (Vertex<Integer> w : current.getAdjacentVertexes()) {\n            if (visited.contains(w)) {\n                continue;\n            } else if (w.equals(start)) {\n                hasCycle = true;\n                pointStack.offerFirst(w);\n                List<Vertex<Integer>> cycle = new ArrayList<>();\n                Iterator<Vertex<Integer>> itr = pointStack.descendingIterator();\n                while(itr.hasNext()) {\n                    cycle.add(itr.next());\n                }\n                pointStack.pollFirst();\n                result.add(cycle);\n            } else if (!markedSet.contains(w)) {\n                hasCycle = findAllSimpleCycles(start, w, result) || hasCycle;\n            }\n        }\n\n        if (hasCycle) {\n            while(!markedStack.peekFirst().equals(current)) {\n                markedSet.remove(markedStack.pollFirst());\n            }\n            markedSet.remove(markedStack.pollFirst());\n        }\n\n        pointStack.pollFirst();\n        return hasCycle;\n    }\n\n    public static void main(String args[]) {\n        Graph<Integer> graph = new Graph<>(true);\n        graph.addEdge(0, 1);\n        graph.addEdge(1, 4);\n        graph.addEdge(1, 7);\n        graph.addEdge(1, 6);\n        graph.addEdge(4, 2);\n        graph.addEdge(4, 3);\n        graph.addEdge(2, 4);\n        graph.addEdge(2, 7);\n        graph.addEdge(2, 6);\n        graph.addEdge(7, 8);\n        graph.addEdge(7, 5);\n        graph.addEdge(5, 2);\n        graph.addEdge(5, 3);\n        graph.addEdge(3, 7);\n        graph.addEdge(3, 6);\n        graph.addEdge(3, 4);\n        graph.addEdge(6, 5);\n        graph.addEdge(6, 8);\n\n        AllCyclesInDirectedGraphTarjan tarjan = new AllCyclesInDirectedGraphTarjan();\n        List<List<Vertex<Integer>>> result = tarjan.findAllSimpleCycles(graph);\n        result.forEach(cycle -> {\n            cycle.forEach(v -> System.out.print(v.getId() + \" \"));\n            System.out.println();\n        });\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/ArticulationPoint.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Date 08/22/2015\n * @author Tushar Roy\n *\n * Find articulation points in connected undirected graph.\n * Articulation points are vertices such that removing any one of them disconnects the graph.\n *\n * We need to do DFS of this graph and keep visitedTime and lowTime for each vertex.\n * lowTime is keeps track of back edges.\n *\n * If any one of following condition meets then vertex is articulation point.\n *\n * 1) If vertex is root of DFS and has atlesat 2 independent children.(By independent it means they are\n * not connected to each other except via this vertex). This condition is needed because if we\n * started from corner vertex it will meet condition 2 but still is not an articulation point. To filter\n * out those vertices we need this condition.\n *\n * 2) It is not root of DFS and if visitedTime of vertex <= lowTime of any adjacent vertex then its articulation point.\n *\n * Time complexity is O(E + V)\n * Space complexity is O(V)\n *\n * References:\n * https://en.wikipedia.org/wiki/Biconnected_component\n * http://www.geeksforgeeks.org/articulation-points-or-cut-vertices-in-a-graph/\n */\npublic class ArticulationPoint<T> {\n\n    private int time;\n\n    public Set<Vertex<T>> findarticulationPoints(Graph<T> graph) {\n        time = 0;\n        Set<Vertex<T>> visited = new HashSet<>();\n        Set<Vertex<T>> articulationPoints = new HashSet<>();\n        Vertex<T> startVertex = graph.getAllVertex().iterator().next();\n\n        Map<Vertex<T>, Integer> visitedTime = new HashMap<>();\n        Map<Vertex<T>, Integer> lowTime = new HashMap<>();\n        Map<Vertex<T>, Vertex<T>> parent = new HashMap<>();\n\n        DFS(visited,articulationPoints,startVertex, visitedTime, lowTime, parent);\n        return articulationPoints;\n    }\n\n    private void DFS(Set<Vertex<T>> visited,\n            Set<Vertex<T>> articulationPoints, Vertex<T> vertex,\n            Map<Vertex<T>, Integer> visitedTime,\n            Map<Vertex<T>, Integer> lowTime, Map<Vertex<T>, Vertex<T>> parent) {\n        visited.add(vertex);\n        visitedTime.put(vertex, time);\n        lowTime.put(vertex, time);\n        time++;\n        int childCount =0;\n        boolean isArticulationPoint = false;\n        for(Vertex<T> adj : vertex.getAdjacentVertexes()){\n            //if adj is same as parent then just ignore this vertex.\n            if(adj.equals(parent.get(vertex))) {\n                continue;\n            }\n            //if adj has not been visited then visit it.\n            if(!visited.contains(adj)) {\n                parent.put(adj, vertex);\n                childCount++;\n                DFS(visited, articulationPoints, adj, visitedTime, lowTime, parent);\n\n                if(visitedTime.get(vertex) <= lowTime.get(adj)) {\n                    isArticulationPoint = true;\n                } else {\n                    //below operation basically does lowTime[vertex] = min(lowTime[vertex], lowTime[adj]);\n                    lowTime.compute(vertex, (currentVertex, time) ->\n                        Math.min(time, lowTime.get(adj))\n                    );\n                }\n\n            } else { //if adj is already visited see if you can get better low time.\n                //below operation basically does lowTime[vertex] = min(lowTime[vertex], visitedTime[adj]);\n                lowTime.compute(vertex, (currentVertex, time) ->\n                                Math.min(time, visitedTime.get(adj))\n                );\n            }\n        }\n\n        //checks if either condition 1 or condition 2 meets). If yes then it is articulation point.\n        if((parent.get(vertex) == null && childCount >= 2) || parent.get(vertex) != null && isArticulationPoint ) {\n            articulationPoints.add(vertex);\n        }\n        \n    }\n\n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<>(false);\n        graph.addEdge(1, 2);\n        graph.addEdge(2, 3);\n        graph.addEdge(1, 3);\n        graph.addEdge(1, 4);\n        graph.addEdge(4, 5);\n        graph.addEdge(5, 6);\n        graph.addEdge(6, 7);\n        graph.addEdge(7, 5);\n        graph.addEdge(6, 8);\n\n        //bigger example\n        /*\n        graph.addEdge(0, 1);\n        graph.addEdge(0, 2);\n        graph.addEdge(0, 3);\n        graph.addEdge(0, 4);\n        graph.addEdge(4, 2);\n        graph.addEdge(3, 5);\n        graph.addEdge(4, 6);\n        graph.addEdge(6, 3);\n        graph.addEdge(6, 7);\n        graph.addEdge(6, 8);\n        graph.addEdge(7, 9);\n        graph.addEdge(9, 10);\n        graph.addEdge(8, 10);*/\n\n        ArticulationPoint<Integer> ap = new ArticulationPoint<Integer>();\n        Set<Vertex<Integer>> aPoints = ap.findarticulationPoints(graph);\n        aPoints.forEach(point -> System.out.println(point));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/graph/BellmanFordShortestPath.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 11/05/2015\n * @author Tushar Roy\n *\n * Write program for Bellman Ford algorithm to find single source shortest path in directed graph.\n * Bellman ford works with negative edges as well unlike Dijksra's algorithm. If there is negative\n * weight cycle it detects it.\n *\n * Time complexity - O(EV)\n * Space complexity - O(V)\n *\n * References\n * https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm\n * http://www.geeksforgeeks.org/dynamic-programming-set-23-bellman-ford-algorithm/\n */\n\npublic class BellmanFordShortestPath {\n\n    //some random big number is treated as infinity. I m not taking INTEGER_MAX as infinity because\n    //doing any addition on that causes integer overflow\n    private static int INFINITY = 10000000;\n\n    class NegativeWeightCycleException extends RuntimeException {\n    }\n    \n    public Map<Vertex<Integer>, Integer> getShortestPath(Graph<Integer> graph,\n            Vertex<Integer> sourceVertex) {\n\n        Map<Vertex<Integer>, Integer> distance = new HashMap<>();\n        Map<Vertex<Integer>, Vertex<Integer>> parent = new HashMap<>();\n\n        //set distance of every vertex to be infinity initially\n        for(Vertex<Integer> v : graph.getAllVertex()) {\n            distance.put(v, INFINITY);\n            parent.put(v, null);\n        }\n\n        //set distance of source vertex to be 0\n        distance.put(sourceVertex, 0);\n\n        int V = graph.getAllVertex().size();\n\n        //relax edges repeatedly V - 1 times\n        for (int i = 0; i < V - 1 ; i++) {\n            for (Edge<Integer> edge : graph.getAllEdges()) {\n                Vertex<Integer> u = edge.getVertex1();\n                Vertex<Integer> v = edge.getVertex2();\n                //relax the edge\n                //if we get better distance to v via u then use this distance\n                //and set u as parent of v.\n                if (distance.get(u) + edge.getWeight() < distance.get(v)) {\n                    distance.put(v, distance.get(u) + edge.getWeight());\n                    parent.put(v, u);\n                }\n            }\n        }\n\n        //relax all edges again. If we still get lesser distance it means\n        //there is negative weight cycle in the graph. Throw exception in that\n        //case\n        for (Edge<Integer> edge : graph.getAllEdges()) {\n            Vertex<Integer> u = edge.getVertex1();\n            Vertex<Integer> v = edge.getVertex2();\n            if (distance.get(u) + edge.getWeight() < distance.get(v)) {\n                throw new NegativeWeightCycleException();\n            }\n        }\n        return distance;\n    }\n\n    public static void main(String args[]){\n        \n        Graph<Integer> graph = new Graph<>(false);\n        graph.addEdge(0, 3, 8);\n        graph.addEdge(0, 1, 4);\n        graph.addEdge(0, 2, 5);\n        graph.addEdge(1, 2, -3);\n        graph.addEdge(2, 4, 4);\n        graph.addEdge(3, 4, 2);\n        graph.addEdge(4, 3, 1);\n\n        BellmanFordShortestPath shortestPath = new BellmanFordShortestPath();\n        Vertex<Integer> startVertex = graph.getAllVertex().iterator().next();\n        Map<Vertex<Integer>,Integer> distance = shortestPath.getShortestPath(graph, startVertex);\n        System.out.println(distance);\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/graph/BinaryMaxHeap.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class BinaryMaxHeap<T> {\n\n    private List<Node> allNodes = new ArrayList<Node>();\n\n    class Node {\n        int weight;\n        T data;\n    }\n\n    public void add(int weight,T data) {\n\n        Node node = new Node();\n        node.weight = weight;\n        node.data = data;\n        allNodes.add(node);\n        int size = allNodes.size();\n        int current = size - 1;\n        int parentIndex = (current - 1) / 2;\n\n        while (parentIndex >= 0) {\n            Node parentNode = allNodes.get(parentIndex);\n            Node currentNode = allNodes.get(current);\n            if (parentNode.weight < currentNode.weight) {\n                swap(parentNode,currentNode);\n                current = parentIndex;\n                parentIndex = (parentIndex - 1) / 2;\n            } else {\n                break;\n            }\n        }\n\n    }\n\n    private void swap(Node node1,Node node2){\n        int weight = node1.weight;\n        T data = node1.data;\n        \n        node1.data = node2.data;\n        node1.weight = node2.weight;\n        \n        node2.data = data;\n        node2.weight = weight;\n    }\n    \n    public T max(){\n        return allNodes.get(0).data;\n    }\n    \n    public boolean empty(){\n        return allNodes.size() == 0;\n    }\n    \n    \n    public T extractMap(){\n        int size = allNodes.size() -1;\n        T max = allNodes.get(0).data;\n        int lastNodeWeight = allNodes.get(size).weight;\n        allNodes.get(0).weight = lastNodeWeight;\n        allNodes.get(0).data = allNodes.get(size).data;\n        allNodes.remove(size);\n        \n        int currentIndex = 0;\n        size--;\n        while(true){\n            int left = 2*currentIndex + 1;\n            int right = 2*currentIndex + 2;\n            if(left > size){\n                break;\n            }\n            if(right > size){\n                right = left;\n            }\n            int largerIndex = allNodes.get(left).weight >= allNodes.get(right).weight ? left : right;\n            if(allNodes.get(currentIndex).weight < allNodes.get(largerIndex).weight){\n                swap(allNodes.get(currentIndex),allNodes.get(largerIndex));\n                currentIndex = largerIndex;\n            }else{\n                break;\n            }\n        }\n        return max;\n    }\n    \n    public void printHeap(){\n        for(Node n : allNodes){\n            System.out.println(n.weight + \" \" + n.data);\n        }\n    }\n    \n    public static void main(String args[]){\n        BinaryMaxHeap<String> heap = new BinaryMaxHeap<String>();\n        heap.add(3, \"Tushar\");\n        heap.add(4, \"Ani\");\n        heap.add(8, \"Vijay\");\n        heap.add(10, \"Pramila\");\n        heap.add(5, \"Roy\");\n        heap.add(6, \"NTF\");\n        heap.printHeap();\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/BinaryMinHeap.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Date 04/06/2013\n * @author Tushar Roy\n *\n * Data structure to support following operations\n * extracMin - O(logn)\n * addToHeap - O(logn)\n * containsKey - O(1)\n * decreaseKey - O(logn)\n * getKeyWeight - O(1)\n *\n * It is a combination of binary heap and hash map\n *\n */\npublic class BinaryMinHeap<T> {\n\n    private List<Node> allNodes = new ArrayList<>();\n    private Map<T,Integer> nodePosition = new HashMap<>();\n        \n    public class Node {\n        int weight;\n        T key;\n    }\n\n    /**\n     * Checks where the key exists in heap or not\n     */\n    public boolean containsData(T key){\n        return nodePosition.containsKey(key);\n    }\n\n    /**\n     * Add key and its weight to they heap\n     */\n    public void add(int weight,T key) {\n        Node node = new Node();\n        node.weight = weight;\n        node.key = key;\n        allNodes.add(node);\n        int size = allNodes.size();\n        int current = size - 1;\n        int parentIndex = (current - 1) / 2;\n        nodePosition.put(node.key, current);\n\n        while (parentIndex >= 0) {\n            Node parentNode = allNodes.get(parentIndex);\n            Node currentNode = allNodes.get(current);\n            if (parentNode.weight > currentNode.weight) {\n                swap(parentNode,currentNode);\n                updatePositionMap(parentNode.key,currentNode.key,parentIndex,current);\n                current = parentIndex;\n                parentIndex = (parentIndex - 1) / 2;\n            } else {\n                break;\n            }\n        }\n    }\n\n    /**\n     * Get the heap min without extracting the key\n     */\n    public T min(){\n        return allNodes.get(0).key;\n    }\n\n    /**\n     * Checks with heap is empty or not\n     */\n    public boolean empty(){\n        return allNodes.size() == 0;\n    }\n\n    /**\n     * Decreases the weight of given key to newWeight\n     */\n    public void decrease(T data, int newWeight){\n        Integer position = nodePosition.get(data);\n        allNodes.get(position).weight = newWeight;\n        int parent = (position -1 )/2;\n        while(parent >= 0){\n            if(allNodes.get(parent).weight > allNodes.get(position).weight){\n                swap(allNodes.get(parent), allNodes.get(position));\n                updatePositionMap(allNodes.get(parent).key,allNodes.get(position).key,parent,position);\n                position = parent;\n                parent = (parent-1)/2;\n            }else{\n                break;\n            }\n        }\n    }\n\n    /**\n     * Get the weight of given key\n     */\n    public Integer getWeight(T key) {\n        Integer position = nodePosition.get(key);\n        if( position == null ) {\n            return null;\n        } else {\n            return allNodes.get(position).weight;\n        }\n    }\n\n    /**\n     * Returns the min node of the heap\n     */\n    public Node extractMinNode() {\n        int size = allNodes.size() -1;\n        Node minNode = new Node();\n        minNode.key = allNodes.get(0).key;\n        minNode.weight = allNodes.get(0).weight;\n\n        int lastNodeWeight = allNodes.get(size).weight;\n        allNodes.get(0).weight = lastNodeWeight;\n        allNodes.get(0).key = allNodes.get(size).key;\n        nodePosition.remove(minNode.key);\n        nodePosition.remove(allNodes.get(0));\n        nodePosition.put(allNodes.get(0).key, 0);\n        allNodes.remove(size);\n\n        int currentIndex = 0;\n        size--;\n        while(true){\n            int left = 2*currentIndex + 1;\n            int right = 2*currentIndex + 2;\n            if(left > size){\n                break;\n            }\n            if(right > size){\n                right = left;\n            }\n            int smallerIndex = allNodes.get(left).weight <= allNodes.get(right).weight ? left : right;\n            if(allNodes.get(currentIndex).weight > allNodes.get(smallerIndex).weight){\n                swap(allNodes.get(currentIndex), allNodes.get(smallerIndex));\n                updatePositionMap(allNodes.get(currentIndex).key,allNodes.get(smallerIndex).key,currentIndex,smallerIndex);\n                currentIndex = smallerIndex;\n            }else{\n                break;\n            }\n        }\n        return minNode;\n    }\n    /**\n     * Extract min value key from the heap\n     */\n    public T extractMin(){\n        Node node = extractMinNode();\n        return node.key;\n    }\n\n    private void printPositionMap(){\n        System.out.println(nodePosition);\n    }\n\n    private void swap(Node node1,Node node2){\n        int weight = node1.weight;\n        T data = node1.key;\n        \n        node1.key = node2.key;\n        node1.weight = node2.weight;\n        \n        node2.key = data;\n        node2.weight = weight;\n    }\n\n    private void updatePositionMap(T data1, T data2, int pos1, int pos2){\n        nodePosition.remove(data1);\n        nodePosition.remove(data2);\n        nodePosition.put(data1, pos1);\n        nodePosition.put(data2, pos2);\n    }\n    \n    public void printHeap(){\n        for(Node n : allNodes){\n            System.out.println(n.weight + \" \" + n.key);\n        }\n    }\n    \n    public static void main(String args[]){\n        BinaryMinHeap<String> heap = new BinaryMinHeap<String>();\n        heap.add(3, \"Tushar\");\n        heap.add(4, \"Ani\");\n        heap.add(8, \"Vijay\");\n        heap.add(10, \"Pramila\");\n        heap.add(5, \"Roy\");\n        heap.add(6, \"NTF\");\n        heap.add(2,\"AFR\");\n        heap.decrease(\"Pramila\", 1);\n        heap.printHeap();\n        heap.printPositionMap();\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/BiparteGraph.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Set;\n\n/**\n http://www.geeksforgeeks.org/bipartite-graph/\n Includes both DFS and BFS method\n */\npublic class BiparteGraph {\n    \n    public boolean isBiparte(Graph<Integer> graph){\n        \n        Set<Vertex<Integer>> redSet = new HashSet<Vertex<Integer>>();\n        Set<Vertex<Integer>> blueSet = new HashSet<Vertex<Integer>>();\n        \n        Queue<Vertex<Integer>> queue = new LinkedList<Vertex<Integer>>();\n        \n        for(Vertex<Integer> vertex : graph.getAllVertex()){\n            if(!redSet.contains(vertex) && !blueSet.contains(vertex)){\n                queue.add(vertex);\n                redSet.add(vertex);\n                while(!queue.isEmpty()){\n                    vertex = queue.poll();\n                    for(Vertex<Integer> v : vertex.getAdjacentVertexes()){\n                        if(redSet.contains(vertex)){\n                            if(redSet.contains(v)){\n                                return false;\n                            }if(blueSet.contains(v)){\n                                continue;\n                            }\n                            blueSet.add(v);\n                        }\n                        else if(blueSet.contains(vertex)){\n                            if(blueSet.contains(v)){\n                                return false;\n                            }if(redSet.contains(v)){\n                                continue;\n                            }\n                            redSet.add(v);\n                        }\n                        queue.add(v);\n                    }\n                }\n            }\n        }\n        System.out.println(redSet);\n        System.out.println(blueSet);\n        return true;\n    }\n\n    public boolean isBiparteDFS(Graph<Integer> graph){\n        Set<Vertex<Integer>> redSet = new HashSet<Vertex<Integer>>();\n        Set<Vertex<Integer>> blueSet = new HashSet<Vertex<Integer>>();\n        for(Vertex<Integer> vertex : graph.getAllVertex()){\n            if(redSet.contains(vertex) || blueSet.contains(vertex)){\n                continue;\n            }\n            boolean flag = isBiparteDFS(vertex, redSet, blueSet, true);\n            if(!flag){\n                return false;\n            }\n        }\n        return true;\n    }\n    \n    private boolean isBiparteDFS(Vertex<Integer> vertex, Set<Vertex<Integer>> redSet, Set<Vertex<Integer>> blueSet,boolean wasRed){\n    \n        if(wasRed){\n            if(redSet.contains(vertex)){\n                return false;\n            }\n            else if(blueSet.contains(vertex)){\n                return true;\n            }\n            blueSet.add(vertex);\n        }\n\n        else if(!wasRed){\n            if(blueSet.contains(vertex)){\n                return false;\n            }\n            if(redSet.contains(vertex)){\n                return true;\n            }\n            redSet.add(vertex);\n        }\n        \n        for(Vertex<Integer> adj : vertex.getAdjacentVertexes()){\n            boolean flag = isBiparteDFS(adj, redSet, blueSet, !wasRed);\n            if(!flag){\n                return false;\n            }\n        }\n        return true;\n        \n    }\n    \n    public static void main(String argsp[]){\n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addEdge(1, 2);\n        graph.addEdge(2, 5);\n        graph.addEdge(1, 3);\n        graph.addEdge(3, 4);\n        graph.addEdge(4, 6);\n        graph.addEdge(5, 6);\n        graph.addEdge(7, 9);\n        graph.addEdge(7, 8);\n        BiparteGraph bi = new BiparteGraph();\n        boolean result = bi.isBiparteDFS(graph);\n        System.out.print(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/Boggle.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Date 03/04/2016\n * @author Tushar Roy\n *\n * Search for dictionary words in the board.\n * Idea is to use trie for the dictionary which keeps search\n * very efficient.\n *\n * https://leetcode.com/problems/word-search-ii/\n */\npublic class Boggle {\n\n    public List<String> findWords(char[][] board, String[] words) {\n        Trie t = new Trie();\n        for (String word : words) {\n            t.insert(word);\n        }\n        StringBuffer buff = new StringBuffer();\n        Set<String> result = new HashSet<>();\n        Set<Integer> visited = new HashSet<>();\n        for (int i = 0; i < board.length; i++) {\n            for (int j = 0; j < board[i].length; j++) {\n                findWordsUtil(board, t, i, j, buff, visited, result, board[0].length);\n            }\n        }\n        return new ArrayList<>(result);\n    }\n\n    private void findWordsUtil(char[][] board, Trie t , int i, int j, StringBuffer buff, Set<Integer> visited, Set<String> result, int col ) {\n        if (i < 0 || j < 0 || i >= board.length || j >= board[i].length) {\n            return;\n        }\n\n        int val = i*col + j;\n\n        if (visited.contains(val)) {\n            return;\n        }\n\n        buff.append(board[i][j]);\n        String str = buff.toString();\n        if(!t.startsWith(str)) {\n            buff.deleteCharAt(buff.length() - 1);\n            return;\n        }\n        visited.add(val);\n\n        if(t.search(str)) {\n            result.add(buff.toString());\n        }\n\n        findWordsUtil(board, t, i + 1, j, buff, visited, result, col);\n        findWordsUtil(board, t, i, j + 1, buff, visited, result, col);\n        findWordsUtil(board, t, i, j - 1, buff, visited, result, col);\n        findWordsUtil(board, t, i - 1, j, buff, visited, result, col);\n\n        buff.deleteCharAt(buff.length() - 1);\n        visited.remove(val);\n    }\n\n    class TrieNode {\n        TrieNode[] child = new TrieNode[26];\n        boolean isWord;\n        public TrieNode() {\n        }\n    }\n\n    class Trie {\n        private TrieNode root;\n\n        public Trie() {\n            root = new TrieNode();\n        }\n\n        // Inserts a word into the trie.\n        public void insert(String word) {\n            TrieNode current = root;\n            for (int i = 0; i < word.length(); i++) {\n                char ch = (char)(word.charAt(i) - 'a');\n\n                if (current.child[ch] == null) {\n                    current.child[ch] = new TrieNode();\n                }\n                current = current.child[ch];\n            }\n            current.isWord = true;\n        }\n\n        // Returns if the word is in the trie.\n        public boolean search(String word) {\n            TrieNode current = root;\n            for (int i = 0; i < word.length(); i++) {\n                char ch = (char)(word.charAt(i) - 'a');\n                if (current.child[ch] == null) {\n                    return false;\n                }\n                current = current.child[ch];\n            }\n            return current.isWord;\n        }\n\n        // Returns if there is any word in the trie\n        // that starts with the given prefix.\n        public boolean startsWith(String prefix) {\n            TrieNode current = root;\n            for (int i = 0; i < prefix.length(); i++) {\n                char ch = (char)(prefix.charAt(i) - 'a');\n                if (current.child[ch] == null) {\n                    return false;\n                }\n                current = current.child[ch];\n            }\n            return true;\n        }\n\n        public void printTrie() {\n            printTrieUtil(root);\n        }\n\n        private void printTrieUtil(TrieNode root) {\n            if (root == null) {\n                return;\n            }\n            for (int i = 0; i < root.child.length; i++) {\n                if (root.child[i] != null) {\n                    System.out.println((char)(i + 'a'));\n                    printTrieUtil(root.child[i]);\n                }\n            }\n        }\n    }\n\n    public static void main(String args[]) {\n        char[][] board = {{'o','a','a','n'},{'e','t','a','e'},{'i','h','k','r'},{'i','f','l','v'}};\n        String[] words = {\"oath\",\"pea\",\"eat\",\"rain\"};\n        Boggle boggle = new Boggle();\n        List<String> result = boggle.findWords(board, words);\n        result.stream().forEach(s -> System.out.println(s));\n    }\n}"
  },
  {
    "path": "src/com/interview/graph/Bridge.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n http://www.geeksforgeeks.org/bridge-in-a-graph/\n */\npublic class Bridge<T> {\n\n    private int time;\n    \n    public Set<Edge<T>> getBridge(Graph<T> graph){\n        \n        Set<Edge<T>> result = new HashSet<Edge<T>>();\n        Map<Vertex<T>,Integer> discovery = new HashMap<Vertex<T>,Integer>();\n        Map<Vertex<T>,Integer> low = new HashMap<Vertex<T>,Integer>();\n        Map<Vertex<T>,Vertex<T>> parent = new HashMap<Vertex<T>,Vertex<T>>();\n        Map<Vertex<T>,Boolean> visited = new HashMap<Vertex<T>,Boolean>();\n        \n        for(Vertex<T> vertex : graph.getAllVertex()){\n            if(!visited.containsKey(vertex)){\n                BridgeUtil(vertex,result,discovery,low,parent,visited);\n            }\n        }\n        return result;\n    }\n\n    private void BridgeUtil(Vertex<T> vertex, Set<Edge<T>> result,Map<Vertex<T>,Integer> discovery,\n            Map<Vertex<T>,Integer> low,Map<Vertex<T>,Vertex<T>> parent,Map<Vertex<T>,Boolean> visited){\n        visited.put(vertex, true);\n        discovery.put(vertex, time);\n        low.put(vertex, time);\n        time++;\n        for(Vertex<T> child : vertex.getAdjacentVertexes()){\n            if(!visited.containsKey(child)){\n                parent.put(child, vertex);\n                BridgeUtil(child,result,discovery,low,parent,visited);\n                \n                if(discovery.get(vertex) < low.get(child) ){\n                    result.add(new Edge<T>(vertex,child));\n                }\n                low.put(vertex, Math.min(discovery.get(vertex), low.get(child)));\n            }else{\n                if(!child.equals(parent.get(vertex))){\n                    low.put(vertex,Math.min(discovery.get(vertex), low.get(child)));\n                }\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        \n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addEdge(2, 1);\n        graph.addEdge(3, 1);\n        graph.addEdge(1, 4);\n        graph.addEdge(4, 5);\n        graph.addEdge(5, 1);\n        Bridge<Integer> ap = new Bridge<Integer>();\n        Set<Edge<Integer>> result = ap.getBridge(graph);\n        System.out.print(result);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/graph/CloneDirectedGraph.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Given a directed graph clone it in O(n) time where n is total number of edges\n * Test cases\n * Graph is directed/non directed\n * Graph has 0 edges\n * Graph has cycle\n * Graph is linear\n * Graph is dense\n * Graph is sparse\n */\npublic class CloneDirectedGraph<T> {\n\n    public Graph<T> clone(Graph<T> graph){\n        if(graph == null){\n            return null;\n        }\n        if(!graph.isDirected){\n            throw new IllegalArgumentException(\"Cloning non directed graph\");\n        }\n        if(graph.getAllVertex().size() == 0){\n            throw new IllegalArgumentException(\"No vertex in the graph\");\n        }\n        Map<Vertex<T>,Vertex<T>> cloneMap = new HashMap<Vertex<T>,Vertex<T>>();\n        for(Vertex<T> vertex : graph.getAllVertex()){\n            clone(vertex,cloneMap);\n        }\n        Graph<T> clonedGraph = new Graph<>(true);\n        for(Vertex<T> vertex : cloneMap.values()){\n            clonedGraph.addVertex(vertex);\n        }\n        return clonedGraph;\n    }\n    \n    private void clone(Vertex<T> origVertex,Map<Vertex<T>,Vertex<T>> cloneMap){\n        Vertex<T> cloneVertex = null;\n        if(cloneMap.containsKey(origVertex)){\n            cloneVertex = cloneMap.get(origVertex);\n        }else{\n            cloneVertex = new Vertex<T>(origVertex.getId()*10);\n            cloneMap.put(origVertex, cloneVertex);\n        }\n        for(Edge<T> edge : origVertex.getEdges()){\n            if(edge.getVertex1().equals(origVertex)){\n                Vertex<T> adjVertex = edge.getVertex2();\n                updateMap(cloneMap,cloneVertex,adjVertex,edge);\n            }else{\n                Vertex<T> adjVertex = edge.getVertex1();\n                updateMap(cloneMap,cloneVertex,adjVertex,edge);\n            }\n        }\n    }\n    \n    private void updateMap(Map<Vertex<T>,Vertex<T>> cloneMap, Vertex<T> cloneVertex, Vertex<T> adjVertex, Edge<T> edge){\n        if(cloneMap.containsKey(adjVertex)){\n            Vertex<T> adjVertexClone = cloneMap.get(adjVertex);\n            Edge<T> newEdge = new Edge<T>(cloneVertex, adjVertexClone, edge.isDirected(), edge.getWeight());\n            cloneVertex.addAdjacentVertex(newEdge, adjVertexClone);\n        }else{\n            Vertex<T> adjVertexClone = new Vertex<T>(adjVertex.getId());\n            cloneMap.put(adjVertex, adjVertexClone);\n            Edge<T> newEdge = new Edge<T>(cloneVertex, adjVertexClone, edge.isDirected(), edge.getWeight());\n            cloneVertex.addAdjacentVertex(newEdge, adjVertexClone);\n        }\n    }\n    \n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<Integer>(true);\n        graph.addEdge(0, 3);\n        graph.addEdge(0, 2);\n        graph.addEdge(0, 4);\n        graph.addEdge(3, 2);\n        graph.addEdge(2, 0);\n        graph.addEdge(4, 3);\n        graph.addEdge(4, 1);\n        graph.addEdge(1, 2);\n        \n        CloneDirectedGraph<Integer> cg = new CloneDirectedGraph<>();\n        Graph<Integer> clonedGraph = cg.clone(graph);\n        System.out.println(clonedGraph);\n   }\n}\n"
  },
  {
    "path": "src/com/interview/graph/CloneGraph.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.\n * https://leetcode.com/problems/clone-graph/\n */\npublic class CloneGraph {\n\n    class UndirectedGraphNode {\n        int label;\n        List<UndirectedGraphNode> neighbors;\n        UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }\n     };\n\n    public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {\n        if (node == null) {\n            return null;\n        }\n        UndirectedGraphNode clone = new UndirectedGraphNode(node.label);\n        Set<Integer> visited = new HashSet<>();\n        Map<Integer, UndirectedGraphNode> map = new HashMap<>();\n        map.put(clone.label, clone);\n        dfs(node, clone, map, visited);\n        return clone;\n    }\n\n    private void dfs(UndirectedGraphNode current, UndirectedGraphNode clone, Map<Integer, UndirectedGraphNode> map,  Set<Integer> visited) {\n        if (visited.contains(current.label)) {\n            return;\n        }\n        visited.add(current.label);\n        for (UndirectedGraphNode adj : current.neighbors) {\n            if (adj.label != current.label) {\n                UndirectedGraphNode adjClone = map.get(adj.label);\n                if (adjClone == null) {\n                    adjClone = new UndirectedGraphNode(adj.label);\n                    map.put(adjClone.label, adjClone);\n                }\n                clone.neighbors.add(adjClone);\n                dfs(adj, adjClone, map, visited);\n            } else {\n                clone.neighbors.add(clone);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/ConvertOneWordToAnother.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.Map;\nimport java.util.Queue;\nimport java.util.Set;\n\n/**\n * 150s qs 18.10\n * Given two words of equal length in dictionary convert one word to another one letter at a time\n * in such a way that all intermediate words are int the dictionary\n */\npublic class ConvertOneWordToAnother {\n\n    public void convert(String word1, String word2, Set<String> dict) {\n\n        Set<String> visited = new HashSet<String>();\n        Queue<String> queue = new LinkedList<String>();\n        Map<String, String> parentMap = new HashMap<String, String>();\n        queue.add(word1);\n        visited.add(word1);\n        while (queue.size() != 0) {\n            String word = queue.poll();\n            if (word.equals(word2)) {\n                break;\n            }\n            for (int i = 0; i < word.length(); i++) {\n                for (int ch = 'a'; ch <= 'z'; ch++) {\n                    String newWord = replace(word, i, (char) ch);\n                    if (dict.contains(newWord)){\n                        if (!visited.contains(newWord)) {\n                            parentMap.put(newWord, word);\n                            queue.add(newWord);\n                            visited.add(newWord);\n                        }\n                    }\n                }\n            }\n        }\n        String word = word2;\n        while(word != null){\n            System.out.println(word);\n            word = parentMap.get(word);\n        }\n\n    }\n\n    public String replace(String newWord, int pos, char ch) {\n        StringBuffer buffer = new StringBuffer();\n        buffer.append(newWord.substring(0, pos));\n        buffer.append(ch);\n        buffer.append(newWord.substring(pos+1,newWord.length()));\n        return buffer.toString();\n    }\n\n    \n    public static void main(String args[]){\n        Set<String> dictionary = new HashSet<String>();\n        dictionary.add(\"cat\");\n        dictionary.add(\"pat\");\n        dictionary.add(\"pit\");\n        dictionary.add(\"pid\");\n        dictionary.add(\"did\");\n        ConvertOneWordToAnother cow = new ConvertOneWordToAnother();\n        cow.convert(\"cat\", \"did\", dictionary);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/CourseSchedule.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.Deque;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Date 03/01/2016\n * @author Tushar Roy\n *\n * There are a total of n courses you have to take, labeled from 0 to n - 1.\n * 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]\n * Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.\n * There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.\n *\n * Time complexity O(n)\n * Space complexity O(n)\n *\n * https://leetcode.com/problems/course-schedule-ii/\n */\npublic class CourseSchedule {\n    public int[] findOrder(int numCourses, int[][] prerequisites) {\n        boolean[] used = new boolean[numCourses];\n        Neighbors[] graph = new Neighbors[numCourses];\n\n        for (int i = 0; i < graph.length; i++) {\n            graph[i] = new Neighbors();\n        }\n\n        for (int[] tuple : prerequisites) {\n            graph[tuple[1]].neighbor.add(tuple[0]);\n        }\n        Deque<Integer> stack = new LinkedList<>();\n        boolean[] dfs = new boolean[numCourses];\n\n        for (int i = 0; i < numCourses; i++) {\n            if (topSort(i, graph, used, stack, dfs)) {\n                return new int[0];\n            }\n        }\n\n        int[] output = new int[numCourses];\n        int index = 0;\n        while (!stack.isEmpty()) {\n            output[index++] = stack.pollFirst();\n        }\n\n        return output;\n    }\n\n    class Neighbors {\n        List<Integer> neighbor = new ArrayList<>();\n    }\n\n    private boolean topSort(int course, Neighbors[] graph, boolean[] used, Deque<Integer> stack, boolean[] dfs) {\n        if (used[course]) {\n            return false;\n        }\n        if (dfs[course]) {\n            return true;\n        }\n        dfs[course] = true;\n        for (int adj : graph[course].neighbor) {\n            if (topSort(adj, graph, used, stack, dfs)) {\n                return true;\n            }\n        }\n        dfs[course] = false;\n        used[course] = true;\n        stack.offerFirst(course);\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/CycleInDirectedGraph.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * http://www.geeksforgeeks.org/detect-cycle-in-a-graph/\n */\npublic class CycleInDirectedGraph {\n\n    public boolean hasCycle(Graph<Integer> graph) {\n        Set<Vertex<Integer>> whiteSet = new HashSet<>();\n        Set<Vertex<Integer>> graySet = new HashSet<>();\n        Set<Vertex<Integer>> blackSet = new HashSet<>();\n\n        for (Vertex<Integer> vertex : graph.getAllVertex()) {\n            whiteSet.add(vertex);\n        }\n\n        while (whiteSet.size() > 0) {\n            Vertex<Integer> current = whiteSet.iterator().next();\n            if(dfs(current, whiteSet, graySet, blackSet)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private boolean dfs(Vertex<Integer> current, Set<Vertex<Integer>> whiteSet,\n                        Set<Vertex<Integer>> graySet, Set<Vertex<Integer>> blackSet ) {\n        //move current to gray set from white set and then explore it.\n        moveVertex(current, whiteSet, graySet);\n        for(Vertex<Integer> neighbor : current.getAdjacentVertexes()) {\n            //if in black set means already explored so continue.\n            if (blackSet.contains(neighbor)) {\n                continue;\n            }\n            //if in gray set then cycle found.\n            if (graySet.contains(neighbor)) {\n                return true;\n            }\n            if(dfs(neighbor, whiteSet, graySet, blackSet)) {\n                return true;\n            }\n        }\n        //move vertex from gray set to black set when done exploring.\n        moveVertex(current, graySet, blackSet);\n        return false;\n    }\n\n    private void moveVertex(Vertex<Integer> vertex, Set<Vertex<Integer>> sourceSet,\n                            Set<Vertex<Integer>> destinationSet) {\n        sourceSet.remove(vertex);\n        destinationSet.add(vertex);\n    }\n\n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<>(true);\n        graph.addEdge(1, 2);\n        graph.addEdge(1, 3);\n        graph.addEdge(2, 3);\n        graph.addEdge(4, 1);\n        graph.addEdge(4, 5);\n        graph.addEdge(5, 6);\n        graph.addEdge(6, 4);\n        CycleInDirectedGraph cdg = new CycleInDirectedGraph();\n        System.out.println(cdg.hasCycle(graph));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/CycleUndirectedGraph.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Date 10/11/2014\n * @author Tushar Roy\n *\n * Given an undirected graph find cycle in this graph.\n *\n * Solution\n * This can be solved in many ways.\n * Below is the code to solve it using disjoint sets and DFS.\n *\n * Runtime and space complexity for both the techniques is O(v)\n * where v is total number of vertices in the graph.\n */\npublic class CycleUndirectedGraph<T> {\n\n    public boolean hasCycleUsingDisjointSets(Graph<T> graph){\n        DisjointSet disjointSet = new DisjointSet();\n        \n        for(Vertex<T> vertex : graph.getAllVertex()){\n            disjointSet.makeSet(vertex.getId());\n        }\n        \n        for(Edge<T> edge : graph.getAllEdges()){\n            long parent1 = disjointSet.findSet(edge.getVertex1().getId());\n            long parent2 = disjointSet.findSet(edge.getVertex2().getId());\n            if(parent1 == parent2){\n                return true;\n            }\n            disjointSet.union(edge.getVertex1().getId(), edge.getVertex2().getId());\n        }\n        return false;\n    }\n    \n    public boolean hasCycleDFS(Graph<T> graph){\n        Set<Vertex<T>> visited = new HashSet<Vertex<T>>();\n        for(Vertex<T> vertex : graph.getAllVertex()){\n            if(visited.contains(vertex)){\n                continue;\n            }\n            boolean flag = hasCycleDFSUtil(vertex, visited, null);\n            if(flag){\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    public boolean hasCycleDFSUtil(Vertex<T> vertex, Set<Vertex<T>> visited,Vertex<T> parent){\n        visited.add(vertex);\n        for(Vertex<T> adj : vertex.getAdjacentVertexes()){\n            if(adj.equals(parent)){\n                continue;\n            }\n            if(visited.contains(adj)){\n                return true;\n            }\n            boolean hasCycle = hasCycleDFSUtil(adj,visited,vertex);\n            if(hasCycle){\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        \n        CycleUndirectedGraph<Integer> cycle = new CycleUndirectedGraph<Integer>();\n        Graph<Integer> graph = new Graph<Integer>(false);\n        \n        graph.addEdge(0, 1);\n        graph.addEdge(1, 2);\n        graph.addEdge(0, 3);\n        graph.addEdge(3, 4);\n        graph.addEdge(4, 5);\n        graph.addEdge(5, 1);\n        boolean isCycle = cycle.hasCycleDFS(graph);\n        System.out.println(isCycle);\n        isCycle = cycle.hasCycleUsingDisjointSets(graph);\n        System.out.print(isCycle);\n        \n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/graph/DAGShortestPathTopological.java",
    "content": "package com.interview.graph;\n\nimport java.util.Deque;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\nhttp://www.geeksforgeeks.org/shortest-path-for-directed-acyclic-graphs/\n */\npublic class DAGShortestPathTopological<T> {\n\n    public Map<Vertex<T>,Integer> shortestPath(Graph<T> graph,Vertex<T> startVertex){\n        \n        Map<Vertex<T>,Integer> distance = new HashMap<Vertex<T>,Integer>();\n        TopologicalSort<T> sort = new TopologicalSort<T>();\n        Deque<Vertex<T>> deque = sort.topSort(graph);\n        distance.put(startVertex, 0);\n        while(!deque.isEmpty()){\n            Vertex<T> vertex = deque.poll();\n            for(Edge<T> edge : vertex.getEdges()){\n                if(getDistance(edge.getVertex2(),distance) > getDistance(edge.getVertex1(),distance) + edge.getWeight()){\n                    distance.put(edge.getVertex2(), getDistance(edge.getVertex1(),distance) + edge.getWeight());\n                }\n            }\n        }\n        \n        return distance;\n    }\n    \n    private int getDistance( Vertex<T> vertex,Map<Vertex<T>,Integer> distance){\n        return distance.containsKey(vertex) ? distance.get(vertex) : 1000;\n    }\n    \n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<Integer>(true);\n        graph.addEdge(1, 2,4);\n        graph.addEdge(2, 3,3);\n        graph.addEdge(2, 4,2);\n        graph.addEdge(1, 3,2);\n        graph.addEdge(3, 5,1);\n        graph.addEdge(4, 5,5);\n        graph.addEdge(5, 6,2);\n        graph.addEdge(4, 7,3);\n\n        DAGShortestPathTopological<Integer> shortestPath = new DAGShortestPathTopological<Integer>();\n        Map<Vertex<Integer>,Integer> distance = shortestPath.shortestPath(graph, graph.getAllVertex().iterator().next());\n        System.out.print(distance);\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/DijkstraShortestPath.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 10/11/2014\n * @author Tushar Roy\n *\n * Find single source shortest path using Dijkstra's algorithm\n *\n * Space complexity - O(E + V)\n * Time complexity - O(ElogV)\n *\n * References\n * https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm\n * CLRS book*/\npublic class DijkstraShortestPath {\n\n    public Map<Vertex<Integer>,Integer> shortestPath(Graph<Integer> graph, Vertex<Integer> sourceVertex){\n\n        //heap + map data structure\n        BinaryMinHeap<Vertex<Integer>> minHeap = new BinaryMinHeap<>();\n\n        //stores shortest distance from root to every vertex\n        Map<Vertex<Integer>,Integer> distance = new HashMap<>();\n\n        //stores parent of every vertex in shortest distance\n        Map<Vertex<Integer>, Vertex<Integer>> parent = new HashMap<>();\n\n        //initialize all vertex with infinite distance from source vertex\n        for(Vertex<Integer> vertex : graph.getAllVertex()){\n            minHeap.add(Integer.MAX_VALUE, vertex);\n        }\n\n        //set distance of source vertex to 0\n        minHeap.decrease(sourceVertex, 0);\n\n        //put it in map\n        distance.put(sourceVertex, 0);\n\n        //source vertex parent is null\n        parent.put(sourceVertex, null);\n\n        //iterate till heap is not empty\n        while(!minHeap.empty()){\n            //get the min value from heap node which has vertex and distance of that vertex from source vertex.\n            BinaryMinHeap<Vertex<Integer>>.Node heapNode = minHeap.extractMinNode();\n            Vertex<Integer> current = heapNode.key;\n\n            //update shortest distance of current vertex from source vertex\n            distance.put(current, heapNode.weight);\n\n            //iterate through all edges of current vertex\n            for(Edge<Integer> edge : current.getEdges()){\n\n                //get the adjacent vertex\n                Vertex<Integer> adjacent = getVertexForEdge(current, edge);\n\n                //if heap does not contain adjacent vertex means adjacent vertex already has shortest distance from source vertex\n                if(!minHeap.containsData(adjacent)){\n                    continue;\n                }\n\n                //add distance of current vertex to edge weight to get distance of adjacent vertex from source vertex\n                //when it goes through current vertex\n                int newDistance = distance.get(current) + edge.getWeight();\n\n                //see if this above calculated distance is less than current distance stored for adjacent vertex from source vertex\n                if(minHeap.getWeight(adjacent) > newDistance) {\n                    minHeap.decrease(adjacent, newDistance);\n                    parent.put(adjacent, current);\n                }\n            }\n        }\n        return distance;\n    }\n\n    private Vertex<Integer> getVertexForEdge(Vertex<Integer> v, Edge<Integer> e){\n        return e.getVertex1().equals(v) ? e.getVertex2() : e.getVertex1();\n    }\n    \n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<>(false);\n        /*graph.addEdge(0, 1, 4);\n        graph.addEdge(1, 2, 8);\n        graph.addEdge(2, 3, 7);\n        graph.addEdge(3, 4, 9);\n        graph.addEdge(4, 5, 10);\n        graph.addEdge(2, 5, 4);\n        graph.addEdge(1, 7, 11);\n        graph.addEdge(0, 7, 8);\n        graph.addEdge(2, 8, 2);\n        graph.addEdge(3, 5, 14);\n        graph.addEdge(5, 6, 2);\n        graph.addEdge(6, 8, 6);\n        graph.addEdge(6, 7, 1);\n        graph.addEdge(7, 8, 7);*/\n\n        graph.addEdge(1, 2, 5);\n        graph.addEdge(2, 3, 2);\n        graph.addEdge(1, 4, 9);\n        graph.addEdge(1, 5, 3);\n        graph.addEdge(5, 6, 2);\n        graph.addEdge(6, 4, 2);\n        graph.addEdge(3, 4, 3);\n\n        DijkstraShortestPath dsp = new DijkstraShortestPath();\n        Vertex<Integer> sourceVertex = graph.getVertex(1);\n        Map<Vertex<Integer>,Integer> distance = dsp.shortestPath(graph, sourceVertex);\n        System.out.print(distance);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/DirectedGraphConnectivity.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayDeque;\nimport java.util.Deque;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class DirectedGraphConnectivity {\n\n    public boolean scc(Graph<Integer> graph) {\n        Deque<Vertex<Integer>> stack = new ArrayDeque<Vertex<Integer>>();\n        Map<Vertex<Integer>, Boolean> visited = new HashMap<Vertex<Integer>, Boolean>();\n        for (Vertex<Integer> vertex : graph.getAllVertex()) {\n            if (visited.containsKey(vertex)) {\n                continue;\n            }\n            DFSUtil(vertex, visited, stack);\n        }\n\n        System.out.println(stack);\n        \n        Graph<Integer> reverseGraph = new Graph<Integer>(true);\n        Map<Long, Vertex<Integer>> vertexMap = new HashMap<Long, Vertex<Integer>>();\n        for (Edge<Integer> edge : graph.getAllEdges()) {\n            reverseGraph.addEdge(edge.getVertex2().getId(), edge.getVertex1()\n                    .getId(), edge.getWeight());\n        }\n        \n        for (Vertex<Integer> vertex : reverseGraph.getAllVertex()) {\n            vertexMap.put(vertex.getId(), vertex);\n        }\n        \n        visited.clear();\n        Vertex<Integer> vertex = vertexMap.get(stack.poll().getId());\n        DFSUtil1(vertex, visited);\n        \n        for(Vertex<Integer> testVertex : reverseGraph.getAllVertex()){\n            if(!visited.containsKey(testVertex)){\n                return false;\n            }\n        }\n        return true;\n    }\n\n    private void DFSUtil(Vertex<Integer> vertex,\n            Map<Vertex<Integer>, Boolean> visited, Deque<Vertex<Integer>> stack) {\n        visited.put(vertex, true);\n        for (Vertex<Integer> v : vertex.getAdjacentVertexes()) {\n            if (visited.containsKey(v)) {\n                continue;\n            }\n            DFSUtil(v, visited, stack);\n        }\n        stack.offerFirst(vertex);\n    }\n\n    private void DFSUtil1(Vertex<Integer> vertex,\n            Map<Vertex<Integer>, Boolean> visited) {\n        visited.put(vertex, true);\n        for (Vertex<Integer> v : vertex.getAdjacentVertexes()) {\n            if (visited.containsKey(v)) {\n                continue;\n            }\n            DFSUtil1(v, visited);\n        }\n    }\n\n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<Integer>(true);\n        graph.addEdge(1, 0);\n        graph.addEdge(2,1);\n        graph.addEdge(0,2);\n        graph.addEdge(0, 3);\n        graph.addEdge(3, 4);\n        graph.addEdge(4, 2);\n        \n        DirectedGraphConnectivity scc = new DirectedGraphConnectivity();\n        boolean result = scc.scc(graph);\n        System.out.println(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/DisjointSet.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * @author tusroy\n * Date 06/20/2015\n *  \n * Video link - https://youtu.be/ID00PMy0-vE\n *  \n * Disjoint sets using path compression and union by rank\n * Supports 3 operations\n * 1) makeSet\n * 2) union\n * 3) findSet\n * \n * For m operations and total n elements time complexity is O(m*f(n)) where f(n) is \n * very slowly growing function. For most cases f(n) <= 4 so effectively\n * total time will be O(m). Proof in Coreman book.\n */\npublic class DisjointSet {\n\n    private Map<Long, Node> map = new HashMap<>();\n\n    class Node {\n        long data;\n        Node parent;\n        int rank;\n    }\n\n    /**\n     * Create a set with only one element.\n     */\n    public void makeSet(long data) {\n        Node node = new Node();\n        node.data = data;\n        node.parent = node;\n        node.rank = 0;\n        map.put(data, node);\n    }\n\n    /**\n     * Combines two sets together to one.\n     * Does union by rank\n     *\n     * @return true if data1 and data2 are in different set before union else false.\n     */\n    public boolean union(long data1, long data2) {\n        Node node1 = map.get(data1);\n        Node node2 = map.get(data2);\n\n        Node parent1 = findSet(node1);\n        Node parent2 = findSet(node2);\n\n        //if they are part of same set do nothing\n        if (parent1.data == parent2.data) {\n            return false;\n        }\n\n        //else whoever's rank is higher becomes parent of other\n        if (parent1.rank >= parent2.rank) {\n            //increment rank only if both sets have same rank\n            parent1.rank = (parent1.rank == parent2.rank) ? parent1.rank + 1 : parent1.rank;\n            parent2.parent = parent1;\n        } else {\n            parent1.parent = parent2;\n        }\n        return true;\n    }\n\n    /**\n     * Finds the representative of this set\n     */\n    public long findSet(long data) {\n        return findSet(map.get(data)).data;\n    }\n\n    /**\n     * Find the representative recursively and does path\n     * compression as well.\n     */\n    private Node findSet(Node node) {\n        Node parent = node.parent;\n        if (parent == node) {\n            return parent;\n        }\n        node.parent = findSet(node.parent);\n        return node.parent;\n    }\n\n    public static void main(String args[]) {\n        DisjointSet ds = new DisjointSet();\n        ds.makeSet(1);\n        ds.makeSet(2);\n        ds.makeSet(3);\n        ds.makeSet(4);\n        ds.makeSet(5);\n        ds.makeSet(6);\n        ds.makeSet(7);\n\n        ds.union(1, 2);\n        ds.union(2, 3);\n        ds.union(4, 5);\n        ds.union(6, 7);\n        ds.union(5, 6);\n        ds.union(3, 7);\n\n        System.out.println(ds.findSet(1));\n        System.out.println(ds.findSet(2));\n        System.out.println(ds.findSet(3));\n        System.out.println(ds.findSet(4));\n        System.out.println(ds.findSet(5));\n        System.out.println(ds.findSet(6));\n        System.out.println(ds.findSet(7));\n    }\n}"
  },
  {
    "path": "src/com/interview/graph/EulerianPathAndCircuit.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class EulerianPathAndCircuit<T> {\n\n    public enum Eulerian{\n        NOT_EULERIAN,\n        EULERIAN,\n        SEMIEULERIAN\n    }\n    \n    private boolean isConnected(Graph<T> graph){\n        \n        Vertex<T> startVertex = null;\n        \n        for(Vertex<T> vertex : graph.getAllVertex()){\n            if(vertex.getDegree() != 0){\n                startVertex = vertex;\n                break;\n            }\n        }\n        \n        if(startVertex == null){\n            return true;\n        }\n        \n        Map<Vertex<T>,Boolean> visited = new HashMap<Vertex<T>, Boolean>();\n        DFS(startVertex,visited);\n        \n        for(Vertex<T> testVertex : graph.getAllVertex()){\n            if(testVertex.getDegree()!= 0 && !visited.containsKey(testVertex)){\n                return false;\n            }\n        }\n        return true;\n        \n    }\n    \n    private void DFS(Vertex<T> startVertex, Map<Vertex<T>, Boolean> visited){\n        visited.put(startVertex, true);\n        for(Vertex<T> child : startVertex.getAdjacentVertexes()){\n            if(!visited.containsKey(child)){\n                DFS(child,visited);\n            }\n        }\n    }\n    \n    public Eulerian isEulerian(Graph<T> graph){\n        \n        if(!isConnected(graph)){\n            return Eulerian.NOT_EULERIAN;\n        }\n\n        int odd = 0;\n        for(Vertex<T> vertex : graph.getAllVertex()){\n            if(vertex.getDegree()!=0 && vertex.getDegree() % 2 != 0){\n                odd++;\n            }\n        }\n        \n        if(odd > 2){\n            return Eulerian.NOT_EULERIAN;\n        }\n        \n        return odd == 0 ? Eulerian.EULERIAN : Eulerian.SEMIEULERIAN; \n    }\n    \n    \n    public static void main(String args[]){\n        \n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addSingleVertex(1);\n        graph.addSingleVertex(2);\n        graph.addSingleVertex(3);\n        graph.addEdge(4, 5);\n        graph.addEdge(6, 4);\n        graph.addEdge(5,6);\n        \n        EulerianPathAndCircuit<Integer> eulerian = new EulerianPathAndCircuit<Integer>();\n        Eulerian result = eulerian.isEulerian(graph);\n        System.out.print(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/EvaluateDivison.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 10/31/2016\n * @author Tushar Roy\n *\n * Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number).\n * Given some queries, return the answers. If the answer does not exist, return -1.0.\n *\n * Solution\n * Do Flyod warshall algorithm initialized as values between equations. Do Flyod Warshall to create\n * all possible paths b/w two strings.\n *\n * Time complexity O(n * n * n) + O(m)\n * where n is total number of strings in equations and m is total number of queries\n *\n * Reference\n * https://leetcode.com/problems/evaluate-division/\n */\npublic class EvaluateDivison {\n    public double[] calcEquation(String[][] equations, double[] values, String[][] queries) {\n        if (equations.length == 0) {\n            return new double[0];\n        }\n        Map<String, Integer> index = new HashMap<>();\n        int count = 0;\n        for (int i = 0; i < equations.length; i++) {\n            String first = equations[i][0];\n            String second = equations[i][1];\n            if (!index.containsKey(first)) {\n                index.put(first, count++);\n            }\n            if (!index.containsKey(second)) {\n                index.put(second, count++);\n            }\n        }\n\n        double graph[][] = new double[count][count];\n        for (int i = 0; i < graph.length; i++) {\n            for (int j = 0; j < graph[i].length; j++) {\n                graph[i][j] = -1;\n            }\n        }\n\n        for (int i = 0; i < equations.length; i++) {\n            String first = equations[i][0];\n            String second = equations[i][1];\n            int i1 = index.get(first);\n            int i2 = index.get(second);\n            graph[i1][i1] = graph[i2][i2] = 1.0;\n            graph[i1][i2] = values[i];\n            graph[i2][i1] = 1/values[i];\n        }\n\n        for (int i = 0 ; i < graph.length; i++) {\n            for (int j = 0; j < graph.length; j++) {\n                if (graph[i][j] != -1) {\n                    continue;\n                }\n                for (int k = 0; k < graph.length; k++) {\n                    if (graph[i][k] == -1 || graph[k][j] == -1) {\n                        continue;\n                    }\n                    graph[i][j] = graph[i][k] * graph[k][j];\n                }\n            }\n        }\n\n        double[] result = new double[queries.length];\n        for (int i = 0; i < queries.length; i++) {\n            String first = queries[i][0];\n            String second = queries[i][1];\n            if (!index.containsKey(first) || !index.containsKey(second)) {\n                result[i] = -1;\n            } else {\n                int i1 = index.get(first);\n                int i2 = index.get(second);\n                result[i] = graph[i1][i2];\n            }\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/FillOsWIthXsIfSurroundedByXs.java",
    "content": "package com.interview.graph;\n\n/**\n * Date 04/17/2016\n * @author Tushar Roy\n *\n * Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.\n * A region is captured by flipping all 'O's into 'X's in that surrounded region.\n *\n * Reference\n * https://leetcode.com/problems/surrounded-regions/\n */\npublic class FillOsWIthXsIfSurroundedByXs {\n\n    public void solve(char[][] board) {\n        if (board.length == 0 || board[0].length == 0) {\n            return;\n        }\n        for (int i = 0; i < board.length; i++) {\n            dfs(board, i, 0);\n            dfs(board, i, board[0].length - 1);\n        }\n\n        for (int i = 0; i < board[0].length; i++) {\n            dfs(board, 0, i);\n            dfs(board, board.length - 1, i);\n        }\n\n        for (int i = 0; i < board.length; i++) {\n            for (int j = 0; j < board[0].length; j++) {\n                if (board[i][j] == 'O') {\n                    board[i][j] = 'X';\n                }\n                else if (board[i][j] == '1') {\n                    board[i][j] = 'O';\n                }\n            }\n        }\n    }\n\n    private void dfs(char[][] board, int i, int j) {\n        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) {\n            return;\n        }\n\n        if (board[i][j] != 'O') {\n            return;\n        }\n\n        board[i][j] = '1';\n        if (i < board.length - 2) {\n            dfs(board, i + 1, j);\n        }\n        if (i > 1) {\n            dfs(board, i - 1, j);\n        }\n        if (j < board[0].length - 2) {\n            dfs(board, i, j + 1);\n        }\n        if (j > 1) {\n            dfs(board, i, j - 1);\n        }\n    }\n    \n    public static void main(String args[]){\n        FillOsWIthXsIfSurroundedByXs fo = new FillOsWIthXsIfSurroundedByXs();\n        char board[][] = {{'X','X','X','X'},\n                          {'X','X','O','X'},\n                          {'X','O','X','X'},\n                          {'X','X','O','X'}};\n        \n        fo.solve(board);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/FloodFillAlgorithm.java",
    "content": "package com.interview.graph;\n\n/**\n * http://en.wikipedia.org/wiki/Flood_fill\n * \n */\npublic class FloodFillAlgorithm {\n\n    public void fillDFS(int screen[][], int oldColor, int newColor,int startx,int starty){\n        fillUtil(screen,startx,starty,oldColor,newColor);\n    }\n    \n    public void fillUtil(int screen[][], int currentx,int currenty, int oldColor, int newColor){\n        if(currentx < 0 || currentx >= screen.length || currenty < 0 || currenty >= screen[currentx].length){\n            return;\n        }\n        \n        if(screen[currentx][currenty] != oldColor){\n            return;\n        }\n        screen[currentx][currenty] = newColor;\n        fillUtil(screen,currentx+1,currenty,oldColor,newColor);\n        fillUtil(screen,currentx-1,currenty,oldColor,newColor);\n        fillUtil(screen,currentx,currenty+1,oldColor,newColor);\n        fillUtil(screen,currentx,currenty-1,oldColor,newColor);\n    }\n    \n    public static void main(String args[]){\n        int screen[][] = {{1,1,1,1,1,1},\n                    {1,1,1,1,1,1},\n                    {1,0,0,1,1,0},\n                    {1,1,1,0,0,0},\n                    {1,1,1,0,1,0},\n                    {1,1,1,1,1,1}};\n        FloodFillAlgorithm ff = new FloodFillAlgorithm();\n        ff.fillDFS(screen, 0, 2, 3, 3);\n        \n        for(int i=0; i < screen.length; i++){\n            for(int j=0; j < screen[i].length; j++){\n                System.out.print(screen[i][j] + \" \");\n            }\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/FloydWarshallAllPairShortestPath.java",
    "content": "package com.interview.graph;\n\nimport java.util.Deque;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.Map;\n\n/**\n * Date 11/02/2015\n * @author Tushar Roy\n *\n * Floyd-Warshall Algorithm for finding all pair shortest path.\n *\n * Time complexity - O(V^3)\n * Space complexity - O(V^2)\n *\n * References\n * https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm\n */\npublic class FloydWarshallAllPairShortestPath {\n\n    class NegativeWeightCycleException extends RuntimeException {\n\n    }\n\n    private static final int INF = 1000000;\n\n    public int[][] allPairShortestPath(int[][] distanceMatrix) {\n        \n        int distance[][] = new int[distanceMatrix.length][distanceMatrix.length];\n        int path[][] = new int[distanceMatrix.length][distanceMatrix.length];\n\n        for (int i=0; i < distanceMatrix.length; i++) {\n            for (int j=0; j< distanceMatrix[i].length; j++){\n                distance[i][j] = distanceMatrix[i][j];\n                if (distanceMatrix[i][j] != INF && i != j) {\n                    path[i][j] = i;\n                } else {\n                    path[i][j] = -1;\n                }\n            }\n        }\n\n        for(int k=0; k < distanceMatrix.length; k++){\n            for(int i=0; i < distanceMatrix.length; i++){\n                for(int j=0; j < distanceMatrix.length; j++){\n                    if(distance[i][k] == INF || distance[k][j] == INF) {\n                        continue;\n                    }\n                    if(distance[i][j] > distance[i][k] + distance[k][j]){\n                        distance[i][j] = distance[i][k] + distance[k][j];\n                        path[i][j] = path[k][j];\n                    }\n                }\n            }\n        }\n\n        //look for negative weight cycle in the graph\n        //if values on diagonal of distance matrix is negative\n        //then there is negative weight cycle in the graph.\n        for(int i = 0; i < distance.length; i++) {\n            if(distance[i][i] < 0) {\n                throw new NegativeWeightCycleException();\n            }\n        }\n\n        printPath(path, 3, 2);\n        return distance;\n    }\n\n    public void printPath(int[][] path, int start, int end) {\n        if(start < 0 || end < 0 || start >= path.length || end >= path.length) {\n            throw new IllegalArgumentException();\n        }\n\n        System.out.println(\"Actual path - between \" + start + \" \" + end);\n        Deque<Integer> stack = new LinkedList<>();\n        stack.addFirst(end);\n        while (true) {\n            end = path[start][end];\n            if(end == -1) {\n                return;\n            }\n            stack.addFirst(end);\n            if(end == start) {\n                break;\n            }\n        }\n\n        while (!stack.isEmpty()) {\n            System.out.print(stack.pollFirst() + \" \");\n        }\n\n        System.out.println();\n    }\n\n    public static void main(String args[]){\n        int[][] graph = {\n                {0,   3,   6,   15},\n                {INF, 0,  -2,   INF},\n                {INF, INF, 0,   2},\n                {1,   INF, INF, 0}\n        };\n\n        FloydWarshallAllPairShortestPath shortestPath = new FloydWarshallAllPairShortestPath();\n        int[][] distance = shortestPath.allPairShortestPath(graph);\n        System.out.println(\"Minimum Distance matrix\");\n        for(int i=0; i < distance.length; i++){\n            for(int j=0; j < distance.length; j++){\n                System.out.print(distance[i][j] + \" \");\n            }\n            System.out.println(\"\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/FordFulkerson.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Date 04/14/2014\n * @author Tushar Roy\n *\n * Ford fulkerson method Edmonds Karp algorithm for finding max flow\n *\n * Capacity - Capacity of an edge to carry units from source to destination vertex\n * Flow - Actual flow of units from source to destination vertex of an edge\n * Residual capacity - Remaining capacity on this edge i.e capacity - flow\n * AugmentedPath - Path from source to sink which has residual capacity greater than 0\n *\n * Time complexity is O(VE^2)\n *\n * References:\n * http://www.geeksforgeeks.org/ford-fulkerson-algorithm-for-maximum-flow-problem/\n * https://en.wikipedia.org/wiki/Edmonds%E2%80%93Karp_algorithm\n */\npublic class FordFulkerson {\n\n    public int maxFlow(int capacity[][], int source, int sink){\n\n        //declare and initialize residual capacity as total avaiable capacity initially.\n        int residualCapacity[][] = new int[capacity.length][capacity[0].length];\n        for (int i = 0; i < capacity.length; i++) {\n            for (int j = 0; j < capacity[0].length; j++) {\n                residualCapacity[i][j] = capacity[i][j];\n            }\n        }\n\n        //this is parent map for storing BFS parent\n        Map<Integer,Integer> parent = new HashMap<>();\n\n        //stores all the augmented paths\n        List<List<Integer>> augmentedPaths = new ArrayList<>();\n\n        //max flow we can get in this network\n        int maxFlow = 0;\n\n        //see if augmented path can be found from source to sink.\n        while(BFS(residualCapacity, parent, source, sink)){\n            List<Integer> augmentedPath = new ArrayList<>();\n            int flow = Integer.MAX_VALUE;\n            //find minimum residual capacity in augmented path\n            //also add vertices to augmented path list\n            int v = sink;\n            while(v != source){\n                augmentedPath.add(v);\n                int u = parent.get(v);\n                if (flow > residualCapacity[u][v]) {\n                    flow = residualCapacity[u][v];\n                }\n                v = u;\n            }\n            augmentedPath.add(source);\n            Collections.reverse(augmentedPath);\n            augmentedPaths.add(augmentedPath);\n\n            //add min capacity to max flow\n            maxFlow += flow;\n\n            //decrease residual capacity by min capacity from u to v in augmented path\n            // and increase residual capacity by min capacity from v to u\n            v = sink;\n            while(v != source){\n                int u = parent.get(v);\n                residualCapacity[u][v] -= flow;\n                residualCapacity[v][u] += flow;\n                v = u;\n            }\n        }\n        printAugmentedPaths(augmentedPaths);\n        return maxFlow;\n    }\n\n    /**\n     * Prints all the augmented path which contribute to max flow\n     */\n    private void printAugmentedPaths(List<List<Integer>> augmentedPaths) {\n        System.out.println(\"Augmented paths\");\n        augmentedPaths.forEach(path -> {\n            path.forEach(i -> System.out.print(i + \" \"));\n            System.out.println();\n        });\n    }\n\n    /**\n     * Breadth first search to find augmented path\n     */\n    private boolean BFS(int[][] residualCapacity, Map<Integer,Integer> parent,\n            int source, int sink){\n        Set<Integer> visited = new HashSet<>();\n        Queue<Integer> queue = new LinkedList<>();\n        queue.add(source);\n        visited.add(source);\n        boolean foundAugmentedPath = false;\n        //see if we can find augmented path from source to sink\n        while(!queue.isEmpty()){\n            int u = queue.poll();\n            for(int v = 0; v < residualCapacity.length; v++){\n                //explore the vertex only if it is not visited and its residual capacity is\n                //greater than 0\n                if(!visited.contains(v) &&  residualCapacity[u][v] > 0){\n                    //add in parent map saying v got explored by u\n                    parent.put(v, u);\n                    //add v to visited\n                    visited.add(v);\n                    //add v to queue for BFS\n                    queue.add(v);\n                    //if sink is found then augmented path is found\n                    if ( v == sink) {\n                        foundAugmentedPath = true;\n                        break;\n                    }\n                }\n            }\n        }\n        //returns if augmented path is found from source to sink or not\n        return foundAugmentedPath;\n    }\n    \n    public static void main(String args[]){\n        FordFulkerson ff = new FordFulkerson();\n        int[][] capacity = {{0, 3, 0, 3, 0, 0, 0},\n                            {0, 0, 4, 0, 0, 0, 0},\n                            {3, 0, 0, 1, 2, 0, 0},\n                            {0, 0, 0, 0, 2, 6, 0},\n                            {0, 1, 0, 0, 0, 0, 1},\n                            {0, 0, 0, 0, 0, 0, 9},\n                            {0, 0, 0, 0, 0, 0, 0}};\n\n        System.out.println(\"\\nMaximum capacity \" + ff.maxFlow(capacity, 0, 6));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/Graph.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Graph<T>{\n\n    private List<Edge<T>> allEdges;\n    private Map<Long,Vertex<T>> allVertex;\n    boolean isDirected = false;\n    \n    public Graph(boolean isDirected){\n        allEdges = new ArrayList<Edge<T>>();\n        allVertex = new HashMap<Long,Vertex<T>>();\n        this.isDirected = isDirected;\n    }\n    \n    public void addEdge(long id1, long id2){\n        addEdge(id1,id2,0);\n    }\n    \n    //This works only for directed graph because for undirected graph we can end up\n    //adding edges two times to allEdges\n    public void addVertex(Vertex<T> vertex){\n        if(allVertex.containsKey(vertex.getId())){\n            return;\n        }\n        allVertex.put(vertex.getId(), vertex);\n        for(Edge<T> edge : vertex.getEdges()){\n            allEdges.add(edge);\n        }\n    }\n    \n    public Vertex<T> addSingleVertex(long id){\n        if(allVertex.containsKey(id)){\n            return allVertex.get(id);\n        }\n        Vertex<T> v = new Vertex<T>(id);\n        allVertex.put(id, v);\n        return v;\n    }\n    \n    public Vertex<T> getVertex(long id){\n        return allVertex.get(id);\n    }\n    \n    public void addEdge(long id1,long id2, int weight){\n        Vertex<T> vertex1 = null;\n        if(allVertex.containsKey(id1)){\n            vertex1 = allVertex.get(id1);\n        }else{\n            vertex1 = new Vertex<T>(id1);\n            allVertex.put(id1, vertex1);\n        }\n        Vertex<T> vertex2 = null;\n        if(allVertex.containsKey(id2)){\n            vertex2 = allVertex.get(id2);\n        }else{\n            vertex2 = new Vertex<T>(id2);\n            allVertex.put(id2, vertex2);\n        }\n\n        Edge<T> edge = new Edge<T>(vertex1,vertex2,isDirected,weight);\n        allEdges.add(edge);\n        vertex1.addAdjacentVertex(edge, vertex2);\n        if(!isDirected){\n            vertex2.addAdjacentVertex(edge, vertex1);\n        }\n\n    }\n    \n    public List<Edge<T>> getAllEdges(){\n        return allEdges;\n    }\n    \n    public Collection<Vertex<T>> getAllVertex(){\n        return allVertex.values();\n    }\n    public void setDataForVertex(long id, T data){\n        if(allVertex.containsKey(id)){\n            Vertex<T> vertex = allVertex.get(id);\n            vertex.setData(data);\n        }\n    }\n\n    @Override\n    public String toString(){\n        StringBuffer buffer = new StringBuffer();\n        for(Edge<T> edge : getAllEdges()){\n            buffer.append(edge.getVertex1() + \" \" + edge.getVertex2() + \" \" + edge.getWeight());\n            buffer.append(\"\\n\");\n        }\n        return buffer.toString();\n    }\n}\n\n\nclass Vertex<T> {\n    long id;\n    private T data;\n    private List<Edge<T>> edges = new ArrayList<>();\n    private List<Vertex<T>> adjacentVertex = new ArrayList<>();\n    \n    Vertex(long id){\n        this.id = id;\n    }\n    \n    public long getId(){\n        return id;\n    }\n    \n    public void setData(T data){\n        this.data = data;\n    }\n    \n    public T getData(){\n        return data;\n    }\n    \n    public void addAdjacentVertex(Edge<T> e, Vertex<T> v){\n        edges.add(e);\n        adjacentVertex.add(v);\n    }\n    \n    public String toString(){\n        return String.valueOf(id);\n    }\n    \n    public List<Vertex<T>> getAdjacentVertexes(){\n        return adjacentVertex;\n    }\n    \n    public List<Edge<T>> getEdges(){\n        return edges;\n    }\n    \n    public int getDegree(){\n        return edges.size();\n    }\n    \n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + (int) (id ^ (id >>> 32));\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        Vertex other = (Vertex) obj;\n        if (id != other.id)\n            return false;\n        return true;\n    }\n}\n\nclass Edge<T>{\n    private boolean isDirected = false;\n    private Vertex<T> vertex1;\n    private Vertex<T> vertex2;\n    private int weight;\n    \n    Edge(Vertex<T> vertex1, Vertex<T> vertex2){\n        this.vertex1 = vertex1;\n        this.vertex2 = vertex2;\n    }\n\n    Edge(Vertex<T> vertex1, Vertex<T> vertex2,boolean isDirected,int weight){\n        this.vertex1 = vertex1;\n        this.vertex2 = vertex2;\n        this.weight = weight;\n        this.isDirected = isDirected;\n    }\n    \n    Edge(Vertex<T> vertex1, Vertex<T> vertex2,boolean isDirected){\n        this.vertex1 = vertex1;\n        this.vertex2 = vertex2;\n        this.isDirected = isDirected;\n    }\n    \n    Vertex<T> getVertex1(){\n        return vertex1;\n    }\n    \n    Vertex<T> getVertex2(){\n        return vertex2;\n    }\n    \n    int getWeight(){\n        return weight;\n    }\n    \n    public boolean isDirected(){\n        return isDirected;\n    }\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + ((vertex1 == null) ? 0 : vertex1.hashCode());\n        result = prime * result + ((vertex2 == null) ? 0 : vertex2.hashCode());\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        Edge other = (Edge) obj;\n        if (vertex1 == null) {\n            if (other.vertex1 != null)\n                return false;\n        } else if (!vertex1.equals(other.vertex1))\n            return false;\n        if (vertex2 == null) {\n            if (other.vertex2 != null)\n                return false;\n        } else if (!vertex2.equals(other.vertex2))\n            return false;\n        return true;\n    }\n\n    @Override\n    public String toString() {\n        return \"Edge [isDirected=\" + isDirected + \", vertex1=\" + vertex1\n                + \", vertex2=\" + vertex2 + \", weight=\" + weight + \"]\";\n    }\n}\n\n "
  },
  {
    "path": "src/com/interview/graph/GraphColoring.java",
    "content": "package com.interview.graph;\n\nimport java.util.Collection;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\n\n/**\n http://www.geeksforgeeks.org/graph-coloring-set-2-greedy-algorithm/\n */\npublic class GraphColoring {\n\n    public void WelshPowell(){\n        \n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addEdge(1, 2);\n        graph.addEdge(2, 3);\n        graph.addEdge(1, 4);\n        graph.addEdge(4, 6);\n        graph.addEdge(1, 7);\n        graph.addEdge(1, 8);\n        graph.addEdge(2, 9);\n        graph.addEdge(1, 3);\n        graph.addEdge(3, 4);\n        graph.addEdge(2,4);\n        graph.addEdge(3, 7);\n        graph.addEdge(2, 7);\n\n        ComparatorVertex c = new ComparatorVertex();\n        Set<Vertex<Integer>> sortedSet = new TreeSet<Vertex<Integer>>(c);\n        for(Vertex<Integer> v : graph.getAllVertex()){\n            sortedSet.add(v);\n        }\n        \n        Map<Long,String> assignedColor = new HashMap<Long,String>();\n        Map<Long,String> finalAssignedColor = new HashMap<Long,String>();\n        \n        Map<String,Boolean> colorsUsed = new TreeMap<String,Boolean>();\n        colorsUsed.put(\"Green\", false);\n        colorsUsed.put(\"Blue\", false);\n        colorsUsed.put(\"Red\", false);\n        colorsUsed.put(\"Yellow\", false);\n        colorsUsed.put(\"Orange\",false);\n\n        Set<Vertex<Integer>> removeSet = new HashSet<Vertex<Integer>>();\n        while(sortedSet.size() != removeSet.size()){\n            String color = null ;\n            \n            for(Vertex<Integer> v : sortedSet){\n                if(removeSet.contains(v)){\n                    continue;\n                }\n                boolean allUncolored = allAdjacentUnColored(v.getAdjacentVertexes(),assignedColor);\n                if(allUncolored){\n                    color = getUnusedColor(colorsUsed);\n                    assignedColor.put(v.getId(), color);\n                    removeSet.add(v);\n                    finalAssignedColor.put(v.getId(), color);\n                }\n            }\n            colorsUsed.remove(color);\n            assignedColor.clear();\n        }\n        \n        System.out.println(finalAssignedColor);\n    }\n    \n    public void colorGraph(){\n        \n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addEdge(1, 2);\n        graph.addEdge(2, 3);\n        graph.addEdge(1, 4);\n        graph.addEdge(4, 6);\n        graph.addEdge(1, 7);\n        graph.addEdge(1, 8);\n        graph.addEdge(2, 9);\n        graph.addEdge(1, 3);\n        graph.addEdge(3, 4);\n        graph.addEdge(2,4);\n        graph.addEdge(3,7);\n\n        Map<String,Boolean> colorsUsed = new HashMap<String,Boolean>();\n        colorsUsed.put(\"Green\", false);\n        colorsUsed.put(\"Blue\", false);\n        colorsUsed.put(\"Red\", false);\n        colorsUsed.put(\"Yellow\", false);\n        \n        Map<Long,String> colorsAssigned = new HashMap<Long,String>();\n        \n        Collection<Vertex<Integer>> allVertex = graph.getAllVertex();\n        \n        for(Vertex<Integer> v : allVertex){\n            List<Vertex<Integer>> adjacentVertexes = v.getAdjacentVertexes();\n            for(Vertex<Integer> adjacentVertex : adjacentVertexes){\n                String color = colorsAssigned.get(adjacentVertex.getId());\n                if(color != null){\n                    assignColor(color,colorsUsed);\n                }\n            }\n            String color = getUnusedColor(colorsUsed);\n            colorsAssigned.put(v.getId(), color);\n            resetColor(colorsUsed);\n        }\n        \n        System.out.println(colorsAssigned);\n    }\n    \n    private String getUnusedColor(Map<String,Boolean> colorsUsed){\n        for(String color : colorsUsed.keySet()){\n            if(colorsUsed.get(color).equals(false)){\n                return color;\n            }\n        }\n        throw new RuntimeException();\n    }\n    \n    private void resetColor(Map<String,Boolean> colorsUsed){\n        Set<String> colors = new HashSet<String>();\n        for(String color : colorsUsed.keySet()){\n            colors.add(color);\n        }\n        for(String color : colors){\n            colorsUsed.remove(color);\n            colorsUsed.put(color, false);\n        }\n    }\n    \n    private void assignColor(String color, Map<String,Boolean> colorsUsed){\n        colorsUsed.remove(color);\n        colorsUsed.put(color, true);\n    }\n    \n    private boolean allAdjacentUnColored(Collection<Vertex<Integer>> vertexes, Map<Long,String> colorsAssigned){\n        for(Vertex<Integer> vertex : vertexes){\n            if(colorsAssigned.containsKey(vertex.getId())){\n                return false;\n            }\n        }\n        return true;\n    }\n    public static void main(String args[]){\n        GraphColoring graphColoring = new GraphColoring();\n        graphColoring.WelshPowell();\n    }\n}\n\n\nclass ComparatorVertex implements Comparator<Vertex<Integer>>{\n\n    @Override\n    public int compare(Vertex<Integer> o1, Vertex<Integer> o2) {\n        if(o1.getDegree() <= o2.getDegree()){\n            return 1;\n        }else{\n            return -1;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/graph/GraphTraversal.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Set;\n\n/**\n * http://www.geeksforgeeks.org/breadth-first-traversal-for-a-graph/\n * http://www.geeksforgeeks.org/depth-first-traversal-for-a-graph/\n */\npublic class GraphTraversal {\n\n    public void DFS(Graph<Integer> graph){\n        Set<Long> visited = new HashSet<Long>();\n        for(Vertex<Integer> vertex : graph.getAllVertex()){\n            if(!visited.contains(vertex.getId())){\n                DFSUtil(vertex,visited);\n            }\n        }\n        \n    }\n    \n    private void DFSUtil(Vertex<Integer> v,Set<Long> visited){\n        visited.add(v.getId());\n        System.out.print(v.getId() + \" \");\n        for(Vertex<Integer> vertex : v.getAdjacentVertexes()){\n            if(!visited.contains(vertex.getId()))\n                DFSUtil(vertex,visited);\n        }\n    }\n    \n    public void BFS(Graph<Integer> graph){\n        Set<Long> visited = new HashSet<Long>();\n        Queue<Vertex<Integer>> q = new LinkedList<Vertex<Integer>>();\n        \n        for(Vertex<Integer> vertex: graph.getAllVertex()){\n            if(!visited.contains(vertex.getId())){\n                q.add(vertex);\n                visited.add(vertex.getId());\n                while(q.size() != 0){\n                    Vertex<Integer> vq = q.poll();\n                    System.out.print(vq.getId()+ \" \");\n                    for(Vertex<Integer> v : vq.getAdjacentVertexes()){\n                        if(!visited.contains(v.getId())){\n                            q.add(v);\n                            visited.add(v.getId());\n                        }\n                    }\n                }\n            }\n        }\n        \n    }\n    \n    \n    public static void main(String args[]){\n        \n        Graph<Integer> graph = new Graph<Integer>(true);\n        graph.addEdge(1, 2);\n        graph.addEdge(1, 3);\n        graph.addEdge(2, 4);\n        graph.addEdge(3, 4);\n        graph.addEdge(4, 6);\n        graph.addEdge(6, 5);\n    //  graph.addEdge(5, 1);\n        graph.addEdge(5,3);\n        \n        GraphTraversal g = new GraphTraversal();\n        g.BFS(graph);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/HamiltonianCycle.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\npublic class HamiltonianCycle<T> {\n\n    public boolean getHamiltonianCycle(Graph<T> graph,List<Vertex<T>> result){\n        \n        Vertex<T> startVertex = graph.getAllVertex().iterator().next();\n        Set<Vertex<T>> visited = new HashSet<Vertex<T>>();\n        return hamiltonianUtil(startVertex,startVertex,result,visited,graph.getAllVertex().size());     \n        \n    }\n    \n    private boolean hamiltonianUtil(Vertex<T> startVertex, Vertex<T> currentVertex\n            , List<Vertex<T>> result, Set<Vertex<T>> visited, int totalVertex){\n        visited.add(currentVertex);\n        result.add(currentVertex);\n        \n        for(Vertex<T> child : currentVertex.getAdjacentVertexes()){\n            if(startVertex.equals(child) && totalVertex == result.size()){\n                result.add(startVertex);\n                return true;\n            }\n            if(!visited.contains(child)){\n                boolean isHamil = hamiltonianUtil(startVertex,child,result,visited,totalVertex);\n                if(isHamil){\n                    return true;\n                }\n            }\n        }\n        result.remove(result.size()-1);\n        visited.remove(currentVertex);\n        return false;\n    }\n    \n    public static void main(String args[]){\n        \n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addEdge(1, 2);\n        graph.addEdge(2, 3);\n        graph.addEdge(3, 5);\n        graph.addEdge(5, 2);\n        graph.addEdge(2, 4);\n        graph.addEdge(4, 1);\n        graph.addEdge(4, 5);\n        \n        HamiltonianCycle<Integer> hamil = new HamiltonianCycle<Integer>();\n        List<Vertex<Integer>> result = new ArrayList<Vertex<Integer>>();\n        boolean isHamiltonian = hamil.getHamiltonianCycle(graph, result);\n        System.out.println(isHamiltonian);\n        if(isHamiltonian){\n            System.out.print(result);\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/KruskalMST.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\n\n/**\n * Date 09/25/2014\n *\n * @author Tushar Roy\n *         <p>\n *         Find minimum spanning tree usinig Kruskals algorithm\n *         <p>\n *         Time complexity - O(ElogE)\n *         Space complexity - O(E + V)\n *         <p>\n *         References\n *         https://en.wikipedia.org/wiki/Kruskal%27s_algorithm\n */\n\npublic class KruskalMST {\n    /**\n     * Comparator to sort edges by weight in non decreasing order\n     */\n    public class EdgeComparator implements Comparator<Edge<Integer>> {\n        @Override\n        public int compare(Edge<Integer> edge1, Edge<Integer> edge2) {\n            if (edge1.getWeight() <= edge2.getWeight()) {\n                return -1;\n            } else {\n                return 1;\n            }\n        }\n    }\n\n    public List<Edge<Integer>> getMST(Graph<Integer> graph) {\n        List<Edge<Integer>> allEdges = graph.getAllEdges();\n        EdgeComparator edgeComparator = new EdgeComparator();\n\n        //sort all edges in non decreasing order\n        Collections.sort(allEdges, edgeComparator);\n        DisjointSet disjointSet = new DisjointSet();\n\n        //create as many disjoint sets as the total vertices\n        for (Vertex<Integer> vertex : graph.getAllVertex()) {\n            disjointSet.makeSet(vertex.getId());\n        }\n\n        List<Edge<Integer>> resultEdge = new ArrayList<Edge<Integer>>();\n\n        for (Edge<Integer> edge : allEdges) {\n            //get the sets of two vertices of the edge\n            long root1 = disjointSet.findSet(edge.getVertex1().getId());\n            long root2 = disjointSet.findSet(edge.getVertex2().getId());\n\n            //check if the vertices are in same set or different set\n            //if verties are in same set then ignore the edge\n            if (root1 == root2) {\n                continue;\n            } else {\n                //if vertices are in different set then add the edge to result and union these two sets into one\n                resultEdge.add(edge);\n                disjointSet.union(edge.getVertex1().getId(), edge.getVertex2().getId());\n            }\n\n        }\n        return resultEdge;\n    }\n\n    public static void main(String args[]) {\n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addEdge(1, 2, 4);\n        graph.addEdge(1, 3, 1);\n        graph.addEdge(2, 5, 1);\n        graph.addEdge(2, 6, 3);\n        graph.addEdge(2, 4, 2);\n        graph.addEdge(6, 5, 2);\n        graph.addEdge(6, 4, 3);\n        graph.addEdge(4, 7, 2);\n        graph.addEdge(3, 4, 5);\n        graph.addEdge(3, 7, 8);\n        KruskalMST mst = new KruskalMST();\n        List<Edge<Integer>> result = mst.getMST(graph);\n        for (Edge<Integer> edge : result) {\n            System.out.println(edge.getVertex1() + \" \" + edge.getVertex2());\n        }\n    }\n}"
  },
  {
    "path": "src/com/interview/graph/MaximumBiparteMatching.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * http://www.geeksforgeeks.org/maximum-bipartite-matching/\n */\npublic class MaximumBiparteMatching {\n\n    public int findMaxMatching(Map<Integer,List<Integer>> jobApplications, List<Integer> allJobs){\n        \n        Map<Integer,Integer> match = new HashMap<Integer,Integer>();\n        int maxMatch = 0;\n        for(Integer candidate : jobApplications.keySet()){\n            Set<Integer> jobsSeen = new HashSet<Integer>();\n            maxMatch += matchJobs(candidate, jobApplications, match, jobsSeen) ==true ? 1 : 0;\n        }\n        return maxMatch;\n    }\n    \n    private boolean matchJobs(Integer candidate, Map<Integer,List<Integer>> jobApplications,Map<Integer,Integer> match,Set<Integer> jobsSeen){\n    \n        for(int job : jobApplications.get(candidate)){\n            if(jobsSeen.contains(job)){\n                continue;\n            }\n            jobsSeen.add(job);\n            \n            if(match.get(job) == null){\n                match.put(job, candidate);\n                return true;\n            }\n            boolean flag = matchJobs(match.get(job),jobApplications,match,jobsSeen);\n            if(flag){\n                match.put(job, candidate);\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        List<Integer> app0 = new ArrayList<Integer>();\n        app0.add(10);\n        app0.add(11);\n        app0.add(13);\n        \n        List<Integer> app1 = new ArrayList<Integer>();\n        app1.add(10);\n        \n        List<Integer> app2 = new ArrayList<Integer>();\n        app2.add(12);\n\n        List<Integer> app3 = new ArrayList<Integer>();\n        app3.add(12);\n        app3.add(10);\n        app3.add(11);\n        \n        Map<Integer,List<Integer>> jobApplications = new HashMap<Integer,List<Integer>>();\n        jobApplications.put(0, app0);\n        jobApplications.put(1, app1);\n        jobApplications.put(2, app2);\n        jobApplications.put(3, app3);\n        MaximumBiparteMatching mbm = new MaximumBiparteMatching();\n        List<Integer> allJobs = new ArrayList<Integer>();\n        allJobs.add(10);\n        allJobs.add(11);\n        allJobs.add(12);\n        allJobs.add(13);\n        System.out.print(mbm.findMaxMatching(jobApplications, allJobs));\n        \n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/graph/MinimumHeightTree.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Date 03/08/2016\n * @author Tushar Roy\n *\n * Given a graph representing a tree. Find all minimum height trees.\n *\n * Time complexity O(n)\n * Space complexity O(n)\n *\n * https://leetcode.com/problems/minimum-height-trees/\n */\npublic class MinimumHeightTree {\n    public List<Integer> findMinHeightTrees(int n, int[][] edges) {\n        if (n == 1) {\n            return Collections.singletonList(0);\n        }\n        List<Set<Integer>> adj = new ArrayList<>();\n        for (int i = 0; i < n; i++) {\n            adj.add(new HashSet<>());\n        }\n        for (int[] edge: edges) {\n            adj.get(edge[0]).add(edge[1]);\n            adj.get(edge[1]).add(edge[0]);\n        }\n\n        List<Integer> leaves = new ArrayList<>();\n        for (int i = 0; i < n; i++) {\n            if (adj.get(i).size() == 1) {\n                leaves.add(i);\n            }\n        }\n\n        while (n > 2) {\n            n -= leaves.size();\n            List<Integer> newLeaves = new ArrayList<>();\n            for (int leaf : leaves) {\n                int node = adj.get(leaf).iterator().next();\n                adj.get(node).remove(leaf);\n                if (adj.get(node).size() == 1) {\n                    newLeaves.add(node);\n                }\n            }\n            leaves = newLeaves;\n        }\n\n        return leaves;\n    }\n\n    public static void main(String args[]) {\n        MinimumHeightTree mht = new MinimumHeightTree();\n        int input[][] = {{1,0},{1,2},{1,3}};\n        List<Integer> result = mht.findMinHeightTrees(4, input);\n        result.forEach(r -> System.out.print(r + \" \"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/NumberOfIsland.java",
    "content": "package com.interview.graph;\n\n/**\n http://www.geeksforgeeks.org/find-number-of-islands/\n */\npublic class NumberOfIsland {\n\n    public int numberOfIsland(int[][] graph){\n        \n        boolean[][] visited = new boolean[graph.length][graph.length];\n        int count = 0;\n        for(int i=0; i < graph.length ; i ++){\n            for(int j =0 ; j < graph[i].length ; j++){\n                if(visited[i][j] == false && graph[i][j] == 1) {\n                    count++;\n                    DFS(graph,visited,i,j);\n                }\n            }\n        }\n        return count;\n    }\n    \n    private void DFS(int[][] graph, boolean[][] visited,int i,int j){\n        if(i <0 || j < 0 || i == graph.length || j == graph[i].length)\n        {\n            return;\n            \n        }\n        visited[i][j] = true;\n        if(graph[i][j] == 0){\n            return;\n        }\n        DFS(graph,visited,i,j+1);\n        DFS(graph,visited,i+1,j);\n        DFS(graph,visited,i+1,j+1);\n        DFS(graph,visited,i-1, j+1);\n    }\n    \n    public static void main(String args[]){\n        \n        int matrix[][] = {{1,1,0,1,0},\n                          {1,0,0,1,1},\n                          {0,0,0,0,0},\n                          {1,0,1,0,1},\n                          {1,0,0,0,0}\n                        };\n        NumberOfIsland island = new NumberOfIsland();\n        int count = island.numberOfIsland(matrix);\n        System.out.println(count);\n    }\n}\n                     "
  },
  {
    "path": "src/com/interview/graph/NumberOfIslandDynamic.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand operation\n * which turns the water at position (row, col) into a land. Given a list of positions to operate,\n * count the number of islands after each addLand operation. An island is surrounded by water and is formed by\n * connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all\n * surrounded by water.\n * https://leetcode.com/problems/number-of-islands-ii/\n */\npublic class NumberOfIslandDynamic {\n    public List<Integer> numIslands2(int n, int m, int[][] positions) {\n        if (positions.length == 0 || positions[0].length == 0) {\n            return Collections.emptyList();\n        }\n        int count = 0;\n        DisjointSet ds = new DisjointSet();\n        Set<Integer> land = new HashSet<>();\n        List<Integer> result = new ArrayList<>();\n        for (int[] position : positions) {\n            int index = position[0]*m + position[1];\n            land.add(index);\n            ds.makeSet(index);\n            count++;\n            //find the four neighbors;\n            int n1 = (position[0] - 1)*m + position[1];\n            int n2 = (position[0] + 1)*m + position[1];\n            int n3 = (position[0])*m + position[1] + 1;\n            int n4 = (position[0])*m + position[1] - 1;\n\n            if (position[0] - 1 >= 0 && land.contains(n1)) {\n                if (ds.union(index, n1)) {\n                    count--;\n                }\n            }\n            if (position[0] + 1 < n && land.contains(n2)) {\n                if (ds.union(index, n2)) {\n                    count--;\n                }\n            }\n            if (position[1] + 1 < m && land.contains(n3)) {\n                if (ds.union(index, n3)) {\n                    count--;\n                }\n            }\n            if (position[1] - 1 >= 0 && land.contains(n4)) {\n                if (ds.union(index, n4)) {\n                    count--;\n                }\n            }\n            result.add(count);\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        NumberOfIslandDynamic nd = new NumberOfIslandDynamic();\n        int[][] input = {{0, 1}, {1, 2}, {2, 1}, {1, 0}, {0, 2}, {0, 0}, {1, 1}};\n        System.out.print(nd.numIslands2(3, 3, input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/NumberofTriangles.java",
    "content": "package com.interview.graph;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * http://www.careercup.com/question?id=5988741646647296\n * Given an undirected graph find number of triangles in this graph\n * Find cycle of length 3. Pass parent in DFS search.\n * If there is a cycle check if my parent is neighbor of the the node \n * which caused it to be a cycle.\n */\npublic class NumberofTriangles {\n\n    public int countTriangles(Graph<Integer> graph){\n        Map<Vertex<Integer>,Boolean> visited = new HashMap<Vertex<Integer>,Boolean>();\n        int count =0;\n        for(Vertex<Integer> vertex : graph.getAllVertex()){\n            count += DFS(vertex,visited,null);\n        }\n        return count;\n    }\n    \n    public int DFS(Vertex<Integer> vertex, Map<Vertex<Integer>,Boolean> visited,Vertex<Integer> parent){\n        \n        if(visited.containsKey(vertex)){\n            return 0;\n        }\n        visited.put(vertex, true);\n        int count = 0;\n        for(Vertex<Integer> child : vertex.getAdjacentVertexes()){\n            if(child.equals(parent)){\n                continue;\n            }\n            if(visited.containsKey(child)){\n                count += isNeighbor(child, parent) ? 1: 0;\n            }else{\n                count += DFS(child, visited, vertex);\n            }\n        }\n        return count;\n    }\n    \n    private boolean isNeighbor(Vertex<Integer> vertex, Vertex<Integer> destVertex){\n        for(Vertex<Integer> child : vertex.getAdjacentVertexes()){\n            if(child.equals(destVertex)){\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addEdge(0, 1);\n        graph.addEdge(0, 2);\n        graph.addEdge(1, 2);\n        graph.addEdge(2, 3);\n        graph.addEdge(1, 3);\n        graph.addEdge(3, 4);\n        graph.addEdge(0, 4);\n        graph.addEdge(0,3);\n        NumberofTriangles not = new NumberofTriangles();\n        System.out.println(not.countTriangles(graph));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/PrimMST.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Date 10/11/2014\n * @author Tushar Roy\n *\n * Find minimum spanning tree using Prim's algorithm\n *\n * Space complexity - O(E + V)\n * Time complexity - O(ElogV)\n *\n * References\n * https://en.wikipedia.org/wiki/Prim%27s_algorithm\n * CLRS book\n */\npublic class PrimMST {\n\n    /**\n     * Main method of Prim's algorithm.\n     */\n    public List<Edge<Integer>> primMST(Graph<Integer> graph){\n\n        //binary heap + map data structure\n        BinaryMinHeap<Vertex<Integer>> minHeap = new BinaryMinHeap<>();\n\n        //map of vertex to edge which gave minimum weight to this vertex.\n        Map<Vertex<Integer>,Edge<Integer>> vertexToEdge = new HashMap<>();\n\n        //stores final result\n        List<Edge<Integer>> result = new ArrayList<>();\n\n        //insert all vertices with infinite value initially.\n        for(Vertex<Integer> v : graph.getAllVertex()){\n            minHeap.add(Integer.MAX_VALUE, v);\n        }\n\n        //start from any random vertex\n        Vertex<Integer> startVertex = graph.getAllVertex().iterator().next();\n\n        //for the start vertex decrease the value in heap + map to 0\n        minHeap.decrease(startVertex, 0);\n\n        //iterate till heap + map has elements in it\n        while(!minHeap.empty()){\n            //extract min value vertex from heap + map\n            Vertex<Integer> current = minHeap.extractMin();\n\n            //get the corresponding edge for this vertex if present and add it to final result.\n            //This edge wont be present for first vertex.\n            Edge<Integer> spanningTreeEdge = vertexToEdge.get(current);\n            if(spanningTreeEdge != null) {\n                result.add(spanningTreeEdge);\n            }\n\n            //iterate through all the adjacent vertices\n            for(Edge<Integer> edge : current.getEdges()){\n                Vertex<Integer> adjacent = getVertexForEdge(current, edge);\n                //check if adjacent vertex exist in heap + map and weight attached with this vertex is greater than this edge weight\n                if(minHeap.containsData(adjacent) && minHeap.getWeight(adjacent) > edge.getWeight()){\n                    //decrease the value of adjacent vertex to this edge weight.\n                    minHeap.decrease(adjacent, edge.getWeight());\n                    //add vertex->edge mapping in the graph.\n                    vertexToEdge.put(adjacent, edge);\n                }\n            }\n        }\n        return result;\n    }\n\n    private Vertex<Integer> getVertexForEdge(Vertex<Integer> v, Edge<Integer> e){\n        return e.getVertex1().equals(v) ? e.getVertex2() : e.getVertex1();\n    }\n\n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<>(false);\n     /* graph.addEdge(0, 1, 4);\n        graph.addEdge(1, 2, 8);\n        graph.addEdge(2, 3, 7);\n        graph.addEdge(3, 4, 9);\n        graph.addEdge(4, 5, 10);\n        graph.addEdge(2, 5, 4);\n        graph.addEdge(1, 7, 11);\n        graph.addEdge(0, 7, 8);\n        graph.addEdge(2, 8, 2);\n        graph.addEdge(3, 5, 14);\n        graph.addEdge(5, 6, 2);\n        graph.addEdge(6, 8, 6);\n        graph.addEdge(6, 7, 1);\n        graph.addEdge(7, 8, 7);*/\n\n        graph.addEdge(1, 2, 3);\n        graph.addEdge(2, 3, 1);\n        graph.addEdge(3, 1, 1);\n        graph.addEdge(1, 4, 1);\n        graph.addEdge(2, 4, 3);\n        graph.addEdge(4, 5, 6);\n        graph.addEdge(5, 6, 2);\n        graph.addEdge(3, 5, 5);\n        graph.addEdge(3, 6, 4);\n\n        PrimMST prims = new PrimMST();\n        Collection<Edge<Integer>> edges = prims.primMST(graph);\n        for(Edge<Integer> edge : edges){\n            System.out.println(edge);\n        }\n    }\n    \n    \n}\n"
  },
  {
    "path": "src/com/interview/graph/PrintAllPathFromSourceToDestination.java",
    "content": "package com.interview.graph;\n\nimport java.util.LinkedHashSet;\nimport java.util.Set;\n\n/**\n * http://www.careercup.com/question?id=5922416572235776\n * Test case\n * Source or destination vertex does not exist in the graph\n * There is no path between src to dest vertex\n */\npublic class PrintAllPathFromSourceToDestination {\n\n    public void printPath(Graph<Integer> graph,Vertex<Integer> start, Vertex<Integer> destination){\n        Set<Vertex<Integer>> visited = new LinkedHashSet<Vertex<Integer>>();\n        printPath(visited,destination,start);\n    }\n    \n    private void printPath(Set<Vertex<Integer>> visited,Vertex<Integer> destination,Vertex<Integer> current){\n        if(visited.contains(current)){\n            return;\n        }\n        if(destination.equals(current)){\n            for(Vertex<Integer> v : visited){\n                System.out.print(v.id + \" \");\n            }\n            System.out.println(destination.id);\n            return;\n        }\n        \n        visited.add(current);\n        for(Vertex<Integer> child : current.getAdjacentVertexes()){\n            printPath(visited,destination,child);\n        }\n        visited.remove(current);\n    }\n    \n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<Integer>(false);\n        graph.addEdge(1, 2);\n        graph.addEdge(1, 3);\n        graph.addEdge(2, 4);\n        graph.addEdge(2, 5);\n        graph.addEdge(3, 6);\n        graph.addEdge(5, 6);\n        graph.addEdge(5, 7);\n        graph.addEdge(6, 7);\n        graph.addEdge(4, 7);\n        graph.addEdge(1, 8);\n        graph.addEdge(8, 9);\n        graph.addEdge(9, 1);\n        Vertex<Integer> start = graph.getVertex(1);\n        Vertex<Integer> dest = graph.getVertex(7);\n        PrintAllPathFromSourceToDestination pap = new PrintAllPathFromSourceToDestination();\n        pap.printPath(graph, start, dest);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/ShortestDistanceFromExit.java",
    "content": "package com.interview.graph;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\n\nenum Cell{\n\tSPACE,\n\tBLOCK,\n\tGUARD\n}\n\nclass Point{\n\tint x;\n\tint y;\n\tPoint(int x, int y){\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t}\n}\n\n/**\n * @Date 07/05/2015\n * @author Tushar Roy\n * \n * Given a 2 D floor plan with empty space, block and multiple exits. Find distance of every empty space\n * from nearest exits in case of fire emergency.\n * \n * Idea is to start from every exit position and do BFS search in all 4 directions and maintain the distance of every\n * space from exit. If another exit in future iterator is closer than already calculated exit then update\n * the distance.\n * \n * Space complexity is O(n*m)\n * Time complexity is O(number of exit * m * n);\n *\n */\npublic class ShortestDistanceFromExit {\n\n\tpublic int[][] findShortest(Cell input[][]){\n\t\tint distance[][] = new int[input.length][input[0].length];\n\t\tfor(int i=0; i < input.length; i++){\n\t\t\tfor(int j=0; j < input[0].length; j++){\n\t\t\t\tdistance[i][j] = Integer.MAX_VALUE;\n\t\t\t}\n\t\t}\n\t\t\n\t\tfor(int i=0; i < input.length; i++){\n\t\t\tfor(int j =0; j < input[i].length; j++){\n\t\t\t\t//for every exit location do a BFS starting with this exit as the origin\n\t\t\t\tif(input[i][j] == Cell.GUARD){\n\t\t\t\t\tdistance[i][j] = 0;\n\t\t\t\t\tsetDistance(input, i, j, distance);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn distance;\n\t\t\n\t}\n\t\n\tprivate void setDistance(Cell input[][], int x, int y, int distance[][]){\n\t\t\n\t\tboolean visited[][] = new boolean[input.length][input[0].length];\n\t\tQueue<Point> q = new LinkedList<>();\n\t\tq.offer(new Point(x,y));\n\t\t//Do a BFS at keep updating distance.\n\t\twhile(!q.isEmpty()){\n\t\t\tPoint p = q.poll();\n\t\t\tsetDistanceUtil(q, input, p, getNeighbor(input, p.x+1, p.y), distance, visited);\n\t\t\tsetDistanceUtil(q, input, p, getNeighbor(input, p.x, p.y+1), distance, visited);\n\t\t\tsetDistanceUtil(q, input, p, getNeighbor(input, p.x-1, p.y), distance, visited);\n\t\t\tsetDistanceUtil(q, input, p, getNeighbor(input, p.x, p.y-1), distance, visited);\n\t\t}\n\t}\n\n\tprivate void setDistanceUtil(Queue<Point> q, Cell input[][], Point p, Point newPoint, int distance[][], boolean visited[][]){\n\t\tif(newPoint != null && !visited[newPoint.x][newPoint.y]){\n\t\t\tif(input[newPoint.x][newPoint.y] != Cell.GUARD && input[newPoint.x][newPoint.y] != Cell.BLOCK){\n\t\t\t\tdistance[newPoint.x][newPoint.y] = Math.min(distance[newPoint.x][newPoint.y], 1 + distance[p.x][p.y]);\n\t\t\t\tvisited[newPoint.x][newPoint.y] = true;\n\t\t\t\tq.offer(newPoint);\n\t\t\t}\n\t\t}\n\t}\n\t\n\tprivate Point getNeighbor(Cell input[][], int x, int y){\n\t\tif(x < 0 || x >= input.length || y < 0 || y >= input[0].length ) {\n\t\t\treturn null;\n\t\t}\n\t\treturn new Point(x,y);\n\t}\n\tpublic static void main(String args[]){\n\t\tShortestDistanceFromExit sdg = new ShortestDistanceFromExit();\n\t\tCell input[][] = {{Cell.SPACE, Cell.SPACE, Cell.BLOCK, Cell.BLOCK},\n\t\t\t\t\t\t  {Cell.SPACE, Cell.SPACE, Cell.GUARD, Cell.SPACE},\n\t\t\t\t\t\t  {Cell.SPACE, Cell.SPACE, Cell.BLOCK, Cell.SPACE},\n\t\t\t\t\t\t  {Cell.SPACE, Cell.GUARD, Cell.BLOCK, Cell.SPACE}\n\t\t\t\t\t\t };\t\t\n\t\tint result[][] = sdg.findShortest(input);\n\t\tfor(int i=0; i < result.length; i++) {\n\t\t\tfor(int j=0; j < result[0].length; j++){\n\t\t\t\tSystem.out.print(result[i][j] + \" \");\n\t\t\t}\n\t\t\tSystem.out.println();\n\t\t}\n\t\t\n\t}\n\t\n}\n"
  },
  {
    "path": "src/com/interview/graph/StronglyConnectedComponent.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.Deque;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Date 10/01/2014\n * @author Tushar Roy\n *\n * Given a directed graph, find all strongly connected components in this graph.\n * We are going to use Kosaraju's algorithm to find strongly connected component.\n *\n * Algorithm\n * Create a order of vertices by finish time in decreasing order.\n * Reverse the graph\n * Do a DFS on reverse graph by finish time of vertex and created strongly connected\n * components.\n *\n * Runtime complexity - O(V + E)\n * Space complexity - O(V)\n *\n * References\n * https://en.wikipedia.org/wiki/Strongly_connected_component\n * http://www.geeksforgeeks.org/strongly-connected-components/\n */\npublic class StronglyConnectedComponent {\n\n    public List<Set<Vertex<Integer>>> scc(Graph<Integer> graph) {\n\n        //it holds vertices by finish time in reverse order.\n        Deque<Vertex<Integer>> stack = new ArrayDeque<>();\n        //holds visited vertices for DFS.\n        Set<Vertex<Integer>> visited = new HashSet<>();\n\n        //populate stack with vertices with vertex finishing last at the top.\n        for (Vertex<Integer> vertex : graph.getAllVertex()) {\n            if (visited.contains(vertex)) {\n                continue;\n            }\n            DFSUtil(vertex, visited, stack);\n        }\n\n        //reverse the graph.\n        Graph<Integer> reverseGraph = reverseGraph(graph);\n\n        //Do a DFS based off vertex finish time in decreasing order on reverse graph..\n        visited.clear();\n        List<Set<Vertex<Integer>>> result = new ArrayList<>();\n        while (!stack.isEmpty()) {\n            Vertex<Integer> vertex = reverseGraph.getVertex(stack.poll().getId());\n            if(visited.contains(vertex)){\n                continue;\n            }\n            Set<Vertex<Integer>> set = new HashSet<>();\n            DFSUtilForReverseGraph(vertex, visited, set);\n            result.add(set);\n        }\n        return result;\n    }\n\n    private Graph<Integer> reverseGraph(Graph<Integer> graph) {\n        Graph<Integer> reverseGraph = new Graph<>(true);\n        for (Edge<Integer> edge : graph.getAllEdges()) {\n            reverseGraph.addEdge(edge.getVertex2().getId(), edge.getVertex1()\n                    .getId(), edge.getWeight());\n        }\n        return reverseGraph;\n    }\n\n    private void DFSUtil(Vertex<Integer> vertex,\n            Set<Vertex<Integer>> visited, Deque<Vertex<Integer>> stack) {\n        visited.add(vertex);\n        for (Vertex<Integer> v : vertex.getAdjacentVertexes()) {\n            if (visited.contains(v)) {\n                continue;\n            }\n            DFSUtil(v, visited, stack);\n        }\n        stack.offerFirst(vertex);\n    }\n\n    private void DFSUtilForReverseGraph(Vertex<Integer> vertex,\n                                        Set<Vertex<Integer>> visited, Set<Vertex<Integer>> set) {\n        visited.add(vertex);\n        set.add(vertex);\n        for (Vertex<Integer> v : vertex.getAdjacentVertexes()) {\n            if (visited.contains(v)) {\n                continue;\n            }\n            DFSUtilForReverseGraph(v, visited, set);\n        }\n    }\n\n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<>(true);\n        graph.addEdge(0, 1);\n        graph.addEdge(1, 2);\n        graph.addEdge(2, 0);\n        graph.addEdge(1, 3);\n        graph.addEdge(3, 4);\n        graph.addEdge(4, 5);\n        graph.addEdge(5, 3);\n        graph.addEdge(5, 6);\n\n        StronglyConnectedComponent scc = new StronglyConnectedComponent();\n        List<Set<Vertex<Integer>>> result = scc.scc(graph);\n\n        //print the result\n        result.forEach(set -> {\n            set.forEach(v -> System.out.print(v.getId() + \" \"));\n            System.out.println();\n        });\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/TarjanStronglyConnectedComponent.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Date 08/16/2015\n * @author Tushar Roy\n *\n * Find strongly connected components of directed graph.\n *\n * Time complexity is O(E + V)\n * Space complexity  is O(V)\n *\n * Reference - https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm\n */\npublic class TarjanStronglyConnectedComponent {\n\n    private Map<Vertex<Integer>, Integer> visitedTime;\n    private Map<Vertex<Integer>, Integer> lowTime;\n    private Set<Vertex<Integer>> onStack;\n    private Deque<Vertex<Integer>> stack;\n    private Set<Vertex<Integer>> visited;\n    private List<Set<Vertex<Integer>>> result;\n    private int time;\n\n    public List<Set<Vertex<Integer>>> scc(Graph<Integer> graph) {\n\n        //keeps the time when every vertex is visited\n        time = 0;\n        //keeps map of vertex to time it was visited\n        visitedTime = new HashMap<>();\n\n        //keeps map of vertex and time of first vertex visited in current DFS\n        lowTime = new HashMap<>();\n\n        //tells if a vertex is in stack or not\n        onStack = new HashSet<>();\n\n        //stack of visited vertices\n        stack = new LinkedList<>();\n\n        //tells if vertex has ever been visited or not. This is for DFS purpose.\n        visited = new HashSet<>();\n\n        //stores the strongly connected components result;\n        result = new ArrayList<>();\n\n        //start from any vertex in the graph.\n        for (Vertex<Integer> vertex : graph.getAllVertex()) {\n            if(visited.contains(vertex)) {\n                continue;\n            }\n            sccUtil(vertex);\n        }\n\n        return result;\n    }\n\n    private void sccUtil(Vertex<Integer> vertex) {\n\n        visited.add(vertex);\n        visitedTime.put(vertex, time);\n        lowTime.put(vertex, time);\n        time++;\n        stack.addFirst(vertex);\n        onStack.add(vertex);\n\n        for (Vertex child : vertex.getAdjacentVertexes()) {\n            //if child is not visited then visit it and see if it has link back to vertex's ancestor. In that case update\n            //low time to ancestor's visit time\n            if (!visited.contains(child)) {\n                sccUtil(child);\n                //sets lowTime[vertex] = min(lowTime[vertex], lowTime[child]);\n                lowTime.compute(vertex, (v, low) ->\n                    Math.min(low, lowTime.get(child))\n                );\n            } //if child is on stack then see if it was visited before vertex's low time. If yes then update vertex's low time to that.\n            else if (onStack.contains(child)) {\n                //sets lowTime[vertex] = min(lowTime[vertex], visitedTime[child]);\n                lowTime.compute(vertex, (v, low) -> Math.min(low, visitedTime.get(child))\n                );\n            }\n        }\n\n        //if vertex low time is same as visited time then this is start vertex for strongly connected component.\n        //keep popping vertices out of stack still you find current vertex. They are all part of one strongly\n        //connected component.\n        if (visitedTime.get(vertex) == lowTime.get(vertex)) {\n            Set<Vertex<Integer>> stronglyConnectedComponenet = new HashSet<>();\n            Vertex v;\n            do {\n                v = stack.pollFirst();\n                onStack.remove(v);\n                stronglyConnectedComponenet.add(v);\n            } while (!vertex.equals(v));\n            result.add(stronglyConnectedComponenet);\n        }\n    }\n\n    public static void main(String args[]) {\n        Graph<Integer> graph = new Graph<>(true);\n        graph.addEdge(1,2);\n        graph.addEdge(2,3);\n        graph.addEdge(3,1);\n        graph.addEdge(3,4);\n        graph.addEdge(4,5);\n        graph.addEdge(5,6);\n        graph.addEdge(6,4);\n        graph.addEdge(7,6);\n        graph.addEdge(7,8);\n        graph.addEdge(8,7);\n\n        TarjanStronglyConnectedComponent tarjanStronglyConnectedComponent = new TarjanStronglyConnectedComponent();\n        List<Set<Vertex<Integer>>> result = tarjanStronglyConnectedComponent.scc(graph);\n\n        result.forEach(scc -> {\n            scc.forEach(vertex -> System.out.print(vertex + \" \"));\n            System.out.println();\n        });\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/TopologicalSort.java",
    "content": "package com.interview.graph;\n\nimport java.util.Set;\nimport java.util.HashSet;\nimport java.util.Deque;\nimport java.util.ArrayDeque;\n\n/**\n * Date 08/20/2014\n * @author Tushar Roy\n *\n * Given a directed acyclic graph, do a topological sort on this graph.\n *\n * Do DFS by keeping visited. Put the vertex which are completely explored into a stack.\n * Pop from stack to get sorted order.\n *\n * Space and time complexity is O(n).\n */\npublic class TopologicalSort<T> {\n\n    /**\n     * Main method to be invoked to do topological sorting.\n     */\n    public Deque<Vertex<T>> topSort(Graph<T> graph) {\n        Deque<Vertex<T>> stack = new ArrayDeque<>();\n        Set<Vertex<T>> visited = new HashSet<>();\n        for (Vertex<T> vertex : graph.getAllVertex()) {\n            if (visited.contains(vertex)) {\n                continue;\n            }\n            topSortUtil(vertex,stack,visited);\n        }\n        return stack;\n    }\n\n    private void topSortUtil(Vertex<T> vertex, Deque<Vertex<T>> stack,\n            Set<Vertex<T>> visited) {\n        visited.add(vertex);\n        for(Vertex<T> childVertex : vertex.getAdjacentVertexes()){\n            if(visited.contains(childVertex)){\n                continue;\n            }\n            topSortUtil(childVertex,stack,visited);\n        }\n        stack.offerFirst(vertex);\n    }\n    \n    public static void main(String args[]){\n        Graph<Integer> graph = new Graph<>(true);\n        graph.addEdge(1, 3);\n        graph.addEdge(1, 2);\n        graph.addEdge(3, 4);\n        graph.addEdge(5, 6);\n        graph.addEdge(6, 3);\n        graph.addEdge(3, 8);\n        graph.addEdge(8, 11);\n        \n        TopologicalSort<Integer> sort = new TopologicalSort<Integer>();\n        Deque<Vertex<Integer>> result = sort.topSort(graph);\n        while(!result.isEmpty()){\n            System.out.println(result.poll());\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/TransitiveClosure.java",
    "content": "package com.interview.graph;\n\n/**\n * http://www.geeksforgeeks.org/transitive-closure-of-a-graph/\n */\npublic class TransitiveClosure {\n\n    public boolean[][] getTransitiveClosure(int [][]graph){\n        int rows = graph.length;\n        int cols = graph[0].length;\n        boolean[][] result = new  boolean[rows][cols];\n\n        for(int i = 0; i < graph.length; i++){\n            for(int j=0; j < graph.length; j++){\n                if(graph[i][j] != 100){\n                    result[i][j] = true;\n                }\n            }\n        }\n        for(int i=0; i < rows; i++){\n            for(int j=0 ; j < rows; j++){\n                for(int k=0; k < rows; k++){\n                    result[i][j] = result[i][j] || (result[i][k] && result[k][j]);\n                }\n            }\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        TransitiveClosure closure = new TransitiveClosure();\n        int[][] graph = {{0,2,2,4,100},{100,0,100,1,100},{100,100,0,3,100},{100,100,3,0,2},{100,3,100,100,0}};\n        boolean result[][] = closure.getTransitiveClosure(graph);\n        for(int i=0; i < result.length; i++){\n            for(int j=0; j < result.length; j++){\n                System.out.print(result[i][j] + \" \");\n            }\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/graph/TravelingSalesmanHeldKarp.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Date 11/17/2015\n * @author Tushar Roy\n *\n * Help Karp method of finding tour of traveling salesman.\n *\n * Time complexity - O(2^n * n^2)\n * Space complexity - O(2^n)\n *\n * https://en.wikipedia.org/wiki/Held%E2%80%93Karp_algorithm\n */\npublic class TravelingSalesmanHeldKarp {\n\n    private static int INFINITY = 100000000;\n\n    private static class Index {\n        int currentVertex;\n        Set<Integer> vertexSet;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Index index = (Index) o;\n\n            if (currentVertex != index.currentVertex) return false;\n            return !(vertexSet != null ? !vertexSet.equals(index.vertexSet) : index.vertexSet != null);\n        }\n\n        @Override\n        public int hashCode() {\n            int result = currentVertex;\n            result = 31 * result + (vertexSet != null ? vertexSet.hashCode() : 0);\n            return result;\n        }\n\n        private static Index createIndex(int vertex, Set<Integer> vertexSet) {\n            Index i = new Index();\n            i.currentVertex = vertex;\n            i.vertexSet = vertexSet;\n            return i;\n        }\n    }\n\n    private static class SetSizeComparator implements Comparator<Set<Integer>>{\n        @Override\n        public int compare(Set<Integer> o1, Set<Integer> o2) {\n            return o1.size() - o2.size();\n        }\n    }\n\n    public int minCost(int[][] distance) {\n\n        //stores intermediate values in map\n        Map<Index, Integer> minCostDP = new HashMap<>();\n        Map<Index, Integer> parent = new HashMap<>();\n\n        List<Set<Integer>> allSets = generateCombination(distance.length - 1);\n\n        for(Set<Integer> set : allSets) {\n            for(int currentVertex = 1; currentVertex < distance.length; currentVertex++) {\n                if(set.contains(currentVertex)) {\n                    continue;\n                }\n                Index index = Index.createIndex(currentVertex, set);\n                int minCost = INFINITY;\n                int minPrevVertex = 0;\n                //to avoid ConcurrentModificationException copy set into another set while iterating\n                Set<Integer> copySet = new HashSet<>(set);\n                for(int prevVertex : set) {\n                    int cost = distance[prevVertex][currentVertex] + getCost(copySet, prevVertex, minCostDP);\n                    if(cost < minCost) {\n                        minCost = cost;\n                        minPrevVertex = prevVertex;\n                    }\n                }\n                //this happens for empty subset\n                if(set.size() == 0) {\n                    minCost = distance[0][currentVertex];\n                }\n                minCostDP.put(index, minCost);\n                parent.put(index, minPrevVertex);\n            }\n        }\n\n        Set<Integer> set = new HashSet<>();\n        for(int i=1; i < distance.length; i++) {\n            set.add(i);\n        }\n        int min = Integer.MAX_VALUE;\n        int prevVertex = -1;\n        //to avoid ConcurrentModificationException copy set into another set while iterating\n        Set<Integer> copySet = new HashSet<>(set);\n        for(int k : set) {\n            int cost = distance[k][0] + getCost(copySet, k, minCostDP);\n            if(cost < min) {\n                min = cost;\n                prevVertex = k;\n            }\n        }\n\n        parent.put(Index.createIndex(0, set), prevVertex);\n        printTour(parent, distance.length);\n        return min;\n    }\n\n    private void printTour(Map<Index, Integer> parent, int totalVertices) {\n        Set<Integer> set = new HashSet<>();\n        for(int i=0; i < totalVertices; i++) {\n            set.add(i);\n        }\n        Integer start = 0;\n        Deque<Integer> stack = new LinkedList<>();\n        while(true) {\n            stack.push(start);\n            set.remove(start);\n            start = parent.get(Index.createIndex(start, set));\n            if(start == null) {\n                break;\n            }\n        }\n        StringJoiner joiner = new StringJoiner(\"->\");\n        stack.forEach(v -> joiner.add(String.valueOf(v)));\n        System.out.println(\"\\nTSP tour\");\n        System.out.println(joiner.toString());\n    }\n\n    private int getCost(Set<Integer> set, int prevVertex, Map<Index, Integer> minCostDP) {\n        set.remove(prevVertex);\n        Index index = Index.createIndex(prevVertex, set);\n        int cost = minCostDP.get(index);\n        set.add(prevVertex);\n        return cost;\n    }\n\n    private List<Set<Integer>> generateCombination(int n) {\n        int input[] = new int[n];\n        for(int i = 0; i < input.length; i++) {\n            input[i] = i+1;\n        }\n        List<Set<Integer>> allSets = new ArrayList<>();\n        int result[] = new int[input.length];\n        generateCombination(input, 0, 0, allSets, result);\n        Collections.sort(allSets, new SetSizeComparator());\n        return allSets;\n    }\n\n    private void generateCombination(int input[], int start, int pos, List<Set<Integer>> allSets, int result[]) {\n        if(pos == input.length) {\n            return;\n        }\n        Set<Integer> set = createSet(result, pos);\n        allSets.add(set);\n        for(int i=start; i < input.length; i++) {\n            result[pos] = input[i];\n            generateCombination(input, i+1, pos+1, allSets, result);\n        }\n    }\n\n    private static Set<Integer> createSet(int input[], int pos) {\n        if(pos == 0) {\n            return new HashSet<>();\n        }\n        Set<Integer> set = new HashSet<>();\n        for(int i = 0; i < pos; i++) {\n            set.add(input[i]);\n        }\n        return set;\n    }\n}\n\n\n\n\n"
  },
  {
    "path": "src/com/interview/graph/ValidTree.java",
    "content": "package com.interview.graph;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes),\n * write a function to check whether these edges make up a valid tree.\n * https://leetcode.com/problems/graph-valid-tree/\n */\npublic class ValidTree {\n    public boolean validTree(int n, int[][] edges) {\n        if (n <= 1) {\n            return true;\n        }\n\n        Map<Integer, List<Integer>> graph = new HashMap<>();\n\n        for (int[] edge : edges) {\n            List<Integer> neighbors = graph.get(edge[0]);\n            if (neighbors == null) {\n                neighbors = new ArrayList<>();\n                graph.put(edge[0], neighbors);\n            }\n            neighbors.add(edge[1]);\n            neighbors = graph.get(edge[1]);\n            if (neighbors == null) {\n                neighbors = new ArrayList<>();\n                graph.put(edge[1], neighbors);\n            }\n            neighbors.add(edge[0]);\n        }\n\n        boolean[] visited = new boolean[n];\n        boolean hasCycle = isCycle(0, graph, -1, visited);\n        if (hasCycle) {\n            return false;\n        }\n        for (int i = 0; i < visited.length; i++) {\n            if (!visited[i]) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    boolean isCycle(int vertex, Map<Integer, List<Integer>> graph, int parent, boolean[] visited) {\n        if (visited[vertex]) {\n            return true;\n        }\n        visited[vertex] = true;\n        if (graph.get(vertex) == null) {\n            return false;\n        }\n        for (int i : graph.get(vertex)) {\n            if (i == parent) {\n                continue;\n            }\n            if (isCycle(i, graph, vertex, visited)) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/graph/WallsAndGates.java",
    "content": "package com.interview.graph;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * You are given a m x n 2D grid initialized with these three possible values.\n *      -1 - A wall or an obstacle.\n *      0 - A gate.\n *      INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as\n *      you may assume that the distance to a gate is less than 2147483647.\n *\n * Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF\n *\n * Time complexity O(n*m)\n * Space complexity O(n*m)\n *\n * https://leetcode.com/problems/walls-and-gates/\n */\npublic class WallsAndGates {\n    private static final int d[][] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    private static final int INF = Integer.MAX_VALUE;\n\n    public void wallsAndGates(int[][] rooms) {\n        Deque<Cell> queue = new LinkedList<>();\n        gates(rooms, queue);\n\n        while (!queue.isEmpty()) {\n            Cell cell = queue.pollLast();\n            addNeighbors(rooms, cell.row, cell.col, queue);\n        }\n\n    }\n\n    private  void addNeighbors(int[][] rooms, int row, int col, Deque<Cell> queue) {\n        for (int[] d1 : d) {\n            int r1 = row + d1[0];\n            int c1 = col + d1[1];\n            if (r1 < 0 || c1 < 0 || r1 >= rooms.length || c1 >= rooms[0].length || rooms[r1][c1] != INF) {\n                continue;\n            }\n            rooms[r1][c1] = 1 + rooms[row][col];\n            queue.offerFirst(new Cell(r1, c1));\n        }\n    }\n\n    private void gates(int[][] rooms, Deque<Cell> queue) {\n        for (int i = 0; i < rooms.length; i++) {\n            for (int j = 0; j < rooms[0].length; j++) {\n                if (rooms[i][j] == 0) {\n                    queue.offerFirst(new Cell(i, j));\n                }\n            }\n        }\n    }\n\n    class Cell {\n        int row;\n        int col;\n\n        Cell(int row, int col) {\n            this.row = row;\n            this.col = col;\n        }\n    }\n}"
  },
  {
    "path": "src/com/interview/graph/WordLadder.java",
    "content": "package com.interview.graph;\n\nimport java.util.*;\n\n/**\n * Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:\n * Only one letter can be changed at a time\n * Each intermediate word must exist in the word list\n *\n * Solution -\n * Since we have to find all paths we need care about below extra stuff on top of regular BFS\n * 1) Maintain parent of every word to recreate the path\n * 2) Maintain 2 visited. First is for level and once the entire level is done then move it to visited.\n * 3) Also since we are looking result from beginWord to endWord switch them initially and go from endWord towards beginWord.\n *\n * https://leetcode.com/problems/word-ladder-ii/\n */\npublic class WordLadder {\n    public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {\n        if (wordList == null || wordList.size() == 0) {\n            return Collections.EMPTY_LIST;\n        }\n        String temp = endWord;\n        endWord = beginWord;\n        beginWord = temp;\n        Map<String, List<String>> parent = new HashMap<>();\n        Queue<String> queue1 = new LinkedList<>();\n        Set<String> visited = new HashSet<>();\n        Set<String> levelVisited = new HashSet<>();\n        List<List<String>> result = new ArrayList<>();\n        parent.put(beginWord, null);\n        queue1.offer(beginWord);\n        visited.add(beginWord);\n        boolean foundDestination = false;\n        while (!queue1.isEmpty()) {\n            while (!queue1.isEmpty()) {\n                String word = queue1.poll();\n                for (int i = 0; i < word.length(); i++) {\n                    char wordArray[] = word.toCharArray();\n                    for (char ch = 'a'; ch <= 'z'; ch++) {\n                        wordArray[i] = ch;\n                        String newWord = new String(wordArray);\n                        if (!endWord.equals(newWord) && (!wordList.contains(newWord) || visited.contains(newWord))) {\n                            continue;\n                        }\n                        List<String> parents = parent.get(newWord);\n                        if (parents == null) {\n                            parents = new ArrayList<>();\n                            parent.put(newWord, parents);\n                        }\n                        parents.add(word);\n\n                        levelVisited.add(newWord);\n                        if (endWord.equals(newWord)) {\n                            foundDestination = true;\n                            break;\n                        }\n                    }\n                }\n            }\n            if (foundDestination) {\n                break;\n            }\n            for (String word : levelVisited) {\n                queue1.offer(word);\n                visited.add(word);\n            }\n            levelVisited.clear();\n        }\n        if (!foundDestination) {\n            return Collections.EMPTY_LIST;\n        } else {\n            setParent(parent, beginWord, new ArrayList<>(), endWord, result);\n        }\n        return result;\n    }\n\n    private void setParent(Map<String, List<String>> parent, String startWord, List<String> path, String currentWord,\n                           List<List<String>> result) {\n        path.add(currentWord);\n        if (startWord.equals(currentWord)) {\n            result.add(new ArrayList<>(path));\n            path.remove(path.size() - 1);\n            return;\n        }\n        for (String p :  parent.get(currentWord)) {\n            setParent(parent, startWord, path, p, result);\n        }\n        path.remove(path.size() - 1);\n    }\n\n    public static void main(String args[]) {\n        String[] wordList = {\"hot\",\"dot\",\"dog\",\"lot\",\"log\"};\n        Set<String> wordSet = new HashSet<>();\n        wordSet.addAll(Arrays.asList(wordList));\n        WordLadder wl = new WordLadder();\n        List<List<String>> result = wl.findLadders(\"hit\", \"cog\", wordSet);\n        System.out.print(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/AddNumberRepresentedByLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/sum-of-two-linked-lists/\n * Test case\n * Either of list is null\n * Size of list1 is greater, equal or smaller than list2\n * Add with carry in main\n * Add with carry in remaining\n */\npublic class AddNumberRepresentedByLinkList {\n\n    private int carry = 0;\n    \n    private Node addWithCarry(Node head1, Node head2){\n        if(head1 == null){\n            return null;\n        }\n        Node result = Node.newNode(0);\n        result.next = addWithCarry(head1.next, head2.next);\n        int r = head1.data + head2.data + carry;\n        result.data = r % 10;\n        carry = r / 10;\n        return result;\n    }\n    \n    private Node addRemaining(Node start, Node stop){\n        if(start != stop){\n            Node result = Node.newNode(0);\n            result.next = addRemaining(start.next , stop);\n            result.data = (start.data + carry)%10;\n            carry = (start.data + carry)/10;\n            return result;\n        }else{\n            return null;\n        }\n    }\n    \n    public Node add(Node head1, Node head2){\n        if(head1 == null || head2 == null){\n            throw new IllegalArgumentException();\n        }\n        LinkList ll = new LinkList();\n        int size1 = ll.size(head1);\n        int size2 = ll.size(head2);\n        Node larger = null;\n        Node smaller = null;\n        if(size1 >= size2){\n            larger = head1;\n            smaller = head2;\n        }else{\n            larger = head2;\n            smaller = head1;\n        }\n        int diff = Math.abs(size1 - size2);\n        Node largerStart = larger;\n        while(diff > 0){\n            largerStart = largerStart.next;\n            diff--;\n        }\n        Node result = addWithCarry(largerStart,smaller);\n        Node result1 = addRemaining(larger,largerStart);\n        if(carry != 0){\n            Node top = Node.newNode(carry);\n            result1 = ll.addAtFront(top, result1);\n        }\n        if(result1 != null){\n            Node tail = result1;\n            while(tail.next != null){\n                tail = tail.next;\n            }\n            tail.next = result;\n            return result1;\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(9, head);\n        head = ll.addNode(4, head);\n    \n        Node head1 = null;\n        head1 = ll.addNode(3, head1);\n        head1 = ll.addNode(1, head1);\n        head1 = ll.addNode(2, head1);\n    \n        AddNumberRepresentedByLinkList anr = new AddNumberRepresentedByLinkList();\n        Node result = anr.add(head,head1);\n        ll.printList(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/CopyLinkListWIthArbitPointer.java",
    "content": "package com.interview.linklist;\n\n/**\n * Date 03/24/2016\n * @author Tushar Roy\n *\n * A linked list is given such that each node contains an additional random pointer which could point\n * to any node in the list or null. Return a deep copy of the list.\n *\n * Time complexity is O(n)\n * Space complexity is O(1)\n *\n * https://leetcode.com/problems/copy-list-with-random-pointer/\n */\npublic class CopyLinkListWIthArbitPointer {\n\n    static class RandomListNode {\n        int label;\n        RandomListNode next, random;\n        RandomListNode(int x) { this.label = x; }\n    }\n\n    public RandomListNode copyRandomList(RandomListNode head) {\n        if (head == null) {\n            return null;\n        }\n\n        RandomListNode current = head;\n        while (current != null) {\n            RandomListNode newNode = new RandomListNode(current.label);\n            newNode.next = current.next;\n            newNode.random = current.random;\n            current.next = newNode;\n            current = newNode.next;\n        }\n\n        current = head;\n        while (current != null) {\n            RandomListNode next = current.next;\n            if (next.random != null) {\n                next.random = next.random.next;\n            }\n            current = current.next.next;\n        }\n\n        current = head;\n        RandomListNode dummy = new RandomListNode(0);\n        RandomListNode newCurrent = dummy;\n        while (current != null) {\n            newCurrent.next = current.next;\n            newCurrent = newCurrent.next;\n            current.next = current.next.next;\n            current = current.next;\n        }\n\n        return dummy.next;\n    }\n\n    public static void main(String args[]){\n\n        CopyLinkListWIthArbitPointer cll = new CopyLinkListWIthArbitPointer();\n\n        RandomListNode randomListNode = new RandomListNode(-1);\n        RandomListNode randomListNode1 = new RandomListNode(4);\n        RandomListNode randomListNode2 = new RandomListNode(8);\n        RandomListNode randomListNode3 = new RandomListNode(-3);\n        RandomListNode randomListNode4 = new RandomListNode(7);\n        randomListNode.next = randomListNode1;\n        randomListNode1.next = randomListNode2;\n        randomListNode2.next = randomListNode3;\n        randomListNode3.next = randomListNode4;\n\n        randomListNode.random = randomListNode1;\n        randomListNode2.random = randomListNode3;\n        randomListNode1.random = randomListNode;\n        cll.copyRandomList(randomListNode);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/DeleteDuplicateNodes.java",
    "content": "package com.interview.linklist;\n\n/**\n * Date 04/17/2016\n * @author Tushar Roy\n * \n * Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct\n * numbers from the original list.\n *\n * For example,\n * Given 1->2->3->3->4->4->5, return 1->2->5.\n * Given 1->1->1->2->3, return 2->3.\n *\n * https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/\n */\npublic class DeleteDuplicateNodes {\n    public Node deleteDuplicates(Node head) {\n        Node dummyNode = new Node();\n        dummyNode.next = head;\n        Node current = head;\n        Node prev = dummyNode;\n        while (current != null) {\n            while(current.next != null && current.data == current.next.data) {\n                current = current.next;\n            }\n            if (prev.next == current) {\n                prev = current;\n            } else {\n                prev.next = current.next;\n            }\n            current = current.next;\n        }\n        return dummyNode.next;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/DeleteNAfterMNodes.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/delete-n-nodes-after-m-nodes-of-a-linked-list/\n * Test cases:\n * neg value of m and/or n - not allowed\n * 0 value of n and/or m - not allowed\n * even n and m\n * odd n and m\n * odd size of the list\n * even size of the list\n */\npublic class DeleteNAfterMNodes {\n\n    public void deleteNAfterMNodes(Node head,int m, int n){\n        if(head == null){\n            return;\n        }\n        while(head != null){\n            int i = 0;\n            while(head != null && i < m-1){\n                head = head.next;\n                i++;\n            }\n            if(head == null){\n                break;\n            }\n            Node temp = head.next;\n            i=0;\n            while(temp != null && i < n){\n                temp = temp.next;\n                i++;\n            }\n            head.next = temp;\n            head = temp;\n        }\n    }\n    public static void main(String args[]){\n        DeleteNAfterMNodes daf = new DeleteNAfterMNodes();\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        daf.deleteNAfterMNodes(head, 3, 2);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/DeleteNodeWithGreaterValueOnRight.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/delete-nodes-which-have-a-greater-value-on-right-side/\n * Test cases\n * Sorted list\n * reverse sorted list\n * 0 1 or more nodes in the list\n */\npublic class DeleteNodeWithGreaterValueOnRight {\n\n    private int maxFound = Integer.MIN_VALUE;\n    \n    public Node deleteNodes(Node head){\n        if(head == null){\n            return null;\n        }\n        Node nextNode = deleteNodes(head.next);\n        if(head.data > maxFound){\n            maxFound = head.data;\n        }\n        if(maxFound > head.data){\n            return nextNode;\n        }\n        head.next = nextNode;\n        return head;\n    }\n    \n    public static void main(String args[]){\n        DeleteNodeWithGreaterValueOnRight dng = new DeleteNodeWithGreaterValueOnRight();\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(12, head);\n        head = ll.addNode(15, head);\n        head = ll.addNode(10, head);\n        head = ll.addNode(11, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = dng.deleteNodes(head);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/DoubleLinkList.java",
    "content": "package com.interview.linklist;\n\npublic class DoubleLinkList {\n\n    public Node addNode(Node head,int data){\n        if(head == null){\n            head = Node.newNode(data);\n            return head;\n        }\n        Node newNode = Node.newNode(data);\n        Node current = head;\n        while(current.next != null){\n            current = current.next;\n        }\n        current.next = newNode;\n        newNode.before = current;\n        return head;\n    }\n    \n    public Node addAtFront(Node head, int data){\n        Node newNode = Node.newNode(data);\n        if(head == null){\n            return newNode;\n        }\n        newNode.next = head;\n        head.before = newNode;\n        return newNode;\n    }\n    \n    public void print(Node head){\n        while(head != null){\n            System.out.print(head.data + \" \");\n            head = head.next;\n        }\n    }\n    \n\n    public void printFrontBack(Node head){\n        Node prev = null;\n        while(head != null){\n            System.out.print(head.data + \" \");\n            prev = head;\n            head = head.next;\n        }\n        System.out.println();\n        while(prev != null){\n            System.out.print(prev.data + \" \");\n            prev = prev.before;\n        }\n    }\n    \n    public Node find(Node head, int data){\n        while(head != null){\n            if(head.data == data){\n                return head;\n            }\n            head = head.next;\n        }\n        return null;\n    }\n    \n    public static void main(String args[]){\n        DoubleLinkList dll = new DoubleLinkList();\n        Node head = null;\n        head = dll.addNode(head,1);\n        head = dll.addNode(head,2);\n        head = dll.addNode(head,3);\n        head = dll.addNode(head,4);\n        head = dll.addNode(head,5);\n        dll.print(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/Flatten2DList.java",
    "content": "package com.interview.linklist;\n\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * Date 10/10/2016\n * @author Tushar Roy\n *\n * Implement an iterator to flatten a 2d vector.\n *\n * https://leetcode.com/problems/flatten-2d-vector/\n *\n */\npublic class Flatten2DList implements Iterator<Integer> {\n    private List<List<Integer>> vector;\n    private int currentList = 0;\n    private int currentPos = 0;\n    public Flatten2DList(List<List<Integer>> vec2d) {\n        vector = vec2d;\n    }\n\n    @Override\n    public Integer next() {\n        if (!hasNext()) {\n            throw new IllegalArgumentException();\n        }\n        int data = vector.get(currentList).get(currentPos);\n        currentPos++;\n        if (currentPos == vector.get(currentList).size()) {\n            currentPos = 0;\n            currentList++;\n        }\n        return data;\n    }\n\n    @Override\n    public boolean hasNext() {\n        while (currentList < vector.size() && vector.get(currentList).size() == 0) {\n            currentList++;\n        }\n        return currentList < vector.size();\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/FlattenLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/flatten-a-linked-list-with-next-and-child-pointers/\n * Test case\n * 0 node in the list\n * 1 node in the list\n * All nodes with child\n * No nodes with child\n */\npublic class FlattenLinkList {\n\n    public void flatten(Node head) {\n        Node tail = getTail(head);\n        while (head != null) {\n            if (head.child != null) {\n                tail.next = head.child;\n                tail = getTail(tail.next);\n                head.child = null;\n            }\n            head = head.next;\n        }\n    }\n\n    private Node getTail(Node head) {\n        if (head == null) {\n            return null;\n        }\n        while (head.next != null) {\n            head = head.next;\n        }\n        return head;\n    }\n\n    public static void main(String args[]) {\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(10, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(12, head);\n        head = ll.addNode(7, head);\n        head = ll.addNode(11, head);\n\n        Node head1 = null;\n        head1 = ll.addNode(4, head1);\n        head1 = ll.addNode(20, head1);\n        head1 = ll.addNode(13, head1);\n\n        Node head2 = null;\n        head2 = ll.addNode(2, head2);\n        head2 = ll.addNode(8, head2);\n\n        Node head4 = null;\n        head4 = ll.addNode(17, head4);\n        head4 = ll.addNode(6, head4);\n\n        Node head5 = null;\n        head5 = ll.addNode(9, head5);\n        head5 = ll.addNode(8, head5);\n        head5 = ll.addNode(15, head5);\n\n        Node f1 = ll.find(head, 10);\n        f1.child = head1;\n\n        f1 = ll.find(head, 7);\n        f1.child = head4;\n\n        f1 = ll.find(head4, 17);\n        f1.child = head5;\n\n        f1 = ll.find(head1, 20);\n        f1.child = head2;\n        \n        FlattenLinkList fll = new FlattenLinkList();\n        fll.flatten(head);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/InsertionSortLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/given-a-linked-list-which-is-sorted-how-will-you-insert-in-sorted-way/\n * Test cases:\n * 0 nodes\n * 1 nodes \n * 2 or more nodes\n * already sorted\n * reverse sorted\n * negative positive numbers \n */\npublic class InsertionSortLinkList {\n\n    private Node insert(Node head,Node curr){\n        if(head == null){\n            return curr;\n        }\n        Node prev = null;\n        Node start = head;\n        while(start != null && curr.data >= start.data){\n            prev = start;\n            start = start.next;\n        }\n        if(prev == null){\n            curr.next = head;\n            head = curr;\n        }else{\n            prev.next = curr;\n            curr.next = start;\n        }\n        return head;\n    }\n    \n    public Node sort(Node head){\n        Node result = null;\n        Node curr = head;\n        Node prevCurr = null;\n        while(curr != null){\n            prevCurr = curr;\n            curr = curr.next;\n            prevCurr.next = null;\n            result = insert(result,prevCurr);\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(11, head);\n        head = ll.addNode(12, head);\n        head = ll.addNode(-3, head);\n        head = ll.addNode(45, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(101, head);\n    \n        InsertionSortLinkList isll = new InsertionSortLinkList();\n        head = isll.sort(head);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/LRUCache.java",
    "content": "package com.interview.linklist;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * http://www.geeksforgeeks.org/implement-lru-cache/\n * Test cases:\n * MAX_SIZE greater than 1\n * Delete when empty\n * Delete when full\n * Enter data more than max\n * Delete till cache is empty\n */\npublic class LRUCache {\n\n    private Node head;\n    private Node tail;\n    private Map<Integer,Node> map = new HashMap<Integer,Node>();\n    private int MAX_SIZE = 5;\n    private int size = 0;\n    public LRUCache(int size){\n        MAX_SIZE = size;\n    }\n    \n    public void used(int data){\n        if(containsInCache(data)){\n            Node node = map.get(data);\n            if(node != head){\n                deleteFromCache(data);\n                node.next = head;\n                head.before = node;\n                head = node;\n                map.put(data, node);\n            }\n        }else{\n            addIntoCache(data);\n        }\n    }\n    \n    public void addIntoCache(int data){\n        size++;\n        if(head == null){\n            head = Node.newNode(data);\n            tail = head;\n            return;\n        }\n        if(size > MAX_SIZE){\n            tail = tail.before;\n            Node next = tail.next;\n            tail.next = null;\n            next.before = null;\n            map.remove(next.data);\n        }\n        Node newNode = Node.newNode(data);\n        newNode.next = head;\n        if(head != null){\n            head.before = newNode;\n        }\n        head = newNode;\n        map.put(data, newNode);\n        return;\n    }\n    \n    public void printCache(){\n        Node temp = head;\n        while(temp != null){\n            System.out.print(temp.data + \" \");\n            temp = temp.next;\n        }\n        System.out.println();\n    }\n    \n    public boolean containsInCache(int data)\n    {\n        return map.containsKey(data);\n    }\n    \n    public void deleteFromCache(int data){\n        Node node = map.get(data);\n        if(node == null){\n            return;\n        }\n        map.remove(data);\n        if(size == 1){\n            head = null;\n            tail = null;\n        }\n        else if(node == head){\n            head = head.next;\n            if(head != null){\n                head.before = null;\n            }\n            node.next = null;\n        }else if(node == tail){\n            tail = tail.before;\n            tail.next = null;\n        }else{\n            Node before = node.before;\n            Node next = node.next;\n            before.next = next;\n            next.before = before;\n        }\n    }\n\n    public static void main(String args[]){\n        LRUCache lruCache = new LRUCache(5);\n        lruCache.used(4);\n        \n        lruCache.used(5);\n        lruCache.printCache();\n        lruCache.used(6);\n        lruCache.printCache();\n        lruCache.used(5);\n        lruCache.printCache();\n        lruCache.used(9);\n        lruCache.printCache();\n        lruCache.used(10);\n        lruCache.printCache();\n        lruCache.used(11);\n        lruCache.printCache();\n        lruCache.used(16);\n        lruCache.printCache();\n        lruCache.used(10);\n        lruCache.printCache();\n        lruCache.deleteFromCache(10);\n        lruCache.printCache();\n        lruCache.deleteFromCache(9);\n        lruCache.printCache();\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/LRUCacheLeetCode.java",
    "content": "package com.interview.linklist;\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n/**\n * Date 02/11/2016\n * @author Tushar Roy\n *\n * Reference\n * https://leetcode.com/problems/lru-cache/\n */\npublic class LRUCacheLeetCode {\n\n    private LinkedHashMap<Integer,Integer> map;\n    private int capacity;\n    public LRUCacheLeetCode(int capacity) {\n        this.capacity = capacity;\n        this.map = new MyMap(capacity);\n    }\n\n    public int get(int key) {\n        Integer val = map.get(key);\n        return val == null ? -1 : val;\n    }\n\n    public void set(int key, int value) {\n        map.put(key, value);\n    }\n\n    class MyMap extends LinkedHashMap<Integer, Integer> {\n        int capacity;\n        MyMap(int capacity) {\n            super(capacity, 0.75f, true);\n            this.capacity = capacity;\n        }\n        @Override\n        protected boolean removeEldestEntry(Map.Entry<Integer, Integer> entry) {\n            return size() > capacity;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/LinkList.java",
    "content": "package com.interview.linklist;\n\nclass NodeRef{\n    Node node;\n    public void next(){\n        node = node.next;\n    }\n}\n\nclass Node{\n    int data;\n    Node next;\n    Node before;\n    Node child;\n    Object obj;\n    \n    public static Node newNode(int data, Object... obj){\n        Node n = new Node();\n        n.data = data;\n        n.next = null;\n        n.before = null;\n        if(obj.length > 0)\n        {    \n            n.obj = obj[0];\n        }\n        return n;\n    }\n}\n\npublic class LinkList {\n    \n    public Node addNode(int data, Node head, Object... obj){\n        Node temp = head;\n        Node n = null;\n        if(obj.length > 0){\n            n = Node.newNode(data, obj[0]);\n        }else{\n            n = Node.newNode(data);\n        }\n        if(head == null){\n            return n;\n        }\n        \n        while(head.next != null){\n            head = head.next;\n        }\n        \n        head.next = n;\n        return temp;\n    }\n    \n    public Node addAtFront(Node node, Node head){\n        if(head == null){\n            return node;\n        }\n        node.next = head;\n        return node;\n    }\n    \n    public Node reverse(Node head){\n        Node front = null;\n        Node middle = head;\n        Node end = null;\n        while(middle != null){\n            end = middle.next;\n            middle.next = front;\n            front = middle;\n            middle = end;\n        }\n        return front;\n    }\n\n    public Node reverseRecursiveEasy(Node head){\n        if(head == null || head.next == null){\n            return head;\n        }\n        \n        Node reversedList = reverseRecursiveEasy(head.next);\n        head.next.next = head;\n        head.next = null;\n        return reversedList;\n    }\n    \n    public void reverseRecursive(NodeRef headRef){\n        if(headRef.node == null){\n            return;\n        }\n        Node first = headRef.node;\n        Node last = headRef.node.next;\n        if(last == null){\n            return;\n        }\n        NodeRef lastHeadRef = new NodeRef();\n        lastHeadRef.node = last;\n        reverseRecursive(lastHeadRef);\n        first.next.next = first;\n        first.next = null;\n        headRef.node = lastHeadRef.node;\n    }\n    \n    public Node addAtFront(int data, Node head){\n        Node node = Node.newNode(data);\n        return addAtFront(node,head);\n    }\n    \n    public void printList(Node head){\n        while(head != null){\n            System.out.println(head.data);\n            head = head.next;\n        }\n    }\n    \n    public Node find(Node head, int data){\n        while(head != null){\n            if(head.data == data){\n                return head;\n            }\n            head = head.next;\n        }\n        return null;\n    }\n    \n    \n    public int size(Node head){\n        int size =0;\n        while(head != null){\n            size++;\n            head = head.next;\n        }\n        return size;\n    }\n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        ll.printList(head);\n        \n    //  NodeRef headRef = new NodeRef();\n    //  headRef.node = head;\n    //  ll.reverseRecursive(headRef);\n    //  head = headRef.node;\n    //  ll.printList(head);\n        System.out.println();\n        head = ll.reverseRecursiveEasy(head);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/LinkListIsPalindrome.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/function-to-check-if-a-singly-linked-list-is-palindrome/ \n * Test cases:\n * odd number of nodes\n * even number of nodes\n * 0 1 or more nodes\n * palindrome list\n * non palindrom list\n */\npublic class LinkListIsPalindrome {\n\n    public boolean isPalindrome(NodeRef head,Node end){\n        if(end == null){\n            return true;\n        }\n        boolean r = isPalindrome(head,end.next);\n        r = r && head.node.data == end.data;\n        head.next();\n        return r;\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(1, head);\n        NodeRef nodeRef = new NodeRef();\n        nodeRef.node = head;\n        LinkListIsPalindrome llp = new LinkListIsPalindrome();\n        System.out.println(llp.isPalindrome(nodeRef, head));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/LinkListToCompleteBinaryTree.java",
    "content": "package com.interview.linklist;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\n\n/**\n * http://www.geeksforgeeks.org/given-linked-list-representation-of-complete-tree-convert-it-to-linked-representation/\n * Test cases\n * Zero, One or more nodes in link list\n */\npublic class LinkListToCompleteBinaryTree {\n\n    public void convert(Node head){\n        if(head == null){\n            return;\n        }\n        \n        Queue<Node> queue = new LinkedList<>();\n        queue.add(head);\n        head = head.next;\n        while(head != null){\n            Node top = queue.poll();\n            top.before = head;\n            head = head.next;\n            if(head != null){\n                top.next = head;\n                head = head.next;\n                //null the next of child before putting them into queue\n                top.before.next = null;\n                top.next.next = null;\n                queue.add(top.before);\n                queue.add(top.next);\n            }else{\n                break;\n            }\n        }\n     }\n    \n    public void inorder(Node head){\n        if(head == null){\n            return;\n        }\n        inorder(head.before);\n        System.out.print(head.data + \" \");\n        inorder(head.next);\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(10, head);\n        head = ll.addNode(12, head);\n        head = ll.addNode(15, head);\n        head = ll.addNode(25, head);\n        head = ll.addNode(30, head);\n        head = ll.addNode(36, head);\n        head = ll.addNode(40, head);\n        head = ll.addNode(45, head);\n        \n        LinkListToCompleteBinaryTree llct = new LinkListToCompleteBinaryTree();\n        llct.convert(head);\n        llct.inorder(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/LoopInLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * Date 04/17/2016\n * @author tusroy\n *\n * Given a linked list, determine if it has a cycle in it.\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * https://leetcode.com/problems/linked-list-cycle/\n */\npublic class LoopInLinkList {\n\n    public boolean hasCycle(Node head){\n        if (head == null) {\n            return false;\n        }\n        Node slow = head;\n        Node fast = head.next;\n        while (fast != null) {\n            if (slow == fast || fast.next == slow) {\n                return true;\n            }\n            slow = slow.next;\n            if (fast.next != null) {\n                fast = fast.next.next;\n            } else {\n                break;\n            }\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        head = ll.addNode(7, head);\n        head = ll.addNode(8, head);\n        Node node1 = ll.find(head, 8);\n        Node node2 = ll.find(head, 4);\n        node1.next = node2;\n        LoopInLinkList lll = new LoopInLinkList();\n        System.out.println(lll.hasCycle(head));\n        \n        node2.next = null;\n        System.out.println(lll.hasCycle(head));\n    \n        node1 = ll.find(head, 3);\n        node2.next = node1;\n        System.out.println(lll.hasCycle(head));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/MergeForLargestSum.java",
    "content": "package com.interview.linklist;\n\n/*\n * http://www.geeksforgeeks.org/maximum-sum-linked-list-two-sorted-linked-lists-common-nodes/\n * Test cases\n * Test that chains never meet\n * Test that chain meets only once\n * Test that chain meets multipe times\n * Test that one chain ends where it meets chain 2\n */\npublic class MergeForLargestSum {\n\n    Node maxChain(Node head1, Node head2){\n        if(head1 == null){\n            return head2;\n        }\n        if(head2 == null){\n            return head1;\n        }\n        Node curr1 = head1;\n        Node curr2 = head2;\n        int sum1 = 0;\n        int sum2 = 0;\n        Node result = null;\n        Node prev = null;\n        while(curr1!= null && curr2 != null){\n            if(curr1.data == curr2.data){\n                sum1 += curr1.data;\n                sum2 += curr2.data;\n                if(sum1 <= sum2){\n                    if(result == null){\n                        result = head2;\n                        prev = curr2;\n                    }else{\n                        prev.next = head2.next;\n                        prev = curr2;\n                    }\n                }else{\n                    if(result == null){\n                        result = head1;\n                        prev = curr1;\n                    }else{\n                        prev.next = head1.next;\n                        prev = curr1;\n                    }\n                }\n                head1 = curr1;\n                head2 = curr2;\n                sum1 = 0;\n                sum2 = 0;\n                curr1 = curr1.next;\n                curr2 = curr2.next;\n            }\n            else if(curr1.data < curr2.data){\n                sum1 += curr1.data;\n                curr1 = curr1.next;\n            }\n            else{\n                sum2 += curr2.data;\n                curr2 = curr2.next;\n            }\n        }\n        while(curr1 != null){\n            sum1+= curr1.data;\n            curr1 = curr1.next;\n        }\n        while(curr2 != null){\n            sum2 += curr2.data;\n            curr2 = curr2.next;\n        }\n        if(result != null){\n        if(sum1 <= sum2){\n            prev.next = head2.next;\n        }else{\n            prev.next = head1.next;\n        }\n        }else{\n            if(sum1 <= sum2){\n                result = head2;\n            }else{\n                result = head1;\n            }\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head1 = null;\n        head1 = ll.addNode(1, head1);\n        head1 = ll.addNode(3, head1);\n        head1 = ll.addNode(30, head1);\n        head1 = ll.addNode(90, head1);\n        head1 = ll.addNode(120, head1);\n        head1 = ll.addNode(240, head1);\n        head1 = ll.addNode(243, head1);\n        head1 = ll.addNode(251, head1);\n        head1 = ll.addNode(511, head1);\n        Node head2 = null;\n        head2 = ll.addNode(0, head2);\n        head2 = ll.addNode(3, head2);\n        head2 = ll.addNode(12, head2);\n        head2 = ll.addNode(32, head2);\n        head2 = ll.addNode(90, head2);\n        head2 = ll.addNode(125, head2);\n        head2 = ll.addNode(240, head2);\n        head2 = ll.addNode(249, head2);\n        head2 = ll.addNode(251, head2);\n        head2 = ll.addNode(260, head2);\n        \n        MergeForLargestSum mls = new MergeForLargestSum();\n        Node result = mls.maxChain(head1, head2);\n        ll.printList(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/MergeSortLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/merge-sort-for-linked-list/\n * Test cases\n * 0 nodes\n * 1 nodes\n * 2 nodes\n * 3 nodes\n * fully sorted\n * reverse sorted\n */\npublic class MergeSortLinkList {\n\n    public Node sort(Node head, boolean isAscending){\n\n        if(head == null || head.next == null){\n            return head;\n        }\n        Node head1 = frontBackSplit(head);\n        head = sort(head,isAscending);\n        head1 = sort(head1,isAscending);\n        return sortedMerge(head, head1, isAscending);\n    }\n    \n    private Node sortedMerge(Node head1, Node head2, boolean isAscending){\n        if(head1 == null){\n            return head2;\n        }\n        if(head2 == null){\n            return head1;\n        }\n        if(isAscending){\n            if(head1.data <= head2.data){\n                head1.next = sortedMerge(head1.next, head2, isAscending);\n                return head1;\n            }else{\n                head2.next = sortedMerge(head1,head2.next, isAscending);\n                return head2;\n            }\n        }else{\n            if(head1.data >= head2.data){\n                head1.next = sortedMerge(head1.next, head2, isAscending);\n                return head1;\n            }else{\n                head2.next = sortedMerge(head1,head2.next, isAscending);\n                return head2;\n            }\n        }\n    }\n    \n    private Node frontBackSplit(Node head){\n        if(head == null){\n            return null;\n        }\n        Node slow = head;\n        Node fast = head.next;\n        while(fast != null && fast.next != null){\n            slow = slow.next;\n            fast = fast.next.next;\n        }\n        Node newHead = slow.next;\n        slow.next = null;\n        return newHead;\n    }\n    \n    public static void main(String args[]){\n        MergeSortLinkList msll = new MergeSortLinkList();\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(11, head);\n        head = ll.addNode(12, head);\n        head = ll.addNode(-3, head);\n        head = ll.addNode(45, head);\n        head = ll.addNode(5, head);\n        head = msll.sort(head, false);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/MiddleElementOfLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * Find middle element in linklist.\n * Use two pointer approach.\n * Test cases\n * 0,1,2,3,4 and so on nodes\n * @author tusroy\n *\n */\npublic class MiddleElementOfLinkList {\n\n    public int middle(Node head){\n        if(head == null || head.next == null){\n            return head.data;\n        }\n        \n        Node slow = head;\n        Node fast = head.next;\n        while(fast != null && fast.next != null){\n            slow = slow.next;\n            fast = fast.next.next;\n        }\n        return slow.data;\n    }\n    \n    public static void main(String args[]){\n        MiddleElementOfLinkList mle = new MiddleElementOfLinkList();\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        System.out.println(mle.middle(head));\n        head = ll.addNode(2, head);\n        System.out.println(mle.middle(head));\n        head = ll.addNode(3, head);\n        System.out.println(mle.middle(head));\n        head = ll.addNode(4, head);\n        System.out.println(mle.middle(head));\n        head = ll.addNode(5, head);\n        System.out.println(mle.middle(head));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/MultiplyTwoNumbersLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * Multiply two numbers in form of link list\n * Idea is to multiply one number from head2 with all numbers from head1.\n * This result is stored in currentResult. Pass this currentResult and any previous result from multiplication\n * and add them\n */\npublic class MultiplyTwoNumbersLinkList {\n\n    public Node multiply(Node head1, Node head2){\n        LinkList ll = new LinkList();\n        head1 = ll.reverse(head1);\n        head2 = ll.reverse(head2);\n        DoubleLinkList dll = new DoubleLinkList();\n        Node result = null;\n        Node resultStart = null;\n        Node currentResult = null;\n        Node currentTail = null;\n        \n        while(head2 != null){\n            Node current = head1;\n            int carry = 0;\n            while(current != null){\n                int r = current.data * head2.data;\n                r += carry;\n                carry = r/10;\n                r = r%10;\n                if(currentResult == null){\n                    currentResult = dll.addAtFront(currentResult, r);\n                    currentTail = currentResult;\n                }else{\n                    currentResult = dll.addAtFront(currentResult, r);\n                }\n                current = current.next;\n            }\n            if(carry != 0){\n                currentResult = dll.addAtFront(currentResult, carry);\n            }\n            currentResult = null;\n            if(result == null){\n                result = add(resultStart,currentTail);\n                resultStart = result;\n            }else{\n                result = add(resultStart,currentTail);\n                resultStart = resultStart.before;\n            }\n            head2 = head2.next;\n        }\n        while(result.before != null){\n            result = result.before;\n        }\n        head1 = ll.reverse(head1);\n        head2 = ll.reverse(head2);\n        return result;\n    }\n    \n    private Node add(Node result, Node currentResult){\n        if(currentResult == null){\n            return result;\n        }\n        if(result == null){\n            return currentResult;\n        }\n        \n        Node r1 = result.before;\n        Node addResult = null;\n        int carry = 0;\n        while(r1 != null && currentResult != null){\n            int r = r1.data + currentResult.data + carry;\n            Node newNode = Node.newNode(r%10);\n            if(addResult == null){\n                addResult = newNode;\n            }else{\n                addResult.before = newNode;\n                newNode.next = addResult;\n                addResult = addResult.before;\n            }\n            carry = r/10;\n            r1 = r1.before;\n            currentResult = currentResult.before;\n        }\n        while(r1 != null){\n            int r = r1.data + carry;\n            Node newNode = Node.newNode(r%10);\n            if(addResult == null){\n                addResult = newNode;\n            }else{\n                addResult.before = newNode;\n                newNode.next = addResult;\n                addResult = addResult.before;\n            }\n            carry = r/10;\n            r1 = r1.before;\n        }\n        while(currentResult != null){\n            int r = currentResult.data + carry;\n            Node newNode = Node.newNode(r%10);\n            if(addResult == null){\n                addResult = newNode;\n            }else{\n                addResult.before = newNode;\n                newNode.next = addResult;\n                addResult = addResult.before;\n            }\n            carry = r/10;\n            currentResult = currentResult.before;\n        }\n        if(carry != 0){\n            Node newNode = Node.newNode(carry);\n            addResult.before = newNode;\n            newNode.next = addResult;\n            addResult = addResult.before;\n        }\n        \n        while(addResult.next != null){\n            addResult = addResult.next;\n        }\n        addResult.next = result;\n        result.before = addResult;\n        return result;\n    }\n    \n    public static void main(String args[]){\n        MultiplyTwoNumbersLinkList mtn = new MultiplyTwoNumbersLinkList();\n        LinkList ll = new LinkList();\n        Node head1 = null;\n        head1 = ll.addNode(2, head1);\n        head1 = ll.addNode(3, head1);\n        head1 = ll.addNode(5, head1);\n        head1 = ll.addNode(0, head1);\n        head1 = ll.addNode(1, head1);\n            \n        Node head2 = null;\n        head2 = ll.addNode(5, head2);\n        head2 = ll.addNode(7, head2);\n        head2 = ll.addNode(8, head2);\n            \n        Node result = mtn.multiply(head1, head2);\n        ll.printList(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/QuickSortSingleLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/quicksort-on-singly-linked-list/\n * Test cases\n * 0 1 or more nodes\n * sorted reverse sorted nodes\n */\n\n//keep head and tail of each result since caller function needs it to \n//set complete linklist. If we do not keep tail in each recursion we will\n//have to traverse to tail of left side which can be costly operation\nclass HeadTail{\n  Node head;\n  Node tail;\n}\n\npublic class QuickSortSingleLinkList {\n\n    public Node quickSort(Node head){\n        if(head == null || head.next == null){\n            return head;\n        }\n        Node smaller = null;\n        Node larger = null;\n        Node pivot = head;\n        Node temp = head.next;\n        pivot.next = null;\n        LinkList ll = new LinkList();\n        while(temp != null){\n            Node next = temp.next;\n            temp.next = null;\n            if(temp.data < pivot.data){\n                smaller = ll.addAtFront(temp, smaller);\n            }else{\n                larger = ll.addAtFront(temp, larger);\n            }\n            temp = next;\n        }\n        \n        smaller = quickSort(smaller);\n        larger = quickSort(larger);\n        \n        Node tail1 = smaller;\n        \n        //this is costly operation which can be prevented by keeping tail.\n        while(tail1 != null && tail1.next != null){\n            tail1 = tail1.next;\n        }\n        \n        if(smaller != null){\n            tail1.next = pivot;\n            pivot.next = larger;\n            return smaller;\n        }else{\n            pivot.next = larger;\n            return pivot;\n        }\n    }\n    \n    public Node quickSortFaster(Node head){\n        HeadTail result = quickSortUtil(head);\n        return result.head;\n    }\n  \n    /**\n     * This version keeps tail of each recursion which helps us avoid going to tail in each recursion.\n     * @param head\n     * @return\n     */\n    private HeadTail quickSortUtil(Node head){\n        if(head == null || head.next == null){\n            HeadTail headTail = new HeadTail();\n            headTail.head = head;\n            headTail.tail = head;\n            return headTail;\n        }\n        LinkList ll = new LinkList();\n        Node leftHead = null;\n        Node rightHead = null;\n        \n        Node curr = head.next;\n        head.next = null;\n        Node next = null;\n        while(curr != null){\n            next = curr.next;\n            curr.next = null;\n            if(curr.data < head.data){\n                leftHead = ll.addAtFront(curr, leftHead);\n            }else{\n                rightHead = ll.addAtFront(curr, rightHead);\n            }\n            curr = next;\n        }\n        HeadTail leftSide = quickSortUtil(leftHead);\n        HeadTail rightSide = quickSortUtil(rightHead);\n        head.next= rightSide.head;\n        HeadTail result = new HeadTail();\n        result.head = head;\n        result.tail = head;\n        if(leftSide.tail != null){\n            leftSide.tail.next = head;\n            result.head = leftSide.head;\n        }\n        if(rightSide.head != null){\n            head.next = rightSide.head;\n            result.tail = rightSide.tail;\n        }\n        return result;\n    }\n\n    \n    public static void main(String args[]){\n        QuickSortSingleLinkList qss = new QuickSortSingleLinkList();\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(11, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(-1, head);\n        head = ll.addNode(50, head);\n        head = ll.addNode(13, head);\n        head = ll.addNode(-5, head);\n        head = ll.addNode(10, head);\n        head = ll.addNode(8, head);\n    \n        head = qss.quickSortFaster(head);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/RemoveDuplicatesSortedList.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/remove-duplicates-from-a-sorted-linked-list/\n * Test cases\n * All duplicates\n * No duplicates\n * Duplicates only in starting\n * Duplicates only at the end\n * 0 1 or more nodes in the list\n */\npublic class RemoveDuplicatesSortedList {\n\n    public void removeDuplicates(Node head){\n        if(head == null){\n            return;\n        }\n        Node current = head;\n        while(current != null && current.next != null){\n            if(current.data == current.next.data){\n                current.next = current.next.next;\n            }else{\n                current = current.next;\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(1, head);\n        head = ll.addNode(1, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        head = ll.addNode(6, head);\n        head = ll.addNode(6, head);\n        RemoveDuplicatesSortedList rds = new RemoveDuplicatesSortedList();\n        rds.removeDuplicates(head);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/RemoveMiddleElementsOfLineSegment.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/given-linked-list-line-segments-remove-middle-points/\n * @author tusroy\n * Test cases:\n * 0 or more nodes\n * All points are edge of line segments so nothing gets removed\n * One long line so all points in between get removed\n *\n */\n\nclass Point{\n    int x;\n    int y;\n    Point(int x, int y){\n        this.x = x;\n        this.y = y;\n    }\n}\n\npublic class RemoveMiddleElementsOfLineSegment {\n\n    public void remove(Node head){\n        if(head == null || head.next == null){\n            return;\n        }\n        Node curr = head;\n        Node next = head.next;\n        Node nextNext = head.next.next;\n        while(nextNext != null){\n            \n            Point pcurr = (Point)curr.obj;\n            Point pnext = (Point)nextNext.obj;\n            if(pcurr.x == pnext.x || pcurr.y == pnext.y){\n                curr.next = nextNext;\n                next = nextNext;\n                nextNext = nextNext.next;\n            }else{\n                curr = curr.next;\n                next = next.next;\n                nextNext = nextNext.next;\n            }\n            \n        }\n    }\n    \n    public static void main(String args[]){\n        Node head1 = null;\n      \n      LinkList ll = new LinkList();\n      head1 = ll.addNode(1, head1, new Point(0,10));\n      head1 = ll.addNode(2, head1, new Point(1,10));\n      head1 = ll.addNode(3, head1, new Point(5,10));\n      head1 = ll.addNode(4, head1, new Point(7,10));\n      head1 = ll.addNode(5, head1, new Point(7,5));\n      head1 = ll.addNode(6, head1, new Point(20,5));\n      head1 = ll.addNode(7, head1, new Point(40,5));\n      head1 = ll.addNode(8, head1, new Point(40,8));\n           \n      RemoveMiddleElementsOfLineSegment rme = new RemoveMiddleElementsOfLineSegment();\n      rme.remove(head1);\n      ll.printList(head1);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/ReorderList.java",
    "content": "package com.interview.linklist;\n\n/**\n * Given a singly linked list L: L0→L1→…→Ln-1→Ln,\n * reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…\n *\n * https://leetcode.com/problems/reorder-list/\n */\npublic class ReorderList {\n\n    public void reorderList(Node head) {\n        Node back = frontBackSplit(head);\n        back = reverse(back);\n        alternateMerge(head, back);\n\n    }\n\n    private Node alternateMerge(Node head1, Node head2) {\n        Node dummyHead = new Node();\n        Node current = dummyHead;\n        while (head1 != null && head2 != null) {\n            current.next= head1;\n            head1 = head1.next;\n            current = current.next;\n            current.next = head2;\n            head2 = head2.next;\n            current = current.next;\n        }\n        current.next = head1;\n        return dummyHead.next;\n    }\n\n    private Node reverse(Node head) {\n        if (head == null) {\n            return null;\n        }\n        Node front = null;\n        Node mid = head;\n        Node next = null;\n        while (mid != null) {\n            next = mid.next;\n            mid.next = front;\n            front = mid;\n            mid = next;\n        }\n        return front;\n    }\n\n    private Node frontBackSplit(Node head) {\n        if (head == null) {\n            return null;\n        }\n        Node slow = head;\n        head = head.next;\n        while (head != null && head.next != null) {\n            slow = slow.next;\n            head = head.next.next;\n        }\n        Node next = slow.next;\n        slow.next = null;\n        return next;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/ReverseAlternateKNodes.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/reverse-alternate-k-nodes-in-a-singly-linked-list/\n * Test case\n * k is even odd\n * number of nodes are even odd\n * k is less than or equal to 1.\n */\npublic class ReverseAlternateKNodes {\n\n    public Node reverse(Node head,int k,boolean reverse){\n        if(k <= 1){\n            return head;\n        }\n        if(head == null){\n            return null;\n        }\n        if(reverse){\n            int i =0;\n            Node front = null;\n            Node middle = head;\n            Node end = null;\n            while(middle != null && i < k){\n                end = middle.next;\n                middle.next = front;\n                front = middle;\n                middle = end;\n                i++;\n            }\n            head.next = reverse(middle,k, !reverse);\n            head = front;\n        }else{\n            int i=0;\n            Node temp = head;\n            while(i < k-1 && head != null){\n                head = head.next;\n                i++;\n            }\n            if(head != null){\n                head.next = reverse(head.next,k, !reverse);\n            }\n            head = temp;\n        }\n        return head;\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        head = ll.addNode(7, head);\n        head = ll.addNode(8, head);\n        \n        ReverseAlternateKNodes ra = new ReverseAlternateKNodes();\n        head = ra.reverse(head, 3, false);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/ReverseAlternateNodeAndAppendAtEnd.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/given-linked-list-reverse-alternate-nodes-append-end/\n * Test case\n * Even and odd number of nodes\n */\npublic class ReverseAlternateNodeAndAppendAtEnd {\n\n    public void act(Node head){\n        \n        Node result = null;\n        LinkList ll = new LinkList();\n        while(head != null && head.next != null){\n            Node temp = head.next;\n            head.next = head.next.next;\n            temp.next = null;\n            result = ll.addAtFront(temp,result);\n            if(head.next == null){\n                break;\n            }\n            head = head.next;\n        }\n        head.next = result;\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        ReverseAlternateNodeAndAppendAtEnd ran = new ReverseAlternateNodeAndAppendAtEnd();\n        ran.act(head);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/ReverseKNodes.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/pairwise-swap-elements-of-a-given-linked-list/\n * Test case\n * odd or even number of k\n * odd or even number of nodes in the list\n */\npublic class ReverseKNodes {\n\n    public Node reverse(Node head,int k){\n        if(head == null){\n            return null;\n        }\n        Node front = null;\n        Node middle = head;\n        Node end = null;\n        int i=0;\n        while(middle != null && i < k){\n            end = middle.next;\n            middle.next = front;\n            front = middle;\n            middle = end;\n            i++;\n        }\n        head.next = reverse(middle,k);\n        return front;\n    }\n    \n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        head = ll.addNode(7, head);\n        head = ll.addNode(8, head);\n        ReverseKNodes rn = new ReverseKNodes();\n        head = rn.reverse(head, 3);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/RotateList.java",
    "content": "package com.interview.linklist;\n\n/**\n * Date 10/10/2016\n * @author Tushar Roy\n * Given a list, rotate the list to the right by k places, where k is non-negative.\n *\n * Time complexity O(min(n, k))\n *\n * https://leetcode.com/problems/rotate-list/\n */\npublic class RotateList {\n    public Node rotateRight(Node head, int k) {\n        if (head == null || k == 0) {\n            return head;\n        }\n        Node slow = head;\n        Node fast = head;\n        int i = 0;\n        while (i < k && fast != null) {\n            fast = fast.next;\n            i++;\n        }\n\n        if (fast == null) {\n            return rotateRight(head, k % i);\n        }\n        while (fast.next != null) {\n            fast = fast.next;\n            slow = slow.next;\n        }\n        Node next = slow.next;\n        slow.next = null;\n        fast.next = head;\n        return next;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/ShuffleMerge.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/merge-a-linked-list-into-another-linked-list-at-alternate-positions/\n * Given two linklist shuffle merge them.\n * e.g head1 = {1->3->5}\n * head2 = {2->4}\n * result = {1->2->3->4->5}\n * Test cases\n * head1 is null and head2 is not\n * head2 is null and head1 is not\n * both are null\n * more nodes in head1 than head2\n * more nodes in head2 than head1\n * @author tusroy\n *\n */\npublic class ShuffleMerge {\n\n    public Node shuffleMergeRecursive(Node head1, Node head2){\n        if(head1 == null){\n            return head2;\n        }\n        \n        if(head2 == null){\n            return head1;\n        }\n        \n        Node recur = null;\n        recur = shuffleMergeRecursive(head1.next, head2.next);\n        \n        head1.next = head2;\n        head2.next = recur;\n        return head1;\n    }\n    /**\n    Size of list 1 is smaller, equal and larger than list 2\n    */\n    public Node shuffleMerge(Node head1, Node head2){\n        if(head1 == null || head2 == null){\n            return head2;\n        }\n        \n        Node tempHead = head1;\n        Node prev = null;\n        while(head1 != null && head2 != null){\n            Node temp = head1.next;\n            Node temp1 = head2.next;\n            head1.next = head2;\n            head2.next = temp;\n            prev = head2;\n            head2 = temp1;\n            head1 = temp;\n        }\n        if(head2 != null){\n            prev.next = head2;\n        }\n        return tempHead;\n    }\n \n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head1 = null;\n        Node head2 = null;\n        head1 = ll.addNode(1, head1);\n        head1 = ll.addNode(3, head1);\n        head1 = ll.addNode(5, head1);\n        head1 = ll.addNode(7, head1);\n        head1 = ll.addNode(9, head1);\n        head2 = ll.addNode(2, head2);\n        head2 = ll.addNode(4, head2);\n        head2 = ll.addNode(6, head2);\n        head2 = ll.addNode(8, head2);\n        head2 = ll.addNode(10, head2);\n        head2 = ll.addNode(12, head2);\n        head2 = ll.addNode(14, head2);\n        ShuffleMerge sm = new ShuffleMerge();\n        Node result = sm.shuffleMerge(head1, head2);\n        ll.printList(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/SortNearlySortedList.java",
    "content": "package com.interview.linklist;\n\n/**\n * Given a linklist which has individual sorted componenets sort the entire linst\n * e.g 1-3-6-8-4-5-10-7-9\n * Here 1,2,6,8 are sorted, 4,5,10 are sorted and 7,9 are sorted\n * Test case\n * null node\n * 1 node\n * 2 sorted nodes\n * 2 reverse sorted nodes\n * 3 reverse sorted nodes\n * 4 nodes 2 each sorted among themselves\n */\npublic class SortNearlySortedList {\n\n    public Node sort(Node head){\n        Node result = null;\n        Node start = head;\n        while(head != null && head.next != null){\n            if(head.data < head.next.data){\n                head = head.next;\n            }else{\n                Node temp = head.next;\n                head.next = null;\n                result = mergeSort(result,start);\n                head = temp;\n                start = temp;\n            }\n        }\n        result = mergeSort(result,start);\n        return result;\n    }\n    \n    private Node mergeSort(Node head1,Node head2){\n        if(head1 == null){\n            return head2;\n        }\n        if(head2 == null){\n            return head1;\n        }\n        if(head1.data <= head2.data){\n            head1.next = mergeSort(head1.next,head2);\n            return head1;\n        }else{\n            head2.next = mergeSort(head1,head2.next);\n            return head2;\n        }\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(7, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        head = ll.addNode(13, head);\n        head = ll.addNode(11, head);\n        head = ll.addNode(12, head);\n        \n        SortNearlySortedList sns = new SortNearlySortedList();\n        head = sns.sort(head);\n        ll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/SortedCircularLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/sorted-insert-for-circular-linked-list/\n * Test cases\n * Insert 2nd element smaller than head\n * Insert 2nd element larger than head\n * Insert element larger than tail\n * Insert element just before tail\n * Insert element somewhere between head and tail\n */\npublic class SortedCircularLinkList {\n\n    public Node add(Node head,int data){\n        if(head == null){\n            head = Node.newNode(data);\n            head.next = head;\n            return head;\n        }\n        Node node = Node.newNode(data);\n        Node tail = getTail(head);\n        if(node.data < head.data){\n            node.next = head;\n            tail.next = node;\n            return node;\n        }\n        Node current = head;\n        Node pre = null;\n        while(current != tail && node.data >= current.data){\n            pre = current;\n            current = current.next;\n        }\n        if(node.data < current.data){\n            node.next = current;\n            pre.next = node;\n        }\n        else{\n            node.next = tail.next;\n            tail.next = node;\n        }\n        return head;\n    }\n    \n    private Node getTail(Node head){\n        Node temp = head;\n        while(temp.next != head){\n            temp = temp.next;\n        }\n        return temp;\n    }\n    \n    public void printList(Node head){\n        if(head == null){\n            return;\n        }\n        Node current = head.next;\n        System.out.println(head.data);\n        while(current != head){\n            System.out.println(current.data);\n            current = current.next;\n        }\n    }\n    \n    public static void main(String args[]){\n        SortedCircularLinkList scll = new SortedCircularLinkList();\n        Node head = null;\n        head = scll.add(head, 10);\n        head = scll.add(head, 12);\n        head = scll.add(head, -1);\n        head = scll.add(head, -5);\n        head = scll.add(head, 11);\n        head = scll.add(head, 7);\n        \n        scll.printList(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/SortedLLToBalancedBST.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/sorted-linked-list-to-balanced-bst/\n * Test cases\n * empty list\n * 0 1 or more node lists\n */\npublic class SortedLLToBalancedBST {\n\n    public Node toBalancedBST(Node head){\n        LinkList ll = new LinkList();\n        int size = ll.size(head);\n        NodeRef headRef = new NodeRef();\n        headRef.node = head;\n        return toBalancedBST(headRef, size);\n    }\n    \n    private Node toBalancedBST(NodeRef headRef, int size){\n        if(size <= 0){\n            return null;\n        }\n        Node left = toBalancedBST(headRef,size/2);\n        Node head = headRef.node;\n        headRef.next();\n        Node right = toBalancedBST(headRef,size - size/2 -1);\n        head.before = left;\n        head.next = right;\n        return head;\n    }\n    \n    public void printTreeInOrder(Node head){\n        if(head == null){\n            return;\n        }\n        printTreeInOrder(head.before);\n        System.out.println(head.data);\n        printTreeInOrder(head.next);\n    }\n    \n    public void printTreePreOrder(Node head){\n        if(head == null){\n            return;\n        }\n        System.out.println(head.data);\n        printTreePreOrder(head.before);\n        printTreePreOrder(head.next);\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(2, head);\n        head = ll.addNode(3, head);\n        head = ll.addNode(4, head);\n        head = ll.addNode(5, head);\n        head = ll.addNode(6, head);\n        head = ll.addNode(7, head);\n        SortedLLToBalancedBST sll = new SortedLLToBalancedBST();\n        head = sll.toBalancedBST(head);\n        sll.printTreeInOrder(head);\n        sll.printTreePreOrder(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/StackWithLinkListMiddleOperation.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/design-a-stack-with-find-middle-operation/\n * Test cases:\n * Delete middle with 1,2,3 element\n * Pop with 1,2,3 elements\n * Delete or pop when empty stack\n */\npublic class StackWithLinkListMiddleOperation {\n    \n    private Node head = null;\n    private Node middle = null;\n    private int size = 0;\n    public void push(int data){\n        if(head == null){\n            head = Node.newNode(data);\n            middle = head;\n            size++;\n            return;\n        }\n        size++;\n        Node node = Node.newNode(data);\n        node.next = head;\n        head.before = node;\n        head = node;\n        if(size % 2 ==0){\n            middle = middle.before;\n        }\n    }\n    \n    public boolean hasMore(){\n        if(size > 0 ){\n            return true;\n        }else{\n            return false;\n        }\n    }\n    \n    public int size(){\n        return size;\n    }\n    \n    public int pop(){\n        if(size == 0){\n            throw new IllegalArgumentException();\n        }\n        size--;\n        if(size % 2 !=  0 || size == 0){\n            middle = middle.next;\n        }\n        int data = head.data;\n        head = head.next;\n        head.before = null;\n        return data;\n    }\n    public int top(){\n        if(size == 0){\n            throw new IllegalArgumentException();\n        }\n        return head.data;\n    }\n    public int middle(){\n        if(size == 0){\n            throw new IllegalArgumentException();\n        }\n        return middle.data;\n    }\n    public int deleteMiddle(){\n        if(size == 0){\n            throw new IllegalArgumentException();\n        }\n        size--;\n        if(middle == head){\n            int data = middle.data;\n            middle = middle.next;\n            head = head.next;\n            if(head != null){\n                head.before = null;\n            }\n            return data;\n        }\n        \n        if(size % 2 == 0){\n            int data = middle.data;\n            Node next = middle.next;\n            middle = middle.before;\n            middle.next = next;\n            if(next != null){\n                next.before = middle;\n            }\n            return data;\n        }\n        else{\n            int data = middle.data;\n            Node before = middle.before;\n            middle = middle.next;\n            middle.before = before;\n            if(before != null){\n                before.next = middle;\n            }\n            return data;\n        }\n    }\n    \n    public static void main(String args[]){\n        StackWithLinkListMiddleOperation swl = new StackWithLinkListMiddleOperation();\n        swl.push(1);\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.push(2);\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.push(3);\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.push(4);\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.push(5);\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.push(6);\n        System.out.println(swl.top() + \" \" + swl.middle());\n        System.out.println(\"\\n\\n\");\n        swl.pop();\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.deleteMiddle();\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.pop();\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.deleteMiddle();\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.pop();\n        System.out.println(swl.top() + \" \" + swl.middle());\n        swl.deleteMiddle();\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/SwapTwoNodesInDoubleLL.java",
    "content": "package com.interview.linklist;\n\n/**\n * Swap two nodes in double link list. If it swaps first node its callers responsibility to fix the head \n * Test cases\n * A right neighbor of B\n * B right neighbor of A\n * A and B not neighbors of each other\n * A or B are start or end nodes\n */\npublic class SwapTwoNodesInDoubleLL {\n\n    public void swap(Node nodeA, Node nodeB){\n        if(nodeA == null || nodeB == null){\n            throw new IllegalArgumentException();\n        }\n        //if B is right neighbor of A\n        if(nodeA.next == nodeB){\n            if(nodeA.before != null){\n                nodeA.before.next = nodeB;\n                nodeB.before = nodeA.before;\n            }else{\n                nodeB.before = null;\n            }\n            if(nodeB.next != null){\n                nodeB.next.before = nodeA;\n                nodeA.next = nodeB.next;\n            }else{\n                nodeA.next = null;\n            }\n            nodeB.next = nodeA;\n            nodeA.before = nodeB;\n        }//else if A is right neighbor of B\n        else if(nodeB.next == nodeA){\n            if(nodeB.before != null){\n                nodeB.before.next = nodeA;\n                nodeA.before = nodeB.before;\n            }else{\n                nodeA.before = null;\n            }\n            if(nodeA.next != null){\n                nodeA.next.before = nodeB;\n                nodeB.next = nodeA.next;\n            }else{\n                nodeB.next = null;\n            }\n            nodeA.next = nodeB;\n            nodeB.before = nodeA;\n        }//if A and B are not neighbors of each other\n        else{\n            if(nodeA.before != null){\n                nodeA.before.next = nodeB;\n            }\n            if(nodeA.next != null){\n                nodeA.next.before = nodeB;\n            }\n            Node next = nodeB.next;\n            Node before = nodeB.before;\n            nodeB.before = nodeA.before;\n            nodeB.next = nodeA.next;\n            \n            if(next != null){\n                next.before = nodeA;\n            }\n            if(before != null){\n                before.next = nodeA;\n            }\n            nodeA.before = before;\n            nodeA.next = next;\n        }\n    }\n    \n    public static void main(String args[]){\n        DoubleLinkList dll = new DoubleLinkList();\n        Node head = null;\n        head = dll.addNode(head,1);\n        head = dll.addNode(head,2);\n        head = dll.addNode(head,3);\n        head = dll.addNode(head,4);\n        head = dll.addNode(head,5);\n        SwapTwoNodesInDoubleLL snt = new SwapTwoNodesInDoubleLL();\n        Node nodeA = dll.find(head, 3);\n        Node nodeB = dll.find(head, 5);\n        snt.swap(nodeA, nodeB);\n        dll.printFrontBack(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/linklist/TripletToSumInLinkList.java",
    "content": "package com.interview.linklist;\n\n/**\n * http://www.geeksforgeeks.org/find-a-triplet-from-three-linked-lists-with-sum-equal-to-a-given-number/\n * Test case\n * empty list\n * list with 0 1 or more nodes\n * negative sum\n * 0 sum\n * positive sum\n */\npublic class TripletToSumInLinkList {\n\n    public void printTriplet(Node head1, Node head2, Node head3,int sum){\n        if(head1 == null || head2 == null || head3 == null){\n            return;\n        }\n        \n        MergeSortLinkList msll = new MergeSortLinkList();\n        head2 = msll.sort(head2, true);\n        head3 = msll.sort(head3, false);\n        \n        while(head1 != null){\n            int newSum = sum - head1.data;\n            Node tempHead2 = head2;\n            Node tempHead3 = head3;\n            while(tempHead2 != null && tempHead3 != null){\n                if(tempHead2.data + tempHead3.data == newSum){\n                    System.out.println(head1.data + \" \" + tempHead2.data + \" \" + tempHead3.data);\n                    break;\n                }\n                else if(tempHead2.data + tempHead3.data < newSum){\n                    tempHead2 = tempHead2.next;\n                }else{\n                    tempHead3 = tempHead3.next;\n                }\n            }\n            head1 = head1.next;\n        }\n    }\n    \n    public static void main(String args[]){\n        LinkList ll = new LinkList();\n        Node head = null;\n        head = ll.addNode(1, head);\n        head = ll.addNode(8, head);\n        head = ll.addNode(-3, head);\n        head = ll.addNode(14, head);\n        \n        Node head1 = null;\n        head1 = ll.addNode(-1, head1);\n        head1 = ll.addNode(22, head1);\n        head1 = ll.addNode(31, head1);\n        head1 = ll.addNode(11, head1);\n        \n        Node head2 = null;\n        head2 = ll.addNode(5, head2);\n        head2 = ll.addNode(7, head2);\n        head2 = ll.addNode(3, head2);\n        head2 = ll.addNode(1, head2);\n        \n        TripletToSumInLinkList tts  = new TripletToSumInLinkList();\n        tts.printTriplet(head, head1, head2, 20);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/AddingTwoSetOfIntervals.java",
    "content": "package com.interview.misc;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class AddingTwoSetOfIntervals {\n\n    public static class Pair implements Comparable<Pair>{\n        int low;\n        int high;\n        Pair(int low,int high){\n            this.low = low;\n            this.high = high;\n        }\n        @Override\n        public int compareTo(Pair o) {\n            if(this.low <= o.low){\n                return -1;\n            }else{\n                return 1;\n            }\n        }\n        \n        public String toString(){\n            return low + \" \" + high;\n        }\n    }\n    \n    public List<Pair> combineInterval(Pair[] arr1, Pair[] arr2){\n        Arrays.sort(arr1);\n        Arrays.sort(arr2);\n        \n        List<Pair> result = new ArrayList<Pair>();\n        int i=0;\n        int j=0;\n        Pair current = new Pair(Integer.MIN_VALUE,Integer.MIN_VALUE+1);\n        while(i < arr1.length && j < arr2.length){\n            if(arr1[i].low <= arr2[j].low){\n                if(arr1[i].low <= current.high){\n                    current.high = Math.max(arr1[i].high,current.high);\n                }else{\n                    current = arr1[i];\n                    result.add(current);\n                }\n                i++;\n            }\n            else{\n                if(arr2[j].low <= current.high){\n                    current.high = Math.max(arr2[j].high,current.high);\n                }else{\n                    current = arr2[j];\n                    result.add(current);\n                }\n                j++;\n            }\n        }\n        while(i < arr1.length){\n            if(arr1[i].low <= current.high){\n                current.high = Math.max(current.high,arr1[i].high);\n            }else{\n                current = arr1[i];\n                result.add(current);\n            }\n            i++;\n        }\n        while(j < arr2.length){\n            if(arr2[j].low <= current.high){\n                current.high = Math.max(current.high, arr2[j].high);\n            }else{\n                current = arr2[j];\n                result.add(current);\n            }\n            j++;\n        }\n        \n        return result;\n    }\n    \n    public static void main(String args[]){\n        Pair p1 = new Pair(1,3);\n        Pair p2 = new Pair(4,6);\n        Pair p3 = new Pair(9,15);\n        Pair p4 = new Pair(14,18);\n        \n        Pair[] arr1 = {p1,p2,p3,p4};\n        \n        Pair r1 = new Pair(2,4);\n        Pair r2 = new Pair(7,8);\n        Pair r3 = new Pair(11,13);\n        \n        Pair[] arr2 = {r1,r2,r3};\n        \n        AddingTwoSetOfIntervals ats = new AddingTwoSetOfIntervals();\n        List<Pair> rs = ats.combineInterval(arr1, arr2);\n        System.out.print(rs);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/misc/AngleBetweenHourAndMinuteHand.java",
    "content": "package com.interview.misc;\n\n/**\n * Find small angle between hour and minute hand in analog clock\n */\npublic class AngleBetweenHourAndMinuteHand {\n\n    public double angle(int hour, int min){\n        double hourAngle = (hour%12)*360/12 + ((double)min/60)*(360/12);\n        double minAngle = min*360/60;\n        \n        double angleDiff = Math.abs(hourAngle - minAngle);\n        return angleDiff < 360 - angleDiff ? angleDiff : 360 - angleDiff;\n    }\n    \n    public static void main(String args[]){\n        AngleBetweenHourAndMinuteHand abm = new AngleBetweenHourAndMinuteHand();\n        System.out.println(abm.angle(10, 15));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/BulbSwitcher.java",
    "content": "package com.interview.misc;\n\n/**\n * There are n bulbs that are initially off. You first turn on all the bulbs.\n * Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it's\n * off or turning off if it's on). For the ith round, you toggle every i bulb. For the nth round, you only\n * toggle the last bulb. Find how many bulbs are on after n rounds.\n *\n * https://leetcode.com/problems/bulb-switcher/\n */\npublic class BulbSwitcher {\n    public int bulbSwitch(int n) {\n        int count = 0;\n        while (count*count <= n) {\n            count++;\n        }\n        return count - 1;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/CandiesProblem.java",
    "content": "package com.interview.misc;\n\n/**\n * Date 2/7/16\n * @author Tushar Roy\n *\n *\n * There are N children standing in a line. Each child is assigned a rating value.\n * You are giving candies to these children subjected to the following requirements:\n * Each child must have at least one candy.\n * Children with a higher rating get more candies than their neighbors.\n * What is the minimum candies you must give?\n *\n *\n * Time complexity - O(n)\n * Space complexity - O(1)\n *\n * Reference\n * https://leetcode.com/problems/candy/\n *\n *\n */\npublic class CandiesProblem {\n\n    public int minCandies(int ratings[]) {\n\n        int pointOfChange = 0;\n        int totalCandies = 1;\n        int currentCandy = 1;\n        boolean isIndependent = true;\n        int maxHeight = 0;\n        int diff = 0;\n        for (int i = 1; i < ratings.length; i++) {\n            diff = 0;\n            //if the rating of ith guy is greater than rating of i-1 guy\n            //then give ith guy one more candy than i-1 guy.\n            if (ratings[i] > ratings[i-1]) {\n                currentCandy += 1;\n            }\n            //if rating of ith guy is same as i-1 guy then give ith guy only 1 candy\n            //because in same rating ith guy can get less candy.\n            //But also mark that if need we can keep increasing candy given to ith\n            //guy without affecting i-1 guy's candy since it can also go more than\n            //i-1th guy candy as they have same rating.\n            else if (ratings[i] == ratings[i-1]) {\n                isIndependent = true;\n                pointOfChange = i;\n                currentCandy = 1;\n            }\n            //if rating of ith guy is less than i-1th guy then\n            //give ith guy one candy. If i-1th guy has only one candy\n            //then all the guys till point of change needs to be given one more candy\n            //which is what diff takes care off.\n            //if point of change guy is independent then we are cool otherwise\n            //point of change needs to point to one less number if we reach its height.\n            else {\n                if (currentCandy == 1) {\n                    if (!isIndependent) {\n                        if (i - pointOfChange == maxHeight - 1) {\n                            pointOfChange--;\n                        }\n                    }\n                }\n                else {\n                    maxHeight = currentCandy;\n                    currentCandy = 1;\n                    isIndependent = false;\n                    pointOfChange = i;\n                }\n                diff = i - pointOfChange;\n            }\n            totalCandies += (diff + currentCandy);\n        }\n        return totalCandies;\n    }\n\n    public static void main(String args[]) {\n        int input[] = {1,3,4,3,2,1};\n        CandiesProblem cp = new CandiesProblem();\n        System.out.println(cp.minCandies(input));\n    }\n\n}\n\n"
  },
  {
    "path": "src/com/interview/misc/ContainsNumberWithinKDistance.java",
    "content": "package com.interview.misc;\n\nimport java.util.Map;\nimport java.util.TreeMap;\n\n/**\n * Date 10/26/2016\n * @author Tushar Roy\n *\n * Given an array of integers,\n * find out whether there are two distinct indices i and j in the array such that the difference\n * between nums[i] and nums[j] is at most t and the difference between i and j is at most k.\n *\n * Solution\n * Keep a tree map of num and its count. For every new number check if any number exists in map between\n * num - t and num + t. If yes than return true. If no then add this number to the tree map. Also if tree map\n * becomes of size k then drop the num[i - k] number from the tree map.\n *\n * Time complexity O(nlogk)\n *\n * https://leetcode.com/problems/contains-duplicate-iii/\n */\npublic class ContainsNumberWithinKDistance {\n\n    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {\n        if (nums.length == 0 || k == 0) {\n            return false;\n        }\n        TreeMap<Integer, Integer> map = new TreeMap<>();\n        for (int i = 0; i < nums.length; i++) {\n            int lowerEntry = nums[i] - t - 1;\n            int higherEntry = nums[i] + t + 1;\n            Map.Entry<Integer, Integer> higher = map.lowerEntry(higherEntry);\n            if (higher != null && higher.getKey() >= nums[i]) {\n                return true;\n            }\n            Map.Entry<Integer, Integer> lower = map.higherEntry(lowerEntry);\n            if (lower != null && lower.getKey() <= nums[i]) {\n                return true;\n            }\n            if (map.size() == k) {\n                map.compute(nums[i - k], (key, val) -> {\n                    if (val == 1) {\n                        return null;\n                    } else {\n                        return val - 1;\n                    }\n                });\n            }\n            map.compute(nums[i], (key, val) -> {\n                if (val == null) {\n                    return 1;\n                } else {\n                    return val + 1;\n                }\n            });\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/ConvertNumberIntoBase26.java",
    "content": "package com.interview.misc;\n\n/**\n * Given a positive integer, return its corresponding column title as appear in an Excel sheet.\n * https://leetcode.com/problems/excel-sheet-column-title/\n */\npublic class ConvertNumberIntoBase26 {\n\n    public String numberToBase26(int n) {\n        StringBuffer buff = new StringBuffer();\n        while (n > 0) {\n            n--;\n            buff.append((char)(n % 26 + 'A'));\n            n = n / 26;\n        }\n        return buff.reverse().toString();\n    }\n    \n    public int base26ToNumber(String str) {\n        int result = 0;\n        int pow = 1;\n        for(int i = str.length() - 1; i>=0; i--) {\n            char s = str.charAt(i);\n            s = (char)(s - 'A'+1);\n            result += s*pow;\n            pow *= 26;\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        ConvertNumberIntoBase26 cni = new ConvertNumberIntoBase26();\n        System.out.println(cni.numberToBase26(704));\n        System.out.println(cni.base26ToNumber(\"AAB\"));\n\n        System.out.println(cni.numberToBase26(52));\n        System.out.println(cni.base26ToNumber(\"AZ\"));\n\n        System.out.println(cni.numberToBase26(13));\n        System.out.println(cni.base26ToNumber(\"M\"));\n\n        System.out.println(cni.numberToBase26(126));\n        System.out.println(cni.base26ToNumber(\"DV\"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/CountRanges.java",
    "content": "package com.interview.misc;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.NavigableMap;\nimport java.util.TreeMap;\n\n/**\n * Date 03/03/2016\n * @author Tushar Roy\n *\n * Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.\n *\n * Time complexity O(nlogn)\n * Space complexity O(n)\n *\n * Performance can be improved by using self balancing BST which keeps the count of key and size of substree under it\n *\n * https://leetcode.com/problems/count-of-range-sum/\n */\npublic class CountRanges {\n\n    public int countRangeSum(int[] nums, int lower, int upper) {\n        TreeMap<Long, Integer> map = new TreeMap<>();\n        Map<Long, Integer> countMap = new HashMap<>();\n        long prefixSum[] = new long[nums.length + 1];\n        map.put(0l, 1);\n        countMap.put(0l, 1);\n        int count = 0;\n        for (int i = 0; i < nums.length; i++) {\n            prefixSum[i+1] = prefixSum[i] + nums[i];\n            NavigableMap<Long, Integer> rangeMap =  map.subMap(prefixSum[i+1] - upper, true, prefixSum[i+1] - lower, true);\n            if (rangeMap.size() > 0) {\n                for (int c : rangeMap.values()) {\n                    count += c;\n                }\n            }\n            if (countMap.containsKey(prefixSum[i+1])) {\n                countMap.put(prefixSum[i+1], countMap.get(prefixSum[i+1]) + 1);\n            } else {\n                countMap.put(prefixSum[i+1], 1);\n            }\n\n            map.put(prefixSum[i+1], countMap.get(prefixSum[i+1]));\n        }\n        return count;\n    }\n\n    public static void main(String args[]) {\n        CountRanges cr = new CountRanges();\n        int[] input = {0, 0};\n        System.out.print(cr.countRangeSum(input, 0, 0));\n    }\n\n}\n\n"
  },
  {
    "path": "src/com/interview/misc/DayDifferenceBetweenTwoDates.java",
    "content": "package com.interview.misc;\n\n/**\n * Number of days between two valid dates\n * The idea is to get number of days from 00/00/0000 for both the dates and find the\n * difference between them.\n */\npublic class DayDifferenceBetweenTwoDates {\n\n    private static final int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};\n    \n    public int diff(int year1,int month1, int day1,int year2, int month2,int day2){\n        int days1 = year1*365 + day1;\n        int days2 = year2*365 + day2;\n        \n        for(int i=0; i < month1-1; i++){\n            days1 = days1 + days[i];\n        }\n    \n        for(int i=0; i < month2-1; i++){\n            days2 = days2 + days[i];\n        }\n        \n        days1 = days1 + (year1-1)/4  - (year1 -1)/100 + (year1 -1 )/400; \n        days2 = days2 + (year2-1)/4  - (year2 -1)/100 + (year2 -1 )/400; \n        \n        if(isLeapYear(year1) && month1 > 2){\n            days1++;\n        }\n        if(isLeapYear(year2) && month2 > 2){\n            days2++;\n        }\n        \n        return days2 - days1;\n    }\n    \n    \n    public static void main(String args[]){\n        DayDifferenceBetweenTwoDates dd = new DayDifferenceBetweenTwoDates();\n        System.out.println(dd.diff(1945, 3, 7, 2009, 8, 31));\n    }\n    \n    public boolean isLeapYear(int year){\n        if(year % 400 == 0){\n            return true;\n        }\n        if(year % 4 == 0 && year % 100 != 0){\n            return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/DifferenceBetweenTwoTime.java",
    "content": "package com.interview.misc;\n\n/**\n * Given two times in four digits number e.g 10:10 is 1010 find difference between them\n * Test cases\n * Time 1 better be less than equal to time 2\n * First 2 digits better be between 0 and 23\n * Last 2 digits of number better be between 0 to 59\n */\npublic class DifferenceBetweenTwoTime {\n\n    public int diff(int time1, int time2){\n        if(time2 < time1){\n            throw new IllegalArgumentException();\n        }\n        \n        int hourDiff = time2/100 - time1/100 -1;\n        int minDiff = time2%100 + (60 - time1%100);\n        if(minDiff >= 60){\n            hourDiff++;\n            minDiff = minDiff - 60;\n        }\n        return hourDiff*100 + minDiff;\n    }\n    \n    public static void main(String args[]){\n        DifferenceBetweenTwoTime dbtt = new DifferenceBetweenTwoTime();\n        int time = dbtt.diff(1400, 1645);\n        System.out.println(time);\n        time = dbtt.diff(1223, 1246);\n        System.out.println(time);\n        time = dbtt.diff(1500, 1620);\n        System.out.println(time);\n        time = dbtt.diff(344, 936);\n        System.out.println(time);\n        time = dbtt.diff(1000, 1234);\n        System.out.println(time);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/FindingCelebrity.java",
    "content": "package com.interview.misc;\n\n/**\n * Find the Celebrity\n * https://leetcode.com/problems/find-the-celebrity/\n */\nclass Relation {\n    boolean knows(int a, int b) {\n        return false;\n    }\n}\n\npublic class FindingCelebrity extends Relation {\n\n    public int findCelebrity(int n) {\n        int celebrity = 0;\n        for (int i = 1; i < n; i++) {\n            if (knows(celebrity, i)) {\n                celebrity = i;\n            }\n        }\n        for (int i = 0; i < n; i++) {\n            if (i == celebrity) {\n                continue;\n            }\n            if (knows(celebrity, i) || !knows(i, celebrity)) {\n                return -1;\n            }\n        }\n        return celebrity;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/FloatPointConversion.java",
    "content": "package com.interview.misc;\n\nimport java.util.StringTokenizer;\n\n/**\n * http://www.careercup.com/question?id=4901629824335872\n * e.g\n * -99.01E-2 -> -.9901\n * 845.67E2  -> 84567.0 \n */\npublic class FloatPointConversion {\n    \n    public double convert(String input){\n        boolean isNeg = false;\n        if(input.startsWith(\"-\")){\n            isNeg = true;\n            input = input.substring(1);\n        }\n        StringTokenizer strtk = new StringTokenizer(input,\"E\");\n        String number = strtk.nextToken();\n        String power = strtk.nextToken();\n        double dNumber = toDouble(number);\n        double dPower = toDouble(power);\n        double pow = Math.pow(10, dPower);\n        double result = dNumber * pow;\n        return isNeg ? result * -1 : result;\n    }\n    \n    private double toDouble(String number){\n        boolean isNeg = false;\n        if(number.startsWith(\"-\")){\n            isNeg = true;\n            number = number.substring(1);\n        }\n        int result = 0;\n        int pow = 1;\n        boolean foundDot = false;\n        for(char ch : number.toCharArray()){\n            if(ch == '.'){\n                foundDot = true;\n                continue;\n            }\n            if(foundDot){\n                pow = pow*10;\n            }\n            result *= 10;\n            result += (ch - '0');\n        }\n        \n        double doubleResult = (result*1.0)/pow;\n        \n        return isNeg ? doubleResult*-1 : doubleResult;\n    }\n    \n    public static void main(String args[]){\n        FloatPointConversion fpc = new FloatPointConversion();\n        System.out.println(fpc.convert(\"-99.01E-2\"));\n        System.out.println(fpc.convert(\"845.67E2\"));\n        System.out.println(fpc.convert(\"99.01E-1\"));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/misc/FourPointsFormSquare.java",
    "content": "package com.interview.misc;\n\nclass Cordinate{\n    int x;\n    int y;\n}\n\n/**\n * Given four points in any order determine if they form a square\n * Test cases\n * Less than or more than 4 points in input\n * Points could be in any quadrants e.it neg and pos allowed\n */\npublic class FourPointsFormSquare {\n\n    public boolean isSquare(Cordinate[] cordinates){\n        Cordinate startPoint = cordinates[0];\n        int a1 = distanceSquare(startPoint, cordinates[1]);\n        int a2 = distanceSquare(startPoint, cordinates[2]);\n        int a3 = distanceSquare(startPoint, cordinates[3]);\n        \n        \n        if(a1 == a2){ //then 0,3 is diagonal\n            return compare(cordinates[3],cordinates[1],cordinates[2],a1,a3);\n        }else if(a1 == a3){\n            return compare(cordinates[2],cordinates[1],cordinates[3],a1,a2);\n        }else if(a2 == a3){\n            return compare(cordinates[1],cordinates[2],cordinates[3],a2,a1);\n        }else{\n            return false;\n        }\n    }\n    \n    private boolean compare(Cordinate startPoint, Cordinate point1, Cordinate point2,int len, int diag){\n        if(2*len != diag){\n            return false;\n        }\n        int a1 = distanceSquare(startPoint,point1);\n        int a2 = distanceSquare(startPoint,point2);\n        if(a1 != len || a2 != len){\n            return false;\n        }\n        return true;\n    }\n    \n    private int distanceSquare(Cordinate c1, Cordinate c2){\n        return (int)(Math.pow(Math.abs(c1.x - c2.x) ,2) +\n                Math.pow(Math.abs(c1.y-c2.y), 2));\n    }\n    \n    public static void main(String args[]){\n        FourPointsFormSquare fpf = new FourPointsFormSquare();\n        Cordinate c1 = new Cordinate();\n        c1.x = 2;\n        c1.y = 2;\n        Cordinate c2 = new Cordinate();\n        c2.x = 6;\n        c2.y = 2;\n        Cordinate c3 = new Cordinate();\n        c3.x = 2;\n        c3.y = -2;\n        Cordinate c4 = new Cordinate();\n        c4.x = 6;\n        c4.y = -2;\n        Cordinate[] c = new Cordinate[4];\n        c[0] = c1;\n        c[1] = c2;\n        c[2] = c3;\n        c[3] = c4;\n        System.out.println(fpf.isSquare(c));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/GetKthPermutation.java",
    "content": "package com.interview.misc;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * https://leetcode.com/problems/permutation-sequence/\n */\npublic class GetKthPermutation {\n\n    public String getPermutation(int n, int k) {\n        List<Integer> unused = new ArrayList<>();\n        for (int i = 1; i <= n; i++) {\n            unused.add(i);\n        }\n        StringBuffer result = new StringBuffer();\n        int fac = factorial(n);\n        int d = n;\n        while (n > 1) {\n            fac = fac/d;\n            d--;\n            int index = (int)Math.ceil((double)k/fac);\n            result.append(unused.get(index - 1));\n            unused.remove(index - 1);\n            n--;\n            k = k - fac*(index - 1);\n        }\n        if (n == 0) {\n            for (int i = unused.size() - 1; i >= 0; i--) {\n                result.append(unused.get(i));\n            }\n        }\n\n        if (n == 1) {\n            for (int i = 0; i < unused.size(); i++) {\n                result.append(unused.get(i));\n            }\n        }\n        return result.toString();\n    }\n\n    private int factorial(int n) {\n        int result = 1;\n        for (int i = 1; i <= n; i++) {\n            result *= i;\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        GetKthPermutation gp = new GetKthPermutation();\n        System.out.println(gp.getPermutation(6, 343));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/HammingDistanceBetweenPair.java",
    "content": "package com.interview.misc;\n\n/**\n * http://www.glassdoor.com/Interview/-a-first-write-a-function-to-calculate-the-hamming-distance-between-two-binary-numbers-b-write-a-function-that-takes-QTN_450885.htm\n * Test cases\n * Not equal length strings\n * String containing anything other than 0 and 1\n */\npublic class HammingDistanceBetweenPair {\n\n    public int hammingDistance(String input[]){\n        int size = input[0].length();\n        int total = 0;\n        for(int i=0; i < size; i++){\n            int count0s = 0;\n            int count1s = 0;\n            for(String str : input){\n                if(str.charAt(i) == '0'){\n                    count0s++;\n                }else{\n                    count1s++;\n                }\n            }\n            total += count0s * count1s;\n        }\n        return total;\n    }\n    \n    public static void main(String args[]){\n        String input[] = {\"10011\",\"00011\",\"11101\",\"01010\"};\n        HammingDistanceBetweenPair hdb = new HammingDistanceBetweenPair();\n        System.out.println(hdb.hammingDistance(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/InsertInterval.java",
    "content": "package com.interview.misc;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Date 03/21/2016\n * @author Tushar Roy\n *\n * Insert internal into sorted intervals and merge them.\n *\n * Time complexity O(n)\n *\n * https://leetcode.com/problems/insert-interval/\n */\npublic class InsertInterval {\n\n    public static class Interval {\n        int start;\n        int end;\n\n        @Override\n        public String toString() {\n            return \"Interval{\" +\n                    \"start=\" + start +\n                    \", end=\" + end +\n                    '}';\n        }\n\n        Interval(int s, int e) { start = s; end = e; }\n    }\n\n    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {\n        List<Interval> result = new ArrayList<>();\n        boolean alreadyAdded = false;\n        for (int i = 0; i < intervals.size(); i++) {\n            if ((intervals.get(i).end < newInterval.start)) {\n                result.add(intervals.get(i));\n            } else if (intervals.get(i).start > newInterval.end) {\n                if (!alreadyAdded) {\n                    result.add(newInterval);\n                    alreadyAdded = true;\n                }\n                result.add(intervals.get(i));\n            } else {\n                newInterval.start = Math.min(newInterval.start, intervals.get(i).start);\n                newInterval.end = Math.max(newInterval.end, intervals.get(i).end);\n                if (!alreadyAdded) {\n                    result.add(newInterval);\n                    alreadyAdded = true;\n                }\n            }\n        }\n        if (!alreadyAdded) {\n            result.add(newInterval);\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        Interval i1 = new Interval(1,3);\n        Interval i2 = new Interval(6,7);\n        Interval i3 = new Interval(9,10);\n        Interval i4 = new Interval(11,12);\n        List<Interval> input = new ArrayList<>();\n        input.add(i1);\n        input.add(i2);\n        input.add(i3);\n        input.add(i4);\n        InsertInterval ii = new InsertInterval();\n        System.out.println(ii.insert(input, new Interval(13, 15)));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/IntegerListParser.java",
    "content": "package com.interview.misc;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Stack;\n\n/**\n * Date 10/10/2016\n * @author Tushar Roy\n *\n * Given a nested list of integers represented as a string, implement a parser to deserialize it.\n * Each element is either an integer, or a list -- whose elements may also be integers or other lists.\n *\n * https://leetcode.com/problems/mini-parser/\n */\npublic class IntegerListParser {\n\n    public NestedInteger deserialize(String s) {\n        Stack<NestedInteger> stack = new Stack();\n\n        NestedInteger current = null;\n        StringBuffer subInteger = new StringBuffer();\n        for (int i = 0; i < s.length(); i++) {\n            if (s.charAt(i) == '[') {\n                if (current != null) {\n                    stack.push(current);\n                }\n                current = new NestedInteger();\n                subInteger = new StringBuffer();\n            } else if (s.charAt(i) == ']') {\n                if (subInteger.length() > 0) {\n                    current.add(new NestedInteger(Integer.parseInt(subInteger.toString())));\n                    subInteger = new StringBuffer();\n                }\n                if (!stack.isEmpty()) {\n                    NestedInteger top = stack.pop();\n                    top.add(current);\n                    current = top;\n                }\n            } else if (s.charAt(i) == ',') {\n                if (subInteger.length() > 0) {\n                    current.add(new NestedInteger(Integer.parseInt(subInteger.toString())));\n                }\n                subInteger = new StringBuffer();\n            } else {\n                subInteger.append(s.charAt(i));\n            }\n        }\n        if (subInteger.length() > 0) {\n            return new NestedInteger(Integer.parseInt(subInteger.toString()));\n        }\n        return current;\n    }\n\n    public String serialize(NestedInteger nestedInteger) {\n        StringBuffer result = new StringBuffer();\n        serialize(nestedInteger, result);\n        return result.toString();\n    }\n\n    private void serialize(NestedInteger nestedInteger, StringBuffer result) {\n        if (nestedInteger.isInteger()) {\n            result.append(nestedInteger.getInteger());\n            return;\n        }\n        boolean isFirst = true;\n        result.append(\"[\");\n        for (NestedInteger ni : nestedInteger.getList()) {\n            if (!isFirst) {\n                result.append(\",\");\n            }\n            isFirst = false;\n            if (ni.isInteger()) {\n                result.append(ni.getInteger());\n            } else {\n                serialize(ni, result);\n            }\n        }\n        result.append(\"]\");\n    }\n\n    public static void main(String args[]) {\n        IntegerListParser integerListParser = new IntegerListParser();\n        NestedInteger nestedInteger = integerListParser.deserialize(\"123\");\n        String result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n        nestedInteger = integerListParser.deserialize(\"[]\");\n        result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n        nestedInteger = integerListParser.deserialize(\"[123]\");\n        result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n        nestedInteger = integerListParser.deserialize(\"[123,41]\");\n        result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[1]]\");\n        result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[[[]]]]\");\n        result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[[[],[]]]],[],[]\");\n        result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[[[121,41,[1]],[2]]]],[2],[4]\");\n        result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[[1,2,[],[]]]],[],[],[[1],[3]]\");\n        result = integerListParser.serialize(nestedInteger);\n        System.out.println(result);\n    }\n\n    class NestedInteger {\n        private List<NestedInteger> nestedInteger = new ArrayList<>();\n        private Integer val;\n        public NestedInteger() {\n\n        }\n\n        public NestedInteger(int value) {\n            this.val = value;\n        }\n\n        public boolean isInteger() {\n            return val != null;\n        }\n\n        public Integer getInteger() {\n            return val;\n        }\n\n        public void setInteger(int value) {\n            this.val = value;\n        }\n\n        public void add(NestedInteger ni) {\n            this.nestedInteger.add(ni);\n        }\n\n        public List<NestedInteger> getList() {\n            return val != null ? null : nestedInteger;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/misc/KthLargestInRowiseColumnWiseSorted2DArray.java",
    "content": "package com.interview.misc;\n\nimport com.interview.graph.BinaryMinHeap;\n\n/**\n * Kth largest in rowwise and column wise sorted array\n * http://www.geeksforgeeks.org/kth-smallest-element-in-a-row-wise-and-column-wise-sorted-2d-array-set-1/\n */\npublic class KthLargestInRowiseColumnWiseSorted2DArray {\n\n    public int kthLargest(int input[][],int k){\n        \n        BinaryMinHeap<Integer> minHeap = new BinaryMinHeap<Integer>();\n        int c = input[0].length;\n        int total = input.length * c;\n        minHeap.add(input[0][0], 0);\n        for(int i=1; i < k; i++){\n            int minIndex = minHeap.extractMin();\n            int minRow = minIndex/c;\n            int minCol = minIndex%c;\n            \n            int downNeighbor = (minRow+1)*c + minCol;\n            int rightNeighbor;\n            if(minCol== (c-1)){\n                rightNeighbor = total;\n            }else{\n                rightNeighbor = minRow*c + (minCol + 1);\n            }\n            if(downNeighbor < total && !minHeap.containsData(downNeighbor)){\n                minHeap.add(input[minRow+1][minCol], downNeighbor);\n            }\n            \n            if(rightNeighbor < total && !minHeap.containsData(rightNeighbor)){\n                minHeap.add(input[minRow][minCol+1], rightNeighbor);\n            }\n        }\n        \n        int minIndex = minHeap.extractMin();\n        return input[minIndex/c][minIndex%c];\n    }\n    \n    public static void main(String args[]){\n        int input[][] ={{1,5,11,21},\n                        {6,8,12,22},\n                        {7,9,15,26},\n                        {11,13,18,28}};\n        KthLargestInRowiseColumnWiseSorted2DArray kl = new KthLargestInRowiseColumnWiseSorted2DArray();\n        System.out.println(kl.kthLargest(input, 10));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/LoadBalancers.java",
    "content": "package com.interview.misc;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class LoadBalancers {\n\n    private List<String> servers = new ArrayList<String>();\n    Map<String,Integer> index = new HashMap<String,Integer>();\n    \n    public void addServer(String name){\n        servers.add(name);\n        index.put(name, servers.size()-1);\n    }\n    \n    public void removeServer(String name){\n        Integer pos = index.get(name);\n        if(pos == null){\n            throw new IllegalArgumentException();\n        }\n        servers.set(pos, servers.get(servers.size()-1));\n        servers.remove(servers.size()-1);\n    }\n    \n    public String getRandom(){\n        int r = (int)(Math.random()*1000);\n        return servers.get(r%servers.size());\n    }\n    \n    public static void main(String args[]){\n        LoadBalancers lb = new LoadBalancers();\n        lb.addServer(\"1\");\n        lb.addServer(\"2\");\n        lb.addServer(\"3\");\n        lb.addServer(\"4\");\n        lb.addServer(\"5\");\n        \n        System.out.print(lb.getRandom());\n        System.out.print(lb.getRandom());\n        System.out.print(lb.getRandom());\n        System.out.print(lb.getRandom());\n            \n        lb.removeServer(\"3\");\n        lb.removeServer(\"1\");\n        System.out.print(lb.getRandom());\n        System.out.print(lb.getRandom());\n        System.out.print(lb.getRandom());\n        System.out.print(lb.getRandom());\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/NestedIterator.java",
    "content": "package com.interview.misc;\n\nimport java.util.Deque;\nimport java.util.Iterator;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Stack;\n\n/**\n * Date 04/17/2017\n * @author Tushar Roy\n *\n * Given a nested list of integers, implement an iterator to flatten it.\n * Each element is either an integer, or a list -- whose elements may also be integers or other lists.\n * Example 1:\n * Given the list [[1,1],2,[1,1]],\n * By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1].\n *\n * https://leetcode.com/problems/flatten-nested-list-iterator/\n */\npublic class NestedIterator implements Iterator<Integer> {\n    Stack<Iterator<NestedInteger>> stack = new Stack<>();\n    Integer nextVal = null;\n    public NestedIterator(List<NestedInteger> nestedList) {\n        stack.push(nestedList.iterator());\n    }\n\n    @Override\n    public Integer next() {\n        if (!hasNext()) {\n            throw new IllegalArgumentException();\n        }\n        Integer val = nextVal;\n        nextVal = null;\n        return val;\n    }\n\n    @Override\n    public boolean hasNext() {\n        if (nextVal != null) {\n            return true;\n        }\n        while (!stack.isEmpty()) {\n            boolean pushedIntoStack = false;\n            Iterator<NestedInteger> itr = stack.peek();\n            if (itr.hasNext()) {\n                NestedInteger ni = itr.next();\n                if (ni.isInteger()) {\n                    nextVal = ni.getInteger();\n                    return true;\n                } else {\n                    pushedIntoStack = true;\n                    stack.push(ni.getList().iterator());\n                }\n            }\n            if (!pushedIntoStack) {\n                stack.pop();\n            }\n        }\n        return false;\n    }\n}\n\ninterface NestedInteger {\n    boolean isInteger();\n    Integer getInteger();\n    List<NestedInteger> getList();\n}"
  },
  {
    "path": "src/com/interview/misc/NumberToWord.java",
    "content": "package com.interview.misc;\n\n/**\n * Convert a number into words\n *\n * Reference\n * https://leetcode.com/problems/integer-to-english-words/\n */\npublic class NumberToWord {\n\n    private static int BILLION = 1000000000;\n    private static int MILLION = 1000000;\n    private static int THOUSAND = 1000;\n    \n    public String numberToWords(int number){\n        StringBuffer buffer = new StringBuffer();\n        if(number ==0){\n            return toString(number).trim();\n        }\n        if(number < 0){\n            buffer.append(\"Minus\");\n            number = number *-1;\n        }\n        if (number >= BILLION) {\n            int first = number / BILLION;\n            number = number % BILLION;\n            buffer.append(hundredsPart(first)).append(toString(BILLION));\n        }\n        if(number >= MILLION){\n            int first = number /MILLION;\n            number = number % MILLION;\n            buffer.append(hundredsPart(first)).append(toString(MILLION));\n        }\n        if(number >= THOUSAND){\n            int first = number /THOUSAND;\n            number = number % THOUSAND;\n            buffer.append(hundredsPart(first)).append(toString(THOUSAND));\n        }\n        buffer.append(hundredsPart(number));\n        return buffer.toString().trim();\n    }\n    \n    private String hundredsPart(int number){\n        StringBuffer buffer = new StringBuffer();\n        if(number != 0){\n            if(number <= 99){\n                buffer.append(tenthPart(number));\n            }else{\n                int first = (number /100);\n                int second = number % 100;\n                buffer.append(toString(first) + toString(100));\n                if (second != 0){\n                    buffer.append(tenthPart(second));\n                }\n            }\n            return buffer.toString();\n        }else{\n            return \"\";\n        }\n    }\n        \n    private String tenthPart(int number){\n        StringBuffer buffer = new StringBuffer();\n        if(number != 0){\n            if(number <= 19){\n                buffer.append(toString(number));\n            }else{\n                int first = (number/10)*10;\n                int second = number%10;\n                buffer.append(toString(first));\n                if (second != 0){\n                    buffer.append(toString(second));\n                }\n            }\n            return buffer.toString();\n        }else{\n            return \"\";\n        }\n    }\n    \n    private String toString(int number){\n        \n        switch(number){\n            case 0:\n                return \" Zero\";\n            case 1:\n                return \" One\";\n            case 2:\n                return \" Two\";\n            case 3:\n                return \" Three\";\n            case 4:\n                return \" Four\";\n            case 5:\n                return \" Five\";\n            case 6:\n                return \" Six\";\n            case 7:\n                return \" Seven\";\n            case 8:\n                return \" Eight\";\n            case 9:\n                return \" Nine\";\n            case 10:\n                return \" Ten\";\n            case 11:\n                return \" Eleven\";\n            case 12:\n                return \" Twelve\";\n            case 13:\n                return \" Thrirteen\";\n            case 14:\n                return \" Fourteen\";\n            case 15:\n                return \" Fifteen\";\n            case 16:\n                return \" Sixteen\";\n            case 17:\n                return \" Seventeen\";\n            case 18:\n                return \" Eighteen\";\n            case 19:\n                return \" Nineteen\";\n            case 20:\n                return \" Twenty\";\n            case 30:\n                return \" Thirty\";\n            case 40:\n                return \" Forty\";\n            case 50:\n                return \" Fifty\";\n            case 60:\n                return \" Sixty\";\n            case 70:\n                return \" Seventy\";\n            case 80:\n                return \" Eighty\";\n            case 90:\n                return \" Ninety\";\n            case 100:\n                return \" Hundred\";\n            case 1000:\n                return \" Thousand\";\n            case 1000000:\n                return \" Million\";\n            case 1000000000:\n                return \" Billion\";\n            default:\n                throw new IllegalArgumentException();\n            }\n    }\n    \n    public static void main(String args[]){\n        NumberToWord ntw = new NumberToWord();\n        System.out.println(ntw.numberToWords(8000));\n        System.out.println(ntw.numberToWords(8192));\n        System.out.println(ntw.numberToWords(8112));\n        System.out.println(ntw.numberToWords(504));\n        System.out.println(ntw.numberToWords(565100));\n        System.out.println(ntw.numberToWords(6721157));\n        System.out.println(ntw.numberToWords(-106721157));\n        System.out.println(ntw.numberToWords(106070571));\n        System.out.println(ntw.numberToWords(-92));\n        System.out.println(ntw.numberToWords(0));\n        System.out.println(ntw.numberToWords(1212121451));\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/PrimeNumbersBeforeN.java",
    "content": "package com.interview.misc;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * All prime numbers before n\n */\npublic class PrimeNumbersBeforeN {\n\n    public List<Integer> primeNumbers(int n){\n        List<Integer> result = new ArrayList<Integer>();\n        result.add(2);\n        boolean flag = false;\n        for(int i=3; i < n; i+=2){\n            for(int r : result){\n                if(2*r > i){\n                    break;\n                }\n                if(i % r == 0){\n                    flag = true;\n                    break;\n                }\n            }\n            if(!flag){\n                result.add(i);\n            }\n            flag = false;\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        PrimeNumbersBeforeN pnb = new PrimeNumbersBeforeN();\n        List<Integer> result = pnb.primeNumbers(150);\n        result.forEach(i -> System.out.print(i + \" \"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/Read4Function.java",
    "content": "package com.interview.misc;\n\nimport java.util.Arrays;\n\n/**\n * Date 03/26/2016\n * @author Tushar Roy\n * \n * Given a reader which only reads 4 bytes implement a Reader which can read bytes of give size.\n *\n * Reference\n * Read N Characters Given Read4 II\n * https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/\n */\n\nclass Read4 {\n    int read4(char[] buff) {\n        buff[0] = 'a';\n        buff[1] = 'b';\n        buff[2] = 'c';\n        buff[3] = 'd';\n        return 4;\n    }\n}\n\npublic class Read4Function extends Read4{\n\n    class Queue {\n        int start;\n        int end;\n        int count;\n        char[] data;\n        int size;\n        Queue(int size) {\n            data = new char[size];\n            this.size = size;\n        }\n\n        boolean isEmpty() {\n            return count == 0;\n        }\n\n        void offer(char b) {\n            data[start] = b;\n            start = (start + 1)%size;\n            count++;\n        }\n\n        char poll() {\n            char d = data[end];\n            end = (end + 1)%size;\n            count--;\n            return d;\n        }\n    }\n\n    private final Queue queue;\n    public Read4Function() {\n        queue = new Queue(4);\n    }\n\n    public int read(char[] buf, int n) {\n        int r = 0;\n        while (!queue.isEmpty() && r < n) {\n            buf[r++] = queue.poll();\n        }\n\n        if (r == n) {\n            return r;\n        }\n        int index = 0;\n        int readSize = 0;\n        char[] input = null;\n        do {\n            input = new char[4];\n            readSize = read4(input);\n            index = 0;\n            while(r < n && index < readSize) {\n                buf[r++] = input[index++];\n            }\n        } while (readSize == 4 && r < n);\n\n        while (index < readSize) {\n            queue.offer(input[index++]);\n        }\n        return r;\n    }\n\n    public static void main(String args[]) {\n        Read4Function rf = new Read4Function();\n        char[] buff = new char[10];\n        int size = rf.read(buff, 2);\n        System.out.print(size);\n        System.out.println(Arrays.toString(buff));\n        size = rf.read(buff, 1);\n        System.out.print(size);\n        System.out.println(Arrays.toString(buff));\n        size = rf.read(buff, 1);\n        System.out.print(size);\n        System.out.println(Arrays.toString(buff));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/RomanNumberToDecimal.java",
    "content": "package com.interview.misc;\n\n/**\n * Convert a roman number to decimal number\n * Test cases: smaller number appearing before bigger number unless it is representing one less. \n * VL is incorrect since XL should be used to represent 90\n * chars not used in roman representation is used\n * http://www.onlineconversion.com/roman_numerals_advanced.htm\n *\n */\npublic class RomanNumberToDecimal {\n\n    public String converToRoman(int decimal){\n        StringBuffer buffer = new StringBuffer();\n        while(decimal > 0){\n            decimal = literal(decimal,buffer);\n        }\n        return buffer.toString();\n    }\n    \n    public int convertToDecimal(char[] roman){\n        int decimal = 0;\n        for(int i=0; i < roman.length; ){\n            if(i < roman.length-1 && literal(roman[i]) < literal(roman[i+1])){\n                decimal += literal(roman[i+1]) - literal(roman[i]);\n                i += 2;\n            }else{\n                decimal += literal(roman[i]);\n                i++;\n            }\n        }\n        return decimal;\n    }\n    \n    private int literal(int decimal,StringBuffer buffer){\n        if(decimal >= 1000){\n            buffer.append(\"M\");\n            decimal -= 1000;\n            return decimal;\n        }\n        else if(decimal >= 900){\n            buffer.append(\"CM\");\n            decimal -= 900;\n            return decimal;\n        }\n        else if(decimal >= 500){\n            buffer.append(\"D\");\n            decimal -= 500;\n            return decimal;\n        }\n        else if(decimal >= 400){\n            buffer.append(\"CD\");\n            decimal -= 400;\n            return decimal;\n        }\n        else if(decimal >= 100){\n            buffer.append(\"C\");\n            decimal -= 100;\n            return decimal;\n        }\n        else if(decimal >= 90){\n            buffer.append(\"XC\");\n            decimal -= 90;\n            return decimal;\n        }\n        else if(decimal >= 50){\n            buffer.append(\"L\");\n            decimal -= 50;\n            return decimal;\n        }\n        else if(decimal >= 40){\n            buffer.append(\"XL\");\n            decimal -= 40;\n            return decimal;\n        }\n        else if(decimal >= 10){\n            buffer.append(\"X\");\n            decimal -= 10;\n            return decimal;\n        }else if(decimal >= 9){\n            buffer.append(\"IX\");\n            decimal -= 9;\n            return decimal;\n        }\n        else if(decimal >=5){\n            buffer.append(\"V\");\n            decimal -= 5;\n            return decimal;\n        }else if(decimal >= 4){\n            buffer.append(\"IV\");\n            decimal -= 4;\n            return decimal;\n        }else {\n            buffer.append(\"I\");\n            decimal -= 1;\n            return decimal;\n        }\n    }\n    \n    private int literal(char ch){\n        switch(ch){\n        case 'I' :  \n            return 1;\n        case 'V' :\n            return 5;\n        case 'X' :\n            return 10;\n        case 'L' :\n            return 50;\n        case 'C' :\n            return 100;\n        case 'D' :\n            return 500;\n        case 'M' :\n            return 1000;\n        default :\n            throw new IllegalArgumentException();\n        }\n    }\n    \n    public static void main(String args[]){\n        RomanNumberToDecimal rnd = new RomanNumberToDecimal();\n        System.out.println(rnd.convertToDecimal(\"XX\".toCharArray()));\n        System.out.println(rnd.convertToDecimal(\"XCIX\".toCharArray()));\n        System.out.println(rnd.convertToDecimal(\"MLXIX\".toCharArray()));\n        System.out.println(rnd.convertToDecimal(\"MMDXLIII\".toCharArray()));\n        \n        System.out.println(rnd.converToRoman(20));\n        System.out.println(rnd.converToRoman(99));\n        System.out.println(rnd.converToRoman(1069));\n        System.out.println(rnd.converToRoman(2543));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/misc/SparseTableRangeMinimumQuery.java",
    "content": "package com.interview.misc;\n\n/**\n * Date 04/28/2016\n * @author Tushar Roy\n *\n * Find range minimum query using sparse table.\n *\n * Preprocessing Time complexity O(nlogn)\n * Query Time complexity O(1)\n * Space complexity O(nlogn)\n *\n * Reference -\n * https://www.topcoder.com/community/data-science/data-science-tutorials/range-minimum-query-and-lowest-common-ancestor/\n */\npublic class SparseTableRangeMinimumQuery {\n\n    private final int[][] sparse;\n    private final int n;\n    private final int[] input;\n\n    public SparseTableRangeMinimumQuery(int[] input) {\n        this.input = input;\n        this.n = input.length;\n        this.sparse = preprocess(input, this.n);\n    }\n\n    private int[][] preprocess(int[] input, int n) {\n        int[][] sparse = new int[n][log2(n) + 1];\n        for (int i = 0; i < input.length; i++) {\n            sparse[i][0] = i;\n        }\n\n        for (int j = 1; 1 << j <= n; j++) {\n            for (int i = 0; i + (1 << j) - 1 < n; i++) {\n                if (input[sparse[i][j - 1]] < input[sparse[i + (1 << (j - 1))][j - 1]]) {\n                    sparse[i][j] = sparse[i][j - 1];\n                } else {\n                    sparse[i][j] = sparse[i + (1 << (j - 1))][j - 1];\n                }\n            }\n        }\n        return sparse;\n    }\n\n    public int rangeMinimumQuery(int low, int high) {\n        int l = high - low + 1;\n        int k = log2(l);\n        if (input[sparse[low][k]] <= input[sparse[low + l - (1<<k)][k]]) {\n            return input[sparse[low][k]];\n        } else {\n            return input[sparse[high - (1<<k) + 1][k]];\n        }\n    }\n\n    private static int log2(int n){\n        if(n <= 0) throw new IllegalArgumentException();\n        return 31 - Integer.numberOfLeadingZeros(n);\n    }\n\n    public static void main(String args[]) {\n        int[] input = {2, 5, 3, 6, 4, 1, -1, 3, 4, 2};\n        SparseTableRangeMinimumQuery sparseTableRangeMinimumQuery = new SparseTableRangeMinimumQuery(input);\n        for (int i = 0; i < input.length; i++) {\n            for (int j = i; j < input.length; j++) {\n                System.out.print(sparseTableRangeMinimumQuery.rangeMinimumQuery(i, j) + \" \");\n            }\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/Fill2DMatrixWith1.java",
    "content": "package com.interview.multiarray;\n\n/**\n * http://www.geeksforgeeks.org/a-boolean-matrix-question/\n */\npublic class Fill2DMatrixWith1 {\n\n\tpublic void fill(int input[][]){\n\t\tboolean row[] = new boolean[input.length];\n\t\tboolean col[] = new boolean[input[0].length];\n\t\tfor(int i=0; i < input.length; i++){\n\t\t\tfor(int j=0; j < input[i].length; j++){\n\t\t\t\tif(input[i][j] == 1){\n\t\t\t\t\trow[i] = true;\n\t\t\t\t\tcol[j] = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor(int i=0; i < input.length; i++){\n\t\t\tfor(int j=0; j < input[i].length; j++){\n\t\t\t\tif(row[i] || col[j]){\n\t\t\t\t\tinput[i][j] = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\tint input[][] = {{0,0,1,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0}};\n\t\tFill2DMatrixWith1 fd = new Fill2DMatrixWith1();\n\t\tfd.fill(input);\n\t\tfor(int i=0; i < input.length; i++){\n\t\t\tfor(int j=0; j < input[i].length; j++){\n\t\t\t\tSystem.out.print(input[i][j] + \" \");\n\t\t\t}\n\t\t\tSystem.out.println();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/GameOfLife.java",
    "content": "package com.interview.multiarray;\n\n/**\n * Date 10/20/2016\n * @author Tushar Roy\n * Given a board with m by n cells, each cell has an initial state live (1) or dead (0).\n * Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following\n * four rules (taken from the above Wikipedia article):\n * Read full qs on leetcode.\n *\n * Solution - Keep two array prev and current. Fill the values in current array. As soon as current row is done\n * replace elemments of board with prev array.\n *\n * Time complexity O(n * m)\n *\n * https://leetcode.com/problems/game-of-life/\n */\npublic class GameOfLife {\n    public void gameOfLife(int[][] board) {\n        if (board.length == 0 || board[0].length == 0) {\n            return;\n        }\n        int n = board.length;\n        int m = board[0].length;\n        int[] prevRow = new int[m];\n        int[] currentRow = new int[m];\n\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < m; j++) {\n                currentRow[j] = doesLive(i, j, board) ? 1 : 0;\n            }\n            if (i != 0) {\n                copyRow(prevRow, board[i - 1]);\n            }\n            if (i != n - 1) {\n                copyRow(currentRow, prevRow);\n            }\n        }\n        copyRow(currentRow, board[n - 1]);\n    }\n\n    private void copyRow(int[] source, int[] dest) {\n        for (int i = 0; i < source.length; i++) {\n            dest[i] = source[i];\n        }\n    }\n\n    private boolean doesLive(int x, int y, int[][] board) {\n        int count = 0;\n        for (int i = x - 1; i <= x + 1; i++) {\n            for (int j = y - 1; j <= y + 1; j++) {\n                if (x == i && y == j) {\n                    continue;\n                }\n                if (i < 0 || i >= board.length) {\n                    break;\n                }\n                if (j < 0 || j >= board[0].length) {\n                    continue;\n                }\n                count += board[i][j];\n            }\n        }\n        if (board[x][y] == 1) {\n            return count == 2 || count == 3;\n        } else {\n            return count == 3;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/LongestConsecutiveIntegerInUnsorted2DArray.java",
    "content": "package com.interview.multiarray;\n\n/**\n * Find the length of the longest chain of consecutive integers in an unsorted 2D square array (non-diagonal)\n */\npublic class LongestConsecutiveIntegerInUnsorted2DArray {\n\n\tpublic int longestConsecutiveInteger(int input[][]){\n\t\n\t\tboolean visited[][] = new boolean[input.length][input[0].length];\n\t\tint max = 1;\n\t\tfor(int i=0; i < input.length; i++){\n\t\t\tfor(int j=0; j < input[i].length; j++){\n\t\t\t\tint r = DFS(input,i,j,visited,-10000);\n\t\t\t\tif(r > max){\n\t\t\t\t\tmax = r;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn max;\n\t}\n\t\n\tprivate int DFS(int input[][],int i,int j,boolean visited[][],int lastNum){\n\t\tif(i >= input.length || i < 0 || j < 0 || j >= input[0].length){\n\t\t\treturn 0;\n\t\t}\n\t\tif(visited[i][j]){\n\t\t\treturn 0;\n\t\t}\n\t\tif(lastNum != -10000 && input[i][j] + 1 != lastNum){\n\t\t\treturn 0;\n\t\t}\n\t\tvisited[i][j] = true;\n\t\t\n\t\tint r1 = DFS(input,i+1,j,visited,input[i][j]);\n\t\tint r2 = DFS(input,i-1,j,visited,input[i][j]);\n\t\tint r3 = DFS(input,i,j+1,visited,input[i][j]);\n\t\tint r4 = DFS(input,i,j-1,visited,input[i][j]);\n\t\tvisited[i][j] = false;\n\t\treturn Math.max(Math.max(r1, r2), Math.max(r3,r4)) + 1;\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\tLongestConsecutiveIntegerInUnsorted2DArray lci = new LongestConsecutiveIntegerInUnsorted2DArray();\n\t\tint input[][] = {{3,2,5},\n\t\t\t\t         {4,1,4},\n\t\t\t\t\t\t {5,6,5}};\n\t\tSystem.out.println(lci.longestConsecutiveInteger(input));\n\t}\n\t\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/MatrixCalculation.java",
    "content": "package com.interview.multiarray;\n\npublic class MatrixCalculation {\n\n    private int r = 0;\n    \n    public String[][] crossMultiply(String[][] str){\n        \n        int cols = 1;\n        for(int i=1; i < str.length; i++){\n            cols = cols*str[i].length;\n        }\n        String[][] result = new String[str[0].length][cols];\n        for(int i=0; i < str[0].length ; i++){\n            StringBuffer buffer = new StringBuffer();\n            r=0;\n            buffer.append(str[0][i]);\n            recur(buffer,result,str,1,i);\n        }\n        \n        return result;\n        \n    }\n    \n    private void recur(StringBuffer buffer,String[][] result,String[][] str,int currentRow,int mainCol){\n        \n        if(currentRow == str.length){\n            result[mainCol][r++] = buffer.toString(); \n            return;\n        }\n        \n        for(int i=0; i < str[currentRow].length; i++){\n            StringBuffer tempBuffer = new StringBuffer(buffer);\n            buffer.append(str[currentRow][i]);\n            recur(buffer,result,str,currentRow+1,mainCol);\n            buffer = tempBuffer;\n        }\n    }\n    \n    public static void main(String args[]){\n        MatrixCalculation mc = new MatrixCalculation();\n        String[][] str = {{\"abc\",\"def\",\"gh\"},{\"l\",\"m\"},{\"p\",\"q\",\"r\"},{\"x\",\"y\"}};\n        String[][] result = mc.crossMultiply(str);\n        for(int i=0; i < result.length; i++){\n            for(int j=0; j < result[i].length; j++){\n                System.out.print(result[i][j] + \" \");\n            }\n            System.out.println();\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/MatrixFindAllSubSquareRectangleMatrix.java",
    "content": "package com.interview.multiarray;\n\n/**\n * Iterate through matrix and get all subsquare and subrectangle matrix and print their sum\n */\npublic class MatrixFindAllSubSquareRectangleMatrix {\n\n    public void printSumOfAllSquareMatrix(int input[][]){\n        \n        for(int len = 1; len <= input.length; len++){\n            for(int i=0; i < input.length - len + 1; i++){\n                for(int j=0; j < input[i].length - len + 1; j++){\n                    int sum = 0;\n                    for(int k=i;k < i+len; k++){\n                        for(int m = j; m < j+len; m++){\n                            sum += input[k][m];\n                        }\n                    }\n                    System.out.println(\"Start \" + i + \" \" + j + \" End \" + len + \" sum \" + sum);\n                }\n            }\n        }\n    }\n    \n    public void printSumOfAllRectangleMatrix(int input[][]){\n        for(int rlen = 1 ; rlen <= input.length; rlen++){\n            for(int clen = 1; clen <= input[0].length; clen++){\n                for(int i=0; i < input.length - rlen + 1; i++){\n                    for(int j=0; j < input[i].length - clen + 1; j++){\n                        int sum = 0;\n                        for(int k=i;k < i+rlen; k++){\n                            for(int m = j; m < j+clen; m++){\n                                sum += input[k][m];\n                            }\n                        }\n                        System.out.println(\"Start \" + i + \" \" + j + \" End \" + (i + rlen-1) + \" \"  + (j + clen-1) + \" sum \" + sum);\n                    }\n                }\n            }\n        }\n    }\n    public static void main(String args[]){\n        int input[][] = {{1,2,3},\n                         {4,5,6},\n                         {7,8,9}};\n        \n        MatrixFindAllSubSquareRectangleMatrix mal = new MatrixFindAllSubSquareRectangleMatrix();\n        mal.printSumOfAllRectangleMatrix(input);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/MatrixInDiagonalOrder.java",
    "content": "package com.interview.multiarray;\n\n/**\n * http://www.geeksforgeeks.org/print-matrix-diagonally/\n */\npublic class MatrixInDiagonalOrder {\n\n\tpublic void printMatrix(int [][]matrix){\n\t\tfor(int i=0; i < matrix.length; i++){\n\t\t\tint start =i;\n\t\t\tint end =0;\n\t\t\twhile(start >= 0 && end < matrix[0].length){\n\t\t\t\tSystem.out.print(matrix[start][end] + \" \");\n\t\t\t\tstart--;\n\t\t\t\tend++;\n\t\t\t}\n\t\t\tSystem.out.print(\"\\n\");\n\t\t}\n\t\t\n\t\tfor(int i=1; i < matrix[0].length; i++){\n\t\t\tint start = matrix.length-1;\n\t\t\tint end =i;\n\t\t\twhile(start >= 0 && end < matrix[0].length){\n\t\t\t\tSystem.out.print(matrix[start][end] + \" \");\n\t\t\t\tstart--;\n\t\t\t\tend++;\n\t\t\t}\n\t\t\tSystem.out.print(\"\\n\");\n\t\t}\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\tint arr[][] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};\n\t\tMatrixInDiagonalOrder mdo = new MatrixInDiagonalOrder();\n\t\tmdo.printMatrix(arr);\n\t}\n\t\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/MatrixOf0sAnd1s.java",
    "content": "package com.interview.multiarray;\n\n/**\n * http://www.geeksforgeeks.org/create-a-matrix-with-alternating-rectangles-of-0-and-x/\n * Test case : negative or 0 for n or m\n */\npublic class MatrixOf0sAnd1s {\n\n\tpublic char[][] create(int n,int m){\n\t\tchar[][] matrix = new char[n][m];\n\t\t\n\t\tint r = 0;\n\t\tchar ch = 'X';\n\t\tint high = Math.min(n, m);\n\t\t//high is min of n and m. If high is odd then high is ceiling of high/2\n\t\t//else high is high/2. e.g high is 5 then high becomes 3 if high is 4\n\t\t//high becomes 2\n\t\thigh = (int)Math.ceil(high*1.0/2);\n\t\twhile(r < high){\n\t\t\t\n\t\t\tfor(int i=r; i < m-r ; i++){\n\t\t\t\tmatrix[r][i] = ch;\n\t\t\t}\n\t\t\t\n\t\t\tfor(int i = r; i < n-r; i++ ){\n\t\t\t\tmatrix[i][m-r-1] = ch;\n\t\t\t}\n\n\t\t\tfor(int i = m-r-1; i >= r; i-- ){\n\t\t\t\tmatrix[n-r-1][i] = ch;\n\t\t\t}\n\n\t\t\tfor(int i = n-r-1; i >= r; i-- ){\n\t\t\t\tmatrix[i][r] = ch;\n\t\t\t}\n\t\t\t\n\t\t\tif(ch =='X'){\n\t\t\t\tch = 'O';\n\t\t\t}else{\n\t\t\t\tch = 'X';\n\t\t\t}\n\t\t\tr++;\n\t\t}\n\t\treturn matrix;\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\tMatrixOf0sAnd1s mos = new MatrixOf0sAnd1s();\n\t\tchar matrix[][] = mos.create(4, 7);\n\t\tfor(int i=0; i < matrix.length; i++){\n\t\t\tfor(int j=0; j < matrix[i].length; j++){\n\t\t\t\tSystem.out.print(matrix[i][j] + \" \");\n\t\t\t}\n\t\t\tSystem.out.println();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/MoveCellPerCellValue.java",
    "content": "package com.interview.multiarray;\n\n/**\n * http://www.careercup.com/question?id=6685828805820416\n * Test Edge cases\n * Values in cell should be in range of 2D array.\n */\nclass Cell{\n\tint x;\n\tint y;\n\tCell(int x,int y){\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t}\n}\n\npublic class MoveCellPerCellValue {\n\n\tpublic boolean isAllCellTraversed(Cell grid[][]){\n\t\tboolean[][] visited = new boolean[grid.length][grid[0].length];\n\t\t\n\t\tint total = grid.length * grid[0].length;\n\t\tint startx = grid[0][0].x;\n\t\tint starty = grid[0][0].y;\n\t\tfor(int i=0; i < total-2; i++){\n\t\t\tif(grid[startx][starty] == null){\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(visited[startx][starty] == true){\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvisited[startx][starty] = true;\n\t\t\tint x = grid[startx][starty].x;\n\t\t\tint y = grid[startx][starty].y;\n\t\t\tstartx = x;\n\t\t\tstarty = y;\n\t\t}\n\t\tif(grid[startx][starty] == null){\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\tCell cell[][] = new Cell[3][2];\n\t\tcell[0][0] = new Cell(0,1);\n\t\tcell[0][1] = new Cell(2,0);\n\t\tcell[1][0] = null;\n\t\tcell[1][1] = new Cell(1,0);\n\t\tcell[2][0] = new Cell(2,1);\n\t\tcell[2][1] = new Cell(1,1);\n\t\t\n\t\tMoveCellPerCellValue mcp = new MoveCellPerCellValue();\n\t\tSystem.out.println(mcp.isAllCellTraversed(cell));\n\t}\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/Mutable2DSumRangeQuery.java",
    "content": "package com.interview.multiarray;\n\n/**\n *\n * Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner\n * (row1, col1) and lower right corner (row2, col2).\n *\n * https://leetcode.com/problems/range-sum-query-2d-mutable/\n */\npublic class Mutable2DSumRangeQuery {\n    private int[][] prefixSum;\n    private int rows;\n    private int cols;\n    private int[][] matrix;\n\n    public Mutable2DSumRangeQuery(int[][] matrix) {\n        if (matrix.length == 0) {\n            return;\n        }\n        prefixSum = new int[matrix.length][matrix[0].length + 1];\n        this.matrix = matrix;\n        rows = matrix.length;\n        cols = matrix[0].length;\n        for (int i = 0; i < rows; i++) {\n            for (int j = 1; j <= cols; j++) {\n                prefixSum[i][j] = prefixSum[i][j - 1] + matrix[i][j - 1];\n            }\n        }\n\n    }\n\n    public void update(int row, int col, int val) {\n        int delta = val - matrix[row][col];\n        matrix[row][col] = val;\n        for (int i = col + 1; i <= cols; i++) {\n            prefixSum[row][i] += delta;\n        }\n    }\n\n    public int sumRegion(int row1, int col1, int row2, int col2) {\n        int sum = 0;\n        for (int i = row1; i <= row2; i++) {\n            sum += prefixSum[i][col2 + 1] - prefixSum[i][col1];\n        }\n        return sum;\n    }\n}"
  },
  {
    "path": "src/com/interview/multiarray/RotateImage.java",
    "content": "package com.interview.multiarray;\n\n/**\n * Date 07/31/2016\n * @author Tushar Roy\n *\n * You are given an n x n 2D matrix representing an image.\n * Rotate the image by 90 degrees (clockwise).\n *\n * https://leetcode.com/problems/rotate-image/\n */\npublic class RotateImage {\n\n    public void rotate(int[][] matrix) {\n        int length = matrix.length-1;\n        int j=0;\n        while(j < matrix.length/2){\n            for(int i=j; i < length-j; i++){\n                int temp = matrix[j][i];\n                matrix[j][i] = matrix[length-i][j];\n                matrix[length-i][j] = matrix[length-j][length-i];\n                matrix[length-j][length-i] = matrix[i][length-j];\n                matrix[i][length-j] = temp;\n            }\n            j++;\n        }\n    }\n\n    private void print(int arr[][]){\n        for(int i=0; i < arr.length; i++){\n            for(int j=0; j < arr.length; j++){\n                System.out.print(arr[i][j] + \" \");\n            }\n            System.out.print(\"\\n\");\n        }\n    }\n\n    public static void main(String args[]){\n\n        int matrix[][] = {{1,2,3,4,20},{5,6,7,8,30},{9,10,11,12,40},{13,14,15,16,50},{21,22,23,24,25}};\n        RotateImage ti = new RotateImage();\n        ti.rotate(matrix);\n        ti.print(matrix);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/ShortestDistanceFromAllBuildings.java",
    "content": "package com.interview.multiarray;\n\nimport java.util.ArrayList;\nimport java.util.Deque;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Queue;\nimport java.util.Set;\n\n/**\n * Date 03/25/2016\n * @author Tushar Roy\n *\n * Shortest Distance from All Buildings\n * https://leetcode.com/problems/shortest-distance-from-all-buildings/\n */\npublic class ShortestDistanceFromAllBuildings {\n    private class Point {\n        int x, y, dist = 0;\n        Point(int row, int col, int dist) {\n            x = row;\n            y = col;\n            this.dist = dist;\n        }\n    }\n\n    public int shortestDistance(int[][] grid) {\n        int totalBuild = 0;\n        int[][] reach = new int[grid.length][grid[0].length];\n        int[][] distance = new int[grid.length][grid[0].length];\n        for(int i = 0; i < grid.length; i++) {\n            for(int j = 0; j < grid[0].length; j++) {\n                if(grid[i][j] == 1) {\n                    Queue<Point> queue = new LinkedList<>();\n                    queue.offer(new Point(i, j, 0));\n                    totalBuild++;\n                    boolean[][] visited = new boolean[grid.length][grid[0].length];\n                    while (!queue.isEmpty()) {\n                        List<Point> neighbors = getNeighbors(queue.poll(), grid, visited, grid.length, grid[0].length);\n                        for (Point neigh : neighbors) {\n                            visited[neigh.x][neigh.y] = true;\n                            reach[neigh.x][neigh.y]++;\n                            distance[neigh.x][neigh.y] += neigh.dist;\n                            queue.offer(neigh);\n                        }\n                    }\n                }\n            }\n        }\n\n        int min = Integer.MAX_VALUE;\n        for (int i = 0; i < reach.length; i++) {\n            for (int j = 0; j < reach[0].length; j++) {\n                if (reach[i][j] == totalBuild) {\n                    min = Math.min(min, distance[i][j]);\n                }\n            }\n        }\n\n        return min == Integer.MAX_VALUE ? -1 : min;\n    }\n\n    private List<Point> getNeighbors(Point p, int[][] grid, boolean[][] visited, int n, int m) {\n        List<Point> resultList = new ArrayList<>();\n        if(p.x > 0 && grid[p.x -1][p.y] == 0 && !visited[p.x - 1][p.y])\n            resultList.add(new Point(p.x -1, p.y, p.dist + 1));\n        if(p.x < n - 1 && grid[p.x + 1][p.y] == 0 && !visited[p.x + 1][p.y])\n            resultList.add(new Point(p.x + 1, p.y, p.dist + 1));\n        if(p.y > 0 && grid[p.x][p.y - 1] == 0 && !visited[p.x][p.y - 1])\n            resultList.add(new Point(p.x, p.y - 1, p.dist + 1));\n        if(p.y < m - 1 && grid[p.x][p.y + 1] == 0 && !visited[p.x][p.y + 1])\n            resultList.add(new Point(p.x, p.y + 1, p.dist + 1));\n\n        return resultList;\n    }\n\n    public static void main(String args[]) {\n        int[][] grid = {{1,1,1,1,1,0},{0,0,0,0,0,1},{0,1,1,0,0,1},{1,0,0,1,0,1},{1,0,1,0,0,1},{1,0,0,0,0,1},{0,1,1,1,1,0}};\n        int[][] grid1 = {{1,1},{0,1}};\n        ShortestDistanceFromAllBuildings shortestDistanceFromAllBuildings = new ShortestDistanceFromAllBuildings();\n        System.out.println(shortestDistanceFromAllBuildings.shortestDistance(grid));\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/SmallestRectangleBlackPixel.java",
    "content": "package com.interview.multiarray;\n\n/**\n * An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel.\n * The black pixels are connected, i.e., there is only one black region. Pixels are connected horizontally\n * and vertically. Given the location (x, y) of one of the black pixels, return the area of the smallest\n * (axis-aligned) rectangle that encloses all black pixels.\n * https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/\n */\npublic class SmallestRectangleBlackPixel {\n    public int minArea(char[][] image, int x, int y) {\n\n        int m = image.length;\n        int n = image[0].length;\n\n        int left = searchColumns(image, 0, y, 0, m -  1, true);\n        int right = searchColumns(image, y, n - 1, 0, m - 1, false);\n\n        int top = searchRows(image, 0, x, left, right, true);\n        int bottom = searchRows(image, x, m - 1, left, right, false);\n\n        return (right - left + 1)*(bottom - top + 1);\n    }\n\n    private int searchColumns(char[][] image, int i, int j, int top, int bottom, boolean opt) {\n        int result = 0;\n        while (i <= j) {\n            int k = top;\n            int mid = (i + j)/2;\n            while (k <= bottom && image[k][mid] == '0') {\n                k++;\n            }\n            if (k != bottom + 1) {\n                result = mid;\n            }\n            if ((k == bottom + 1) == opt) {\n                i = mid + 1;\n            } else {\n                j = mid - 1;\n            }\n        }\n        return result;\n    }\n\n    private int searchRows(char[][] image, int i, int j, int left, int right, boolean opt) {\n        int result = 0;\n        while (i <= j) {\n            int k = left;\n            int mid = (i + j)/2;\n            while (k <= right && image[mid][k] == '0') {\n                k++;\n            }\n            if (k != right + 1) {\n                result = mid;\n            }\n            if ((k == right + 1) == opt) {\n                i = mid + 1;\n            } else {\n                j = mid - 1;\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        char[][] image1 = {{'1'},{'1'}};\n        char[][] image = {{'0', '0', '1', '0'}, {'0', '1', '1', '0'}, {'0', '1', '0', '0'}};\n        SmallestRectangleBlackPixel sbp = new SmallestRectangleBlackPixel();\n        System.out.print(sbp.minArea(image, 0, 2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/SpiralGeneration.java",
    "content": "package com.interview.multiarray;\n\n/**\n * Date 07/31/2016\n * @author Tushar Roy\n *\n * Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.\n *\n * https://leetcode.com/problems/spiral-matrix-ii/\n */\npublic class SpiralGeneration {\n    public int[][] generateMatrix(int n) {\n        int[][] result = new int[n][n];\n        int up = 0;\n        int down = n - 1;\n        int left = 0;\n        int right = n - 1;\n        int index = 1;\n        while (up <= down && left <= right) {\n            for (int i = left; i <= right; i++) {\n                result[up][i] = index++;\n            }\n            up++;\n\n            for (int i = up; i <= down; i++) {\n                result[i][right] = index++;\n            }\n            right--;\n\n            for (int i = right; i >= left; i--) {\n                result[down][i] = index++;\n            }\n            down--;\n\n            for (int i = down; i >= up; i--) {\n                result[i][left] = index++;\n            }\n            left++;\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        SpiralGeneration sg = new SpiralGeneration();\n        int[][] r = sg.generateMatrix(4);\n        for (int i = 0; i < r.length; i++) {\n            for (int j = 0; j < r[i].length; j++) {\n                System.out.print(r[i][j] + \" \");\n            }\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/SpiralPrinting.java",
    "content": "package com.interview.multiarray;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Date 03/15/2015 \n * @author Tushar Roy\n * \n * Given a 2D matrix(square or rectangular) print it in spiral way.\n * e.g 1 2 3\n *     4 5 6\n *     7 8 9 \n * Printing should be 1 2 3 6 9 8 7 4 5    \n *    \n * Solution:\n * Keep 4 pointers which are bounds for this matrix, up, down, left, right. Print each\n * row or column and keep incrementing and decrementing the bounds. As soon as up meets down\n * or left meets right we are done.\n * \n * Reference\n * https://leetcode.com/problems/spiral-matrix/\n * http://stackoverflow.com/questions/726756/print-two-dimensional-array-in-spiral-order\n * http://www.geeksforgeeks.org/print-a-given-matrix-in-spiral-form/\n */\npublic class SpiralPrinting {\n\n    public List<Integer> spiralOrder(int[][] matrix) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {\n            return Collections.EMPTY_LIST;\n        }\n\n        List<Integer> result = new ArrayList<>();\n        int left = 0;\n        int right = matrix[0].length - 1;\n        int up = 0;\n        int down = matrix.length - 1;\n\n        while (left <= right && up <= down) {\n            for (int i = left; i <= right; i++) {\n                result.add(matrix[up][i]);\n            }\n            up++;\n\n            for (int i = up; i <= down; i++) {\n                result.add(matrix[i][right]);\n            }\n            right--;\n\n            if (up <= down) {\n                for (int i = right; i >= left; i--) {\n                    result.add(matrix[down][i]);\n                }\n            }\n            down--;\n\n            if (left <= right) {\n                for (int i = down; i >= up; i--) {\n                    result.add(matrix[i][left]);\n                }\n            }\n            left++;\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        SpiralPrinting sp = new SpiralPrinting();\n        int[][] matrix = {{1, 2, 3}, {4, 5, 6}};\n        List<Integer> result = sp.spiralOrder(matrix);\n        System.out.print(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multiarray/TilingProblem.java",
    "content": "package com.interview.multiarray;\n\n/**\n * http://www.geeksforgeeks.org/divide-and-conquer-set-6-tiling-problem/\n * Test cases\n * Size of matrix is at least 2 and power of 2 always\n * Missing point could be on edges\n * Missing point could be in any of 4 quadrants\n */\n\nclass Position{\n    int x;\n    int y;\n    Position(int x, int y){\n        this.x = x;\n        this.y = y;\n    }\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + x;\n        result = prime * result + y;\n        return result;\n    }\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        Position other = (Position) obj;\n        if (x != other.x)\n            return false;\n        if (y != other.y)\n            return false;\n        return true;\n    }\n    \n}\n\npublic class TilingProblem {\n\n    char tileCount = 'a';\n    public char[][] fit(int size, Position missingPosition){\n        char matrix[][] = new char[size][size];\n        matrix[missingPosition.x][missingPosition.y] = 'X';\n        fit(matrix, new Position(0,0), matrix.length, missingPosition);\n        return matrix;\n    }\n    \n    private void fit(char matrix[][], Position topLeft,\n            int size, Position missingPosition){\n        if(size == 2){\n            updateMatrix(matrix, topLeft, missingPosition);\n            return;\n        }\n        Position alreadyFilledQuadrantPosition = determineQuadrant(topLeft, size, missingPosition);\n        updateMatrix(matrix, new Position(topLeft.x + size/2-1, topLeft.y + size/2-1), alreadyFilledQuadrantPosition);\n        for(int i=0 ; i < 2; i++){\n            for(int j=0; j < 2; j++){\n                Position newMissingPosition = new Position(topLeft.x + size/2 -1+i, topLeft.y + size/2 -1 + j);\n                if(newMissingPosition.equals(alreadyFilledQuadrantPosition)){\n                    fit(matrix, new Position(topLeft.x + i*size/2, topLeft.y + j*size/2) , size/2, missingPosition);\n                }else{\n                    fit(matrix, new Position(topLeft.x + i*size/2, topLeft.y + j*size/2) , size/2, newMissingPosition);\n                }\n            }\n        }\n    }\n    \n    private Position determineQuadrant(Position topLeft, int size, Position missingPosition){\n        for(int i = 0; i < 2; i++){\n            for(int j = 0; j < 2; j++){\n                if(missingPosition.x >= topLeft.x + i*size/2 && missingPosition.x <= topLeft.x + i*size/2 + size/2-1 &&\n                        missingPosition.y >= topLeft.y + j*size/2 && missingPosition.y <= topLeft.y + j*size/2 + size/2 -1){\n                        return new Position(topLeft.x+size/2 -1 +i, topLeft.y + size/2 - 1 + j);\n                }\n            }\n        }\n        throw new IllegalArgumentException(\"Something went wrong in determining quadrant\");\n    }\n    \n    private void updateMatrix(char matrix[][], Position topLeft, Position missingPosition){\n        for(int i=topLeft.x; i < topLeft.x + 2; i++){\n            for(int j=topLeft.y; j < topLeft.y + 2; j++){\n                if(i == missingPosition.x && j == missingPosition.y){\n                    continue;\n                }\n                matrix[i][j] = tileCount;\n            }\n        }\n        tileCount++;\n    }\n    \n    public static void main(String args[]){\n        TilingProblem tp = new TilingProblem();\n        Position p = new Position(5,6);\n        char matrix[][] = tp.fit(8, p);\n        for(int i=0; i < matrix.length; i++){\n            for(int j=0; j < matrix[0].length ; j++){\n                System.out.print(matrix[i][j] + \" \");\n            }\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/BoundedBlockingQueue.java",
    "content": " package com.interview.multithreaded;\n\nimport java.util.Optional;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.concurrent.locks.Condition;\nimport java.util.concurrent.locks.ReentrantLock;\n\n\n/**\n * Date 06/25/2015\n * @author tusroy\n * \n * Write a program to implement bounded blocking queue. This is similar to consumer producer problem\n * Properties of queue\n * 1) If queue is empty poll will wait with timeout till item is available\n * 2) If queue is full offer will wait with timeout till space is available\n */\npublic class BoundedBlockingQueue<T> {\n\n    private final Object[] items;\n    private int takeIndex;\n    private int putIndex;\n    private int count;\n    \n    private final ReentrantLock lock;\n    private final Condition notEmpty;\n    private final Condition notFull;\n    \n    /**\n     * @param size - Define the size of bounded blocking queue.\n     */\n    public BoundedBlockingQueue(int size){\n        items = new Object[size];\n        lock = new ReentrantLock();\n        notEmpty = lock.newCondition();\n        notFull = lock.newCondition();\n    }\n    \n    /**\n     * Poll an item from queue. If queue is empty wait with timeout till item is available\n     * @return Optional<T> depending on if item was polled or queue was empty\n     */\n    public Optional<T> poll(long timeout, TimeUnit timeUnit) throws InterruptedException{\n        long left = timeUnit.toNanos(timeout);\n        //acquire the lock on the lock object\n        lock.lockInterruptibly();\n        T t;\n        try{\n            //if count is 0 means there is no item to poll. Keep trying to poll\n            //till either item is available or left gets 0 or less which means its\n            //time to time out.\n            while(count == 0){\n                if(left <= 0){\n                    return Optional.empty();\n                }\n                //if queue is empty wait fir signal from notEmpty condition\n                left = notEmpty.awaitNanos(timeUnit.toNanos(left));\n            }\n            //dequeu the item.\n            t = dequeue();\n            //signal notFull since queue is not full anymore\n            notFull.signal();\n        } finally {\n            //unlock the lock object\n            lock.unlock();\n        }\n        return Optional.of(t);\n    }\n    \n    /**\n     * Offer item to queue. If queue is full wait with timeout till space is available.\n     * @param t - item to offer\n     * @param timeout - time out time\n     * @param timeUnit - time out unit\n     * @return - returns true if item was offered in queue successfully else false.\n     * @throws InterruptedException\n     */\n    public boolean offer(T t, long timeout, TimeUnit timeUnit) throws InterruptedException{\n        if(t == null) { \n            throw new IllegalArgumentException();\n        }\n   \n        long left = timeUnit.toNanos(timeout);\n        \n        //acquire lock on lock object\n        lock.lockInterruptibly();\n        try{\n            //keep trying if you do not have space available in queue or time out is reached.\n            while(count == items.length){\n                if(left <= 0){\n                    return false;\n                }\n                left = notFull.awaitNanos(timeUnit.toNanos(left));\n            }\n            //enqueue the item into the queue \n            enqueue(t);\n            //signal notEmpty condition since queue is not empty anymore\n            notEmpty.signal();\n        } finally {\n            //release the lock.\n            lock.unlock();\n        }\n        return true;\n    }\n    \n    private void enqueue(T t){\n        items[putIndex] = t;\n        if(++putIndex == items.length) {\n            putIndex = 0;\n        }\n        count++;\n    }\n    \n    @SuppressWarnings(\"unchecked\")\n    private T dequeue() {\n        T t = (T)items[takeIndex];\n        items[takeIndex] = null;\n        if(++takeIndex == items.length) { \n            takeIndex = 0;\n        }\n        count--;\n        return t;\n    }\n    \n    public static void main(String args[]) throws Exception{\n        verifyQueueWorks();\n    }\n    \n    public static void verifyQueueWorks() throws Exception{\n        BoundedBlockingQueue<Integer> queue = new BoundedBlockingQueue<>(30);\n        ExecutorService writeExecutors = Executors.newFixedThreadPool(10);\n        int TOTAL = 10000;\n        AtomicInteger result[] = new AtomicInteger[TOTAL];\n        AtomicInteger test = new AtomicInteger(0);\n        for(int i = 0; i < TOTAL; i++) { \n            writeExecutors.execute(() -> {\n                try {\n                    int val = test.getAndIncrement();\n                    result[val] = new AtomicInteger(1);\n                    while(true){\n                        if(queue.offer(val, (long)(Math.random()*100 + 1), TimeUnit.MILLISECONDS)){\n                            break;\n                        }\n                    }\n                } catch (InterruptedException e) {\n                    System.out.println(\"Shutting down read thread\");\n                }\n            });\n        }\n        \n        ExecutorService readExecutors = Executors.newFixedThreadPool(10);\n        for(int i = 0; i < TOTAL; i++) { \n            readExecutors.execute(() -> {\n                try {\n                    while(true){\n                        Optional<Integer> r = queue.poll((long)(Math.random()*1000 + 1), TimeUnit.MILLISECONDS);\n                        if(r.isPresent()) {\n                            result[r.get()].incrementAndGet();\n                        }\n                    }\n                } catch (InterruptedException e) {\n                    System.out.println(\"Shutting down read thread\");\n                }\n            });\n        }\n        \n        //you can replace this with countdown latch. But I do not feel like writing all that code.\n        Thread.sleep(10000);\n        System.out.println(\"Validating result after reasonable wait\");\n        \n        //if queue worked as expected all integers in result array should have value 2.\n        for(int i=0; i < result.length; i++){\n            if(result[i].get() != 2){\n                throw new RuntimeException(String.valueOf(i));\n            }\n        }\n        \n        System.out.println(\"Shutting down executors\");\n        //force shutdown on read/write executor\n        readExecutors.shutdownNow();\n        writeExecutors.shutdownNow();\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/CountingWord.java",
    "content": "package com.interview.multithreaded;\n\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ConcurrentMap;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.atomic.AtomicLong;\n\n/**\n * Date 03/05/2015\n * @author tusroy\n * \n * Write a program to count words. This program should be threadsafe.\n * Implement two apis \n * 1) void addWord(String word) -> increment count of this word\n * 2) long getCount(String word) -> get count of this word\n * \n * Solution\n * Keep a concurrent map. Key to this map should be word while value should be AtomicLong to update it\n * in threadsafe way\n * \n * Test cases\n * One word updated by many threads\n * Many words updated by many threads\n *\n *@Threadsafe\n */\npublic class CountingWord {\n\n    private ConcurrentMap<String, AtomicLong> map = new ConcurrentHashMap<>();\n   \n    public void addWord(String word){\n        AtomicLong l = map.get(word);\n        if(l == null){\n            l = new AtomicLong(1);\n            l = map.putIfAbsent(word, l);\n            if(l != null){\n                l.incrementAndGet();\n            }\n        }else{\n            l.incrementAndGet();\n        }\n    }\n    \n    public long getCount(String word){\n        AtomicLong l = map.get(word);\n        if(l != null){\n            return l.longValue();\n        }\n        return 0;\n    }\n    \n    public static void main(String args[]) throws InterruptedException{\n        ExecutorService executor1 = Executors.newFixedThreadPool(20);\n        ExecutorService executor2 = Executors.newFixedThreadPool(20);\n        ExecutorService executor3 = Executors.newFixedThreadPool(20);\n     \n        int total = 100000;\n        CountDownLatch countDownLatch = new CountDownLatch(3*total);\n        CountingWord cw = new CountingWord();\n        for(int i= 0; i < total; i++){\n            executor1.execute(() -> cw.addWord(\"word1\"));\n            countDownLatch.countDown();\n        }\n        for(int i= 0; i < total; i++){\n            executor2.execute(() -> cw.addWord(\"word2\"));\n            countDownLatch.countDown();\n        }\n        for(int i= 0; i < total; i++){\n            executor3.execute(() -> cw.addWord(\"word3\"));\n            countDownLatch.countDown();\n        }\n        \n        try {\n            countDownLatch.await();\n        } catch (InterruptedException e) {\n            throw e;\n        }\n        executor1.shutdownNow();\n        executor2.shutdownNow();\n        executor3.shutdownNow();\n        \n        long count1 = cw.getCount(\"word1\");\n        long count2 = cw.getCount(\"word2\");\n        long count3 = cw.getCount(\"word3\");\n        assert count1 == total;\n        assert count2 == total;\n        assert count3 == total;\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/DependencyTaskExecutor.java",
    "content": "package com.interview.multithreaded;\n\nimport com.google.common.collect.Lists;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.RunnableFuture;\n\n/**\n * Given a Task with list of its dependencies and execute method. Run the task such that dependencies are executed first.\n * You are given x number of threads. Increase parallelism as much as possible.\n */\npublic class DependencyTaskExecutor {\n\n    Map<String, CompletableFuture<Void>> taskTracker = new HashMap<>();\n    void scheduleTask(List<Task> tasks, int threads) {\n        ExecutorService executor = Executors.newFixedThreadPool(threads);\n        CompletableFuture<Void> future = CompletableFuture.completedFuture(null);\n        for (Task task : tasks) {\n            future = future.thenAcceptBothAsync(scheduleTaskUtil(task, executor), (a, b) -> {}, executor);\n        }\n        future.thenRunAsync(() -> {System.out.println(\"All tasks done. Closing executor\"); executor.shutdown();});\n    }\n\n    CompletableFuture<Void> scheduleTaskUtil(Task task, Executor executor) {\n        CompletableFuture<Void> f = taskTracker.get(task.name());\n        if (f != null) {\n            return f;\n        }\n        if (task.dependencies().isEmpty()) {\n            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> task.execute(), executor);\n            taskTracker.put(task.name(), future);\n            return future;\n        }\n        CompletableFuture<Void> future = CompletableFuture.completedFuture(null);;\n        for (Task upstreamTask : task.dependencies()) {\n            future = future.thenAcceptBothAsync(scheduleTaskUtil(upstreamTask, executor), (a, b) -> {}, executor);\n        }\n        future = future.thenRunAsync(() -> task.execute(), executor);\n        taskTracker.put(task.name(), future);\n        return future;\n    }\n\n    public static void main(String args[]) {\n        DependencyTaskExecutor taskExecutor = new DependencyTaskExecutor();\n        SimpleSleepTask a = new SimpleSleepTask(\"a\", 2000);\n        SimpleSleepTask b = new SimpleSleepTask(\"b\", 4000);\n        SimpleSleepTask c = new SimpleSleepTask(\"c\", 6000);\n        SimpleSleepTask d = new SimpleSleepTask(\"d\", 3000);\n        SimpleSleepTask x = new SimpleSleepTask(\"x\", 4000);\n        SimpleSleepTask y = new SimpleSleepTask(\"y\", 6000);\n        SimpleSleepTask z = new SimpleSleepTask(\"z\", 3000);\n\n        d.addDependency(b);\n        d.addDependency(c);\n        c.addDependency(a);\n        b.addDependency(a);\n        x.addDependency(y);\n        x.addDependency(z);\n        y.addDependency(a);\n        taskExecutor.scheduleTask(Lists.newArrayList(a, b, c, d, x, y, z), 4);\n    }\n}\n\ninterface Task {\n    String name();\n    List<Task> dependencies();\n    void execute();\n}\n\nclass SimpleSleepTask implements Task {\n    String name;\n    int sleepTimeInMillis;\n    List<Task> dependencies = new ArrayList<>();\n    SimpleSleepTask(String name, int sleepTimeInMillis) {\n        this.name = name;\n        this.sleepTimeInMillis = sleepTimeInMillis;\n    }\n\n    void addDependency(Task task) {\n        dependencies.add(task);\n    }\n\n    @Override\n    public String name() {\n        return name;\n    }\n\n    @Override\n    public List<Task> dependencies() {\n        return dependencies;\n    }\n\n    @Override\n    public void execute() {\n        try {\n            System.out.println(\"Starting sleep for task \" + name);\n            Thread.sleep(sleepTimeInMillis);\n            System.out.println(\"Ending sleep for task \" + name);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}\n\nclass FutureTask implements Runnable {\n\n    Task task;\n    List<FutureTask> chainedTasks = new ArrayList<>();\n    Executor executor;\n    FutureTask(Task task, Executor executor) {\n        this.task = task;\n        this.executor = executor;\n    }\n    @Override\n    public void run() {\n        task.execute();\n        for (FutureTask t : chainedTasks) {\n            supplyAsync(t, executor);\n        }\n    }\n\n    void supplyAsync(FutureTask task, Executor executor) {\n        executor.execute(task);\n    }\n\n    void addChain(FutureTask task) {\n        task.addChain(this);\n    }\n\n\n}"
  },
  {
    "path": "src/com/interview/multithreaded/FillupMatrix.java",
    "content": "package com.interview.multithreaded;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicLong;\n\n/**\n * Date 03/05/2015\n * @author tusroy\n * \n * Write a program which fills up boolean matrix from top left to bottom right with true. \n * This program should support two apis\n * 1) void updateMatrix() which updates last position of matrix with true\n * 2) boolean getVal(int x,int y) return boolean val at matrix[x][y]\n * \n * This program should be threadsafe.\n * \n * Solution\n * Use AtomicLong to increment the value and return old value.\n * \n * Test cases\n * 1) Try with single thread\n * 2) Try with multiple threads and big matrix size.\n *\n */\npublic class FillupMatrix {\n\n    private boolean matrix[][];\n    private int size;\n    private AtomicLong pos;\n    public FillupMatrix(int size){\n        matrix = new boolean[size][size];\n        this.size = size;\n        pos = new AtomicLong(-1);\n    }\n    \n    public void updateMatrix(){\n        long pos = next();\n        updateMatrix(pos);\n    }\n    \n    private void updateMatrix(long pos){\n        if(pos >= size*size){\n            throw new IllegalArgumentException(\"Out of memory\");\n        }\n        matrix[(int)(pos/size)][(int)(pos%size)] = true;\n    }\n    \n    private long next(){\n        long val = pos.incrementAndGet();\n        return val;\n    }\n    \n    public boolean getVal(int x, int y){\n        return matrix[x][y];\n    }\n    \n    public static void main(String args[]) throws InterruptedException{\n        int size = 5000;\n        FillupMatrix fum = new FillupMatrix(size);\n        ExecutorService executor = Executors.newFixedThreadPool(10);\n        for(int i=0; i < size*size ; i++){\n            executor.execute(() -> fum.updateMatrix());\n        }\n        \n        executor.shutdown();\n        executor.awaitTermination(10, TimeUnit.SECONDS);\n        for(int i=0; i < size ; i++){\n            for(int j=0; j < size; j++){\n                assert fum.getVal(i, j);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/MinMaxKeeper.java",
    "content": "package com.interview.multithreaded;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ThreadLocalRandom;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Date 03/05/2015\n * @author tusroy\n * \n * Write a program which keeps min and max value in threadsafe way\n * Support 2 apis\n * void updateMaxMin(int val)\n * int getMin()\n * int getMax()\n * \n * Solution\n * Use compareAndSet method of AtomicInteger to update min and max\n *\n * @ThreadSafe\n */\npublic class MinMaxKeeper {\n\n    private AtomicInteger min = new AtomicInteger(Integer.MAX_VALUE);\n    private AtomicInteger max = new AtomicInteger(Integer.MIN_VALUE);\n    \n    /**\n     * Threadsafe way of updating min and max\n     * @param value\n     */\n    public void updateMinMax(int value){\n        //update min\n        while(true){\n            //if value is greater than whatever is in min just break right away\n            int minVal = min.get();\n            if(value >= minVal){\n                break;\n            }\n            //try to update value only if minVal is in min\n            boolean isSetSuccesful = min.compareAndSet(minVal, value);\n            //if set was successful break from while loop else keep looping\n            if(isSetSuccesful){\n                break;\n            }\n        }\n        \n        //update max\n        while(true){\n            int maxVal = max.get();\n            if(value <= maxVal){\n                break;\n            }\n            boolean isSetSuccesful = max.compareAndSet(maxVal, value);\n            if(isSetSuccesful){\n                break;\n            }\n        }\n    }\n    \n    public int getMin(){\n        return min.get();\n    }\n    \n    public int getMax(){\n        return max.get();\n    }\n    \n    public static void main(String args[]) throws InterruptedException{\n        ExecutorService executors = Executors.newFixedThreadPool(100);\n        MinMaxKeeper mmKeeper = new MinMaxKeeper();\n        \n        for(int i=0 ; i < 100000; i++){\n            GenerateRand rand = new GenerateRand(mmKeeper, i);\n            executors.execute(rand);\n        }\n        \n        executors.shutdown();\n        executors.awaitTermination(10, TimeUnit.SECONDS);\n        \n        assert mmKeeper.getMin() == -1;\n        assert mmKeeper.getMax() == 1000001;\n    }\n\n    static class GenerateRand implements Runnable{\n        int index = 0;\n        MinMaxKeeper mmKeeper;\n        public GenerateRand(MinMaxKeeper mmKeeper, int index) {\n            this.index = index;\n            this.mmKeeper = mmKeeper;\n        }\n        @Override\n        public void run() {\n            int rand = ThreadLocalRandom.current().nextInt(1000000);\n            if(index == 999){\n                rand = -1;\n            }\n            if(index == 1001){\n                rand = 1000001;\n            }\n            mmKeeper.updateMinMax(rand);\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/PrintInSequence.java",
    "content": "package com.interview.multithreaded;\n\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\n\n/**\n * A class that has 5 threads - two to increment the myVar variable, two to decrement the myVar variable and one to print the value of myVar.\n * Implement increment(), decrement() and printVar() methods such that the following series is printed:\n * 0 1 2 3 4 5 4 3 2 1 0 1 2 3 4 5 4 3 2 1 ... (repeating)\n */\npublic class PrintInSequence {\n\n    private volatile int val = 0;\n    private volatile boolean shouldPrint = true;\n    private volatile boolean isIncreasing = true;\n    private ReentrantReadWriteLock.WriteLock lock = new ReentrantReadWriteLock().writeLock();\n    public void increment() {\n        lock.lock();\n        if (!shouldPrint && isIncreasing) {\n            val = val + 1;\n            if (val == 5) {\n                isIncreasing = false;\n            }\n            shouldPrint = true;\n        }\n        lock.unlock();\n    }\n\n    public void decrement() {\n        lock.lock();\n        if (!shouldPrint && !isIncreasing) {\n            val = val - 1;\n            if (val == 0) {\n                isIncreasing = true;\n            }\n            shouldPrint = true;\n        }\n        lock.unlock();\n    }\n\n    //only one thread is calling print. So no contention in updating shouldPrint flag.\n    public void printVar() {\n        if (shouldPrint) {\n            System.out.println(val);\n            shouldPrint = false;\n        }\n    }\n\n    public static void main(String args[]) {\n        PrintInSequence printInSequence = new PrintInSequence();\n        Thread t1 = new Thread(printInSequence::runIncrement);\n        t1.start();\n        Thread t2 = new Thread(printInSequence::runIncrement);\n        t2.start();\n        Thread t3 = new Thread(printInSequence::runPrint);\n        t3.start();\n        Thread t4 = new Thread(printInSequence::runDecrement);\n        t4.start();\n        Thread t5 = new Thread(printInSequence::runDecrement);\n        t5.start();\n    }\n\n    private void runIncrement() {\n        while(true) {\n            this.increment();\n        }\n    }\n\n    private void runPrint() {\n        while (true) {\n            this.printVar();\n        }\n    }\n\n    private void runDecrement() {\n        while (true) {\n            this.decrement();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/RealTimeCounter.java",
    "content": "package com.interview.multithreaded;\n\nimport java.util.Random;\nimport java.util.Timer;\nimport java.util.TimerTask;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.atomic.AtomicLongArray;\n\n/**\n * Date 03/03/2015\n * @author tusroy\n *\n * Develop a software to count number of events in last 5 mins. You have to support two apis\n * 1) addEvent() -> It means increment event by 1\n * 2) getTotalEvents() -> Return total number of events in last 5 mins\n * \n * Program should support millions of events every minute and should also provide multi-threading support\n * \n * This class might not have 100% accuracy as far as events in last 5 mins are concerned. \n * Since we are using circular queue last second information may not be very accurate.\n * \n * Solution:\n * Keep atomiclong of 300 in array. PositionUpdater updates position every second.\n * @Threadsafe\n */\npublic class RealTimeCounter {\n\n    private final static int GRANULARITY = 300;\n    private AtomicLongArray counter = new AtomicLongArray(GRANULARITY);\n    private volatile int pos = 0;\n    \n    private RealTimeCounter(){\n        PositionUpdater positionUpdater = new PositionUpdater(this);\n        positionUpdater.start();\n    }\n    \n    private static volatile RealTimeCounter INSTANCE;\n    \n    public static RealTimeCounter getInstance(){\n        if(INSTANCE == null){\n            synchronized (RealTimeCounter.class) {\n                if(INSTANCE == null){\n                    INSTANCE = new RealTimeCounter();\n                }\n            }\n        }\n        return INSTANCE;\n    }\n    \n    public long getTotalEvents(){\n        int total = 0;\n        for(int i=0; i < GRANULARITY; i++){\n            total += counter.get(i);\n        }\n        return total;\n    }\n    \n    public void addEvent(){\n        counter.getAndIncrement(pos);\n    }\n    \n    void incrementPosition(){\n        //first reset the value to 0 at next counter location.\n        counter.set((pos + 1)%GRANULARITY, 0);\n        pos = (pos + 1)%GRANULARITY;\n    }\n    \n    public static void main(String args[]){\n        ExecutorService executor = Executors.newFixedThreadPool(10);\n        RealTimeCounter realTimeCounter = new RealTimeCounter();\n        final Random random = new Random();\n        final int TOTAL_EVENTS = 10000;\n        CountDownLatch countDownLatch = new CountDownLatch(TOTAL_EVENTS);\n        for(int i=0; i < TOTAL_EVENTS; i++){\n            executor.execute(() -> {\n                realTimeCounter.addEvent();\n                try {\n                    Thread.sleep(random.nextInt(10));\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n                countDownLatch.countDown();\n            }\n            );\n        }\n        try{\n            countDownLatch.await();\n        }catch(Exception e){\n            \n        }\n        System.out.println(realTimeCounter.getTotalEvents());\n        executor.shutdownNow();\n    }\n}\n\nclass PositionUpdater extends TimerTask{\n\n    private final RealTimeCounter realTimeCounter;\n    private final Timer timer = new Timer(true);\n    private static final int DELAY = 1000;\n    PositionUpdater(RealTimeCounter realTimeCounter) {\n        this.realTimeCounter = realTimeCounter;\n    }\n    \n    public void start(){\n        timer.schedule(this, DELAY);\n    }\n    @Override\n    public void run() {\n        realTimeCounter.incrementPosition();\n    }\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/SingleQueueDomainTableUpdate.java",
    "content": "package com.interview.multithreaded;\n\nimport java.util.Queue;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ConcurrentMap;\n\n/**\n * Given a queue which gets millions of messages. Message is of form <Domain,Update>.\n * You have 10000 domain tables. Also you have 50 worker threads. You can only get \n * data from front of the queue. Threads get data from the front and then update the \n * domain table. If work is being done on domain table you cannot apply another update.\n * Update should also be applied sequentially. So an update coming later on should not\n * be applied before an update coming sooner.\n */\n\nclass Data{\n    private String domain;\n    private String update;\n    public String getUpdate() {\n        return update;\n    }\n    public String getDomain() {\n        return domain;\n    }\n}\n\ninterface DomainLock{\n    boolean acquireLock(String domain);\n    boolean releaseLock(String domain);\n    boolean isLocked(String domain);\n}\n\nclass ThreadPoolManager{\n    private ConcurrentMap<String, Queue<Data>> domainQueueMap = new ConcurrentHashMap<>();\n    public ThreadPoolManager(int numOfThreads){\n        //initialize numOfThreads of type ThreadWorker;\n    }\n}\n\ninterface DatabaseLayer{\n    public void applyUpdates(String domain,String update);\n}\n\nclass ThreadWorker implements Runnable{\n\n    private QueueManager mgr;\n    private ConcurrentMap<String,Queue<Data>> domainQueueMap;\n    private DomainLock domainLock;\n    private DatabaseLayer databaseLayer;\n    public ThreadWorker(QueueManager mgr){\n        this.mgr = mgr;\n    }\n    @Override\n    public void run() {\n        while(true){\n            Pair p = mgr.getDataFromFrontOfQueue(domainLock);\n            if(p.yourLock){\n                Queue<Data> queue = domainQueueMap.get(p.data.getDomain());\n                if(queue != null){\n                    while(queue.size() > 0){\n                        Data data = queue.poll();\n                        databaseLayer.applyUpdates(data.getDomain(), data.getUpdate());\n                    }\n                }\n                databaseLayer.applyUpdates(p.data.getDomain(), p.data.getUpdate());\n                queue = domainQueueMap.get(p.data.getDomain());\n                if(queue != null){\n                    while(queue.size() > 0){\n                        Data data = queue.poll();\n                        databaseLayer.applyUpdates(data.getDomain(), data.getUpdate());\n                    }\n                }\n                domainLock.releaseLock(p.data.getDomain());\n                //check if queue is not empty\n                //if queue is not empty try to acquire lock again\n            }else{\n                if(domainQueueMap.containsKey(p.data.getDomain())){\n                    Queue<Data> queue = domainQueueMap.get(p.data.getDomain());\n                    queue.offer(p.data);\n                }\n            }\n        }\n    }\n    \n}\n\ninterface QueueHandle{\n    //this is a blocking call. If there is no data in the queue it just waits for data to be available\n    public Data getNextData();\n}\n\nclass Pair{\n    Data data;\n    boolean yourLock;\n}\n\nclass QueueManager{\n    private QueueHandle queueHandle;\n    public QueueManager(QueueHandle queueHandle){\n        this.queueHandle = queueHandle;\n    }\n    \n    public synchronized Pair getDataFromFrontOfQueue(DomainLock domainLock){\n        Data data = queueHandle.getNextData();\n        boolean yourLock = false;\n        //if lock for table does not exists or if it is false lock the table\n        if(!domainLock.isLocked(data.getDomain())){\n            domainLock.acquireLock(data.getDomain());\n            yourLock = true;\n        }\n        Pair p = new Pair();\n        p.data = data;\n        p.yourLock = yourLock;\n        return p;\n    }\n}\npublic class SingleQueueDomainTableUpdate {\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/SpinLockMutex.java",
    "content": "package com.interview.multithreaded;\n\n/**\n * Design a mutex using 2 variable method assuming operation ice happens atomically\n */\nclass Mutex {\n\n    int val = 0;\n\n    /**\n     * Val is stored somewhere. If oldVal is same as val\n     * then you change val to newVal and return oldVal\n     * Otherwise you do nothing but return val\n     * @param oldValue\n     * @param newValue\n     * @return\n     */\n    private synchronized int ice(int oldValue, int newValue) {\n        if (oldValue == val) {\n            val = newValue;\n            return oldValue;\n        } else {\n            return val;\n        }\n    }\n\n    void acquireLock() {\n        while (ice(0, 1) != 0);\n    }\n\n    void releaseLock() {\n        ice(1, 0);\n    }\n\n}\n\npublic class SpinLockMutex {\n\n    StringBuffer buff = new StringBuffer();\n\n    // some method needs mutex protection\n    public void changeBuffer(String str) {\n        buff.append(str);\n    }\n\n    public String getBuffer() {\n        return buff.toString();\n    }\n\n    public static void main(String args[]) throws Exception{\n        SpinLockMutex slm = new SpinLockMutex();\n        Mutex m = new Mutex();\n        Thread t1 = new Thread(() -> {\n            for (int i = 0; i < 10; i++) {\n                m.acquireLock();\n                slm.changeBuffer(\"a\" + i);\n                m.releaseLock();\n            }\n        });\n\n        Thread t2 = new Thread(() -> {\n            for (int i = 0; i < 10; i++) {\n                m.acquireLock();\n                slm.changeBuffer(\"b\" + i);\n                m.releaseLock();\n            }\n        });\n\n        t1.start();\n        t2.start();\n        try {\n            t1.join();\n            t2.join();\n        } catch (InterruptedException e) {\n            throw e;\n        }\n        System.out.println(slm.getBuffer());\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/ThreadPoolExample.java",
    "content": "package com.interview.multithreaded;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ArrayBlockingQueue;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.CompletionService;\nimport java.util.concurrent.ExecutorCompletionService;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\n\npublic class ThreadPoolExample {\n\n    private static BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(10);\n    public static ExecutorService threadPool =  Executors.newFixedThreadPool(5);\n    public void doWork() throws Exception{\n        CompletionService<String> completionService = new ExecutorCompletionService<String>(threadPool);\n        List<Future<String>> futureList = new ArrayList<Future<String>>();\n        for(int i=0; i < 20; i++){\n            futureList.add(completionService.submit(new Count10(i)));\n        }\n        for(int i=0; i < 20; i++){\n            Future<String> future = completionService.take();\n            System.out.println(future.get());\n        }\n    }\n    \n    public static void main(String args[]) throws Exception{\n        ThreadPoolExample tpe = new ThreadPoolExample();\n        tpe.doWork();\n    }\n    \n}\n\nclass Count10 implements Callable<String>{\n\n    private int index = 0;\n    Count10(int i){\n        index = i;\n    }\n    @Override\n    public String call() throws Exception {\n  //      for(int i=0; i < 10; i++){\n            int sleepTime = 5000 + 1;\n            try {\n             \n                System.out.println(\"Before sleep \" + index);\n                Thread.sleep(sleepTime);\n                System.out.println(\"After sleep \" + index);\n                \n            } catch (InterruptedException e) {\n                // TODO Auto-generated catch block\n                e.printStackTrace();\n            }\n //       }\n        return \"Done\" + index;\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/multithreaded/ThreadPoolImpl.java",
    "content": "package com.interview.multithreaded;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\n\nclass ThreadPool {\n\n    public Thread run(Runnable runnable) {\n        Thread t = new Thread(runnable);\n        t.start();\n        return t;\n    }\n}\n\n/**\n * Facebook interview question\n * Implement a non block run which takes as many runnables as given but only\n * runs a specified number of threads.\n * You can also update maxSize in between which will change number of threads executing\n * http://tutorials.jenkov.com/java-concurrency/thread-pools.html\n */\npublic class ThreadPoolImpl {\n\n    private int maxSize = 0;\n    ThreadPool threadPool;\n\n    public ThreadPoolImpl(int size, ThreadPool threadPool) {\n        maxSize = size;\n        this.threadPool = threadPool;\n    }\n    \n    public void setMax(int size){\n        System.out.print(\"Setting max size \" + size);\n        if(maxSize == 0){\n            maxSize = size;\n            execute();\n        }else{\n            maxSize = size;\n        }\n    }\n\n    private int currentSize = 0;\n    private Queue<Runnable> waitingThreads = new LinkedList<Runnable>();\n    private boolean isExecuting = false;\n    private Object monitor = new Object();\n\n    public void run(Runnable thread) {\n        synchronized (monitor) {\n            waitingThreads.offer(thread);\n            execute();\n        }\n    }\n\n    private void execute() {\n        if (!isExecuting) {\n            isExecuting = true;\n            ExecutingRunnable runnable = new ExecutingRunnable();\n            threadPool.run(runnable);\n        }\n    }\n\n    class ExecutingRunnable implements Runnable {\n        @Override\n        public void run() {\n            while (true) {\n                synchronized(monitor){\n                    if(maxSize ==0){\n                        isExecuting = false;\n                        break;\n                    }\n                }\n                while (waitingThreads.size() > 0) {\n                    synchronized(monitor){\n                        if(maxSize ==0){\n                            isExecuting = false;\n                            break;\n                        }\n                    }\n                    if (currentSize < maxSize) {\n                        currentSize++;\n                        Runnable run = waitingThreads.poll();\n                        RunnableThreads r = new RunnableThreads(run);\n                        threadPool.run(r);\n                    }\n                }\n                synchronized (monitor) {\n                    if (waitingThreads.size() == 0) {\n                        isExecuting = false;\n                        break;\n                    }\n                }\n//              System.out.println(\"Looping\");\n            }\n        }\n\n    }\n\n    class RunnableThreads implements Runnable {\n        private Runnable r;\n\n        RunnableThreads(Runnable r) {\n            this.r = r;\n        }\n\n        @Override\n        public void run() {\n            r.run();\n            currentSize--;\n        }\n    }\n    \n    public static void main(String args[]) throws InterruptedException{\n        ThreadPool threadPool = new ThreadPool();\n        ThreadPoolImpl impl = new ThreadPoolImpl(4, threadPool);\n        int i;\n        for(i=0; i < 10; i++){\n            MyRunnable runnable = new MyRunnable(i);\n            impl.run(runnable);\n        }\n        Thread.sleep(5000);\n        impl.setMax(0);\n        Thread.sleep(10000);\n        impl.setMax(6);\n        for(;i < 15;i++){\n            MyRunnable runnable = new MyRunnable(i);\n            impl.run(runnable);\n        }\n    }\n}\n\nclass MyRunnable implements Runnable{\n    int index = 0;\n    MyRunnable(int index){\n        this.index =index;\n    }\n    @Override\n    public void run() {\n        System.out.println(\"Start of index \" + index);\n        try {\n            Thread.sleep(3000);\n        } catch (InterruptedException e) {\n            System.out.println(\"Exception \" + index + \" \" + e);\n        }\n        System.out.println(\"End of index \" + index);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/number/AggregateNumber.java",
    "content": "package com.interview.number;\n\n/**\n * Number such that 11 + 11 = 22, 11 +22 = 33, 22 +33 = 55\n * so 1111223355 is aggregate number\n */\npublic class AggregateNumber {\n\n    //assumption is that numbers in array are single digit non-negative number(0..9)\n    public boolean isAggregate(int[] number){\n        if(number.length < 3){\n            return false;\n        }\n        int prev = 0;\n        for(int i=1; i <= number.length/2; i++){\n            for(int j=0; j <i; j++){\n                int num1 = getNumber(number, prev, j);\n                int num2 = getNumber(number,j+1,i);\n                int start = i+1;\n                boolean flag = false;\n                int k = start;\n                for(; k < number.length; k++){\n                    int num3 = getNumber(number, start, k);\n                    if(num1 + num2 < num3){\n                        break;\n                    }\n                    if(num1 + num2 == num3){\n                        num1 = num2;\n                        num2 = num3;\n                        flag = true;\n                        start = k+1;\n                    }else{\n                        flag = false;\n                    }\n                }\n                if(k == number.length && flag){\n                    return true;\n                }\n                flag = false;\n            }\n        }\n        return false;\n    }\n    \n    private int getNumber(int[] number, int start, int end){\n        int total = 0;\n        for(int i = start; i <= end; i++){\n            total *= 10;\n            total += number[i];\n        }\n        return total;\n    }\n    \n    public static void main(String args[]){\n        AggregateNumber an = new AggregateNumber();\n        int number[] = {1,1,2,2,3,3,5,5,8,8,1,4,3}; //true 11 + 22 == 33(+22) = 55(+33) = 88(+55) = 143\n        int number1[] = {1,1,2,2,3,3,5,5,8,8,1,4,4};//false 11 + 22 == 33(+55) = 88(+55) != 144 \n        int number2[] = {1,1,2,2,3,2,3,4}; //true 11 + 223 = 234\n        int number3[] = {1,1,2,2,3,2,3,4,4,5,7}; //true 11 + 223 = 234(+223)=457\n        System.out.println(an.isAggregate(number));\n        System.out.println(an.isAggregate(number1));\n        System.out.println(an.isAggregate(number2));\n        System.out.println(an.isAggregate(number3));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/AllStrobogrammaticNumber.java",
    "content": "package com.interview.number;\n\n/**\n * Date 04/17/2016\n * @author Tushar Roy\n *\n * A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down).\n * Write a function to count the total strobogrammatic numbers that exist in the range of low <= num <= high.\n *\n * https://leetcode.com/problems/strobogrammatic-number-iii/\n */\npublic class AllStrobogrammaticNumber {\n    private static char[][] pairs = {{'6', '9'}, {'9', '6'}, {'0', '0'}, {'1', '1'}, {'8', '8'}};\n\n    public int strobogrammaticInRange(String low, String high) {\n        int count = 0;\n        for (int i = low.length(); i <= high.length(); i++) {\n            char[] result = new char[i];\n            count += strobogrammaticInRangeUtil(low, high, 0, result.length - 1, result);\n        }\n        return count;\n    }\n\n    private int strobogrammaticInRangeUtil(String low, String high, int left, int right, char[] result) {\n        if (left > right) {\n            String r = new String(result);\n            if ((r.length() == low.length() && low.compareTo(r) > 0) || (high.length() == result.length && high.compareTo(r) < 0)) {\n                return 0;\n            }\n            return 1;\n        }\n\n        int count = 0;\n\n        for (char[] pair : pairs) {\n            result[left] = pair[0];\n            result[right] = pair[1];\n            //number should not start with 0 if its length is greater than 0\n            if (result.length != 1 && result[0] == '0') {\n                continue;\n            }\n            //if left == right then we got to make sure we dont pick pair 6, 9 or 9, 6\n            if ((left < right) || (left == right && pair[0] == pair[1])) {\n                count += strobogrammaticInRangeUtil(low, high, left + 1, right - 1, result);\n            }\n        }\n        return count;\n    }\n}"
  },
  {
    "path": "src/com/interview/number/ArithemeticProgressionExists.java",
    "content": "package com.interview.number;\n\n/**\n * http://www.geeksforgeeks.org/length-of-the-longest-arithmatic-progression-in-a-sorted-array/\n */\npublic class ArithemeticProgressionExists {\n\n    public boolean exists(int input[]){\n        \n        for(int i=1; i < input.length-1; i++){\n            int j = i-1;\n            int k = i+1;\n            while(j >=0 && k <= input.length-1){\n                if(input[i]*2 == input[j] + input[k]){\n                    return true;\n                }else if(input[i]*2 > input[j] + input[k]){\n                    k++;\n                }else{\n                    j--;\n                }\n            }\n        }\n        return false;\n    }\n    public static void main(String args[]){\n        int input[] = {1,3,6,7,10,11,15};\n        ArithemeticProgressionExists ape = new ArithemeticProgressionExists();\n        System.out.println(ape.exists(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/ArrayMultiplication.java",
    "content": "package com.interview.number;\n\nimport com.interview.array.ArrayAddition;\n\npublic class ArrayMultiplication {\n\n    public int[] multiplyDivideAndConquer(int arr1[],int arr2[],int low1,int high1,int low2,int high2){\n        \n        if(low1 == high1 || low2 == high2){\n            return simpleMultiplication(arr1, arr2, low1, high1, low2, high2);\n        }\n        \n        int mid1 = (low1 + high1)/2;\n        int mid2 = (low2 + high2)/2;\n        \n        int r1[] = multiplyDivideAndConquer(arr1,arr2,low1,mid1,low2,mid2);\n        int shiftBy = high1-mid1 + high2-mid2;\n        r1 = shift(r1,shiftBy);\n        \n        int r2[] = multiplyDivideAndConquer(arr1,arr2,mid1+1,high1,mid2+1,high2);\n        \n        int r3[] = multiplyDivideAndConquer(arr1,arr2,low1,mid1,mid2+1,high2);\n        shiftBy = high1 - mid1;\n        r3 = shift(r3,shiftBy);\n        \n        int r4[] = multiplyDivideAndConquer(arr1,arr2,mid1+1,high1,low2,mid2);\n        shiftBy = high2 - mid2;\n        r4 = shift(r4,shiftBy);\n        \n        ArrayAddition aa = new ArrayAddition();\n        r1 = aa.add(r1, r2);\n        r1 = aa.add(r1, r3);\n        r1 = aa.add(r1, r4);\n        return r1;\n        \n    }\n    \n    private int[] shift(int arr[],int n){\n        int[] result = new int[arr.length + n];\n        int i=0;\n        for(i=0; i < arr.length; i++){\n            result[i] = arr[i];\n        }\n        return result;\n    }\n    \n    public int[] simpleMultiplication(int arr1[],int arr2[],int low1,int high1,int low2,int high2){\n        \n        int[] result = new int[high1-low1 + high2 -low2 + 2];\n        \n        int m=0;\n        int c=0;\n        int n =0;\n        int index = result.length-1;\n        int temp[] = new int[Math.max(high1-low1+1, high2-low2+1)+1];\n        for(int i= high1; i >=low1; i--){\n            int l = temp.length-1;\n            for(int j=high2; j>=low2; j--){\n                m = arr1[i]*arr2[j] + c;\n                n = m%10;\n                temp[l--] = n;\n                c = m/10;\n            }\n            temp[l] = c;\n            addToResult(result,temp,index);\n            index--;\n            c=0;\n            for(int t=0; t < temp.length; t++){\n                temp[t] = 0;\n            }\n        }\n        return result;\n    }\n    \n    private void addToResult(int[] result,int temp[],int start){\n        int c=0;\n        for(int i=temp.length-1; i>=0 ; i--){\n            if(start == -1){\n                break;\n            }\n            int m = result[start] + temp[i] + c;\n            result[start--] = m%10;\n            c = m/10;\n        }\n    }\n    \n    public int multiplicationImproved(int x, int y, int len){\n        if(len == 1){\n            return x*y;\n        }\n        len = len/2;\n        int div = power(len);\n        int result1 = multiplicationImproved(x/div,y/div,len);\n        int result2 = multiplicationImproved(x%div, y % div, len);\n        int result3 = multiplicationImproved(x/div + x%div,y/div + y % div,len);\n        \n        return result1*div*(div -1) +\n                result3*div - result2*(div -1 );\n        \n    }\n    \n    private int power(int n){\n        return (int)Math.pow(10, n);\n    }\n    \n    \n    public static void main(String args[]){\n        int arr2[] = {9,9,7,4,7,9};\n        int arr1[] = {9,9,5,7,4,2,1};\n        ArrayMultiplication am = new ArrayMultiplication();\n        int result[] = am.multiplyDivideAndConquer(arr1, arr2, 0, arr1.length-1, 0, arr2.length-1);\n        for(int i=0; i < result.length; i++){\n            System.out.print(\" \" + result[i]);\n        }\n        \n        System.out.print(\"\\n\" + am.multiplicationImproved(999, 168, 2));\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/BasicCalculator.java",
    "content": "package com.interview.number;\n\nimport java.util.Stack;\n\n/**\n * Date 10/11/2016\n * @author Tushar Roy\n *\n * Implement a basic calculator to evaluate a simple expression string.\n * The expression string contains only non-negative integers, +, -, *, / operators and empty spaces.\n * The integer division should truncate toward zero.\n *\n * Time complexity O(n)\n * Space complexity (n)\n *\n * https://leetcode.com/problems/basic-calculator-ii/\n */\npublic class BasicCalculator {\n    public int calculate(String s) {\n        Stack<Integer> operand = new Stack<>();\n        int current = 0;\n        char prevOperator = '+';\n        for (int i = 0; i < s.length(); i++) {\n            char ch = s.charAt(i);\n            if (Character.isDigit(ch)) {\n                current = current * 10 + ch - '0';\n            }\n            //if its not a digit or space then go in this block.\n            //also if it is last character then go in this block and finish up last operation.\n            if (i == s.length() - 1 || (ch != ' ' && !Character.isDigit(ch))) {\n                if (prevOperator == '+') {\n                    operand.push(current);\n                } else if (prevOperator == '-') {\n                    operand.push(-current);\n                } else if (prevOperator == '/') {\n                    operand.push(operand.pop() / current);\n                } else {\n                    operand.push(operand.pop() * current);\n                }\n                prevOperator = ch;\n                current = 0;\n            }\n        }\n        int result = 0;\n        while (!operand.isEmpty()) {\n            result += operand.pop();\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/BinomialCoefficient.java",
    "content": "package com.interview.number;\n\n/**\n * http://www.geeksforgeeks.org/space-and-time-efficient-binomial-coefficient/\n * Test cases\n * k is 0\n * k or n are negative\n * k greater than n\n */\npublic class BinomialCoefficient {\n\n    public int calculate(int n, int k){\n        if(k > n-k){\n            k = n-k;\n        }\n        int result = 1;\n        for(int i=0; i < k; i++){\n            result *= (n-i);\n            result /= (i+1);\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        BinomialCoefficient bc = new BinomialCoefficient();\n        System.out.print(bc.calculate(8, 3));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/ConvertToBaseN.java",
    "content": "package com.interview.number;\n\npublic class ConvertToBaseN {\n\n    int baseN(int num,int base){\n        if(base > 10){\n            throw new IllegalArgumentException();\n        }\n        int result =0;\n        int pow = 1;\n        while(num > 0){\n            result += pow*(num%base);\n            pow = pow*10;\n            num /= base;\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        ConvertToBaseN ctb = new ConvertToBaseN();\n        System.out.println(ctb.baseN(13, 9));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/CountNoOf2s.java",
    "content": "package com.interview.number;\n\n/**\n * 150 qs 18.4\n */\npublic class CountNoOf2s {\n\n    public int count2s(int n){\n        if(n < 2){\n            return 0;\n        }else if(n <= 9){\n            return 1;\n        }\n        int pow = 1;\n        while(pow <= n){\n            pow *= 10;\n        }\n        pow = pow/10;\n        \n        if(n/pow == 2){\n            //e.g 2105 becomes 1 + 105 + count2s(105) + count2s(1999)\n            return 1 + n%pow + count2s(n%pow) + count2s((n/pow)*pow -1);\n        }else{\n            //e.g 3856 becomes 1000*count2s(3) + count2s(856) + 3*counts(999)\n            return pow*count2s(n/pow) + count2s(n%pow) + (n/pow)*count2s(pow-1);\n        }\n    }\n    \n    public static void main(String args[]){\n        CountNoOf2s cn2 = new CountNoOf2s();\n        System.out.println(cn2.count2s(255));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/number/CountNumbersNotIncluding4.java",
    "content": "package com.interview.number;\n\n/**\n * http://www.geeksforgeeks.org/count-numbers-that-dont-contain-3/\n */\npublic class CountNumbersNotIncluding4 {\n\n    public int count(int n){\n        if(n < 4){\n            return n;\n        }\n        if( n >=4 && n <=10){\n            return n-1;\n        }\n        \n        int pow = 1;\n        while(n/pow > 9){\n            pow = pow*10;\n        }\n        \n        int msd = n/pow;\n        if(msd == 4){\n            return count(msd*pow -1);\n        }else{\n            //suppose number is 276. So this becomes count(2)*count(99) +\n            //count(2) + count(76)\n            //reason we split this way rather than count(2)*count(100) is because\n            //count(100) can go into infinite loop\n            return count(msd)*count(pow-1) + count(msd) + count(n%pow);\n        }\n    }\n    \n    public static void main(String args[]){\n        CountNumbersNotIncluding4 cn = new CountNumbersNotIncluding4();\n        int c = cn.count(44);\n        System.out.print(c);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/DivisionWithoutDivisionOperator.java",
    "content": "package com.interview.number;\n\npublic class DivisionWithoutDivisionOperator {\n\n    public static class Pair {\n        int remainder;\n        int quotient;\n    }\n\n    public Pair divide(int number, int divisor) {\n        int divident = 0;\n        while (number >= divisor) {\n            number -= divisor;\n            divident++;\n        }\n        Pair p = new Pair();\n        p.quotient = divident;\n        p.remainder = number;\n        return p;\n    }\n    \n    public int divideRec(int number, int divisor){\n        if(number < divisor){\n            return 0;\n        }\n        \n        return divideRec(number-divisor, divisor) + 1;\n    }\n\n    public Pair efficientDivide(int divident, int divisor) {\n        int quotient = 1;\n        int currentDivisor = divisor;\n        int currentDivident = divident;\n        int q = 0;\n        while (divisor < divident) {\n            currentDivisor = divisor;\n            currentDivident = divident;\n            quotient = 1;\n            while (currentDivisor <= currentDivident) {\n                currentDivisor *= 2;\n                quotient *= 2;\n            }\n            currentDivisor = currentDivisor >> 1;\n            quotient = quotient >> 1;\n            divident = divident - currentDivisor;\n            q += quotient;\n        }\n        Pair p = new Pair();\n        p.quotient = q;\n        p.remainder = divident;\n        return p;\n    }\n\n    public int efficientDivideRec(int divident, int divisor){\n        if(divisor > divident){\n            return 0;\n        }\n        int tempDivisor = divisor;\n        int quotient = 1;\n        while(divisor <= divident){\n            divisor = divisor*2;\n            quotient *= 2;\n        }\n        divisor = divisor >> 1;\n        quotient = quotient >> 1;\n        return quotient + efficientDivideRec(divident - divisor, tempDivisor);\n    }\n    \n    public static void main(String args[]) {\n        DivisionWithoutDivisionOperator dd = new DivisionWithoutDivisionOperator();\n        Pair p = dd.efficientDivide(95,4);\n        System.out.println(p.quotient + \" \" + p.remainder);\n        \n        System.out.print(dd.efficientDivideRec(135,12));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/EuclideanAlgoForGCD.java",
    "content": "package com.interview.number;\n\n/**\n * GCD greatest common divisor\n * Co prime numbers if GCD of both the numbers is 1\n */\npublic class EuclideanAlgoForGCD {\n\n    public int gcd(int num1, int num2){\n        if(num1 > num2){\n            int temp = num1;\n            num1 = num2;\n            num2 = temp;\n        }\n        while(num1 != 0){\n            int temp = num1;\n            num1 = num2 % num1;\n            num2 = temp;\n        }\n        return num2;\n    }\n    \n    /**\n     * assumption that num1 is less than num2 as initial parameter\n     */\n    public int gcdRec(int num1, int num2){\n        if(num1 == 0){\n            return num2;\n        }\n        return gcdRec(num2%num1, num1);\n    }\n    \n    public static void main(String args[]){\n        EuclideanAlgoForGCD ea = new EuclideanAlgoForGCD();\n        int gcd = ea.gcd(956,1044);\n        if(gcd == 1){\n            System.out.println(\"Co prime numbers\");\n        }else{\n            System.out.println(\"No coprime numbers \" + gcd);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/FactorialOfLargeNumber.java",
    "content": "package com.interview.number;\n\n/**\n * Date 03/14/2015\n * @author tusroy\n\n * Find factorial of very large number like 100.\n * \n * Solution \n * Since result will be very large it cannot fit in long. We need to store result in array\n * and do regular multiplication of result in array with next number of factorial.\n * Result is randomly initialized with size 500. Better would be to use list which grows\n * dynamically.\n * \n * Test cases:\n * Negative number - should throw exception for negative number\n * 0 \n * large number\n * \n * Reference\n * http://www.geeksforgeeks.org/factorial-large-number/\n */\npublic class FactorialOfLargeNumber {\n\n    public int calculate(int result[], int n){\n        assert n >= 0;\n        result[0] = 1;\n        int size = 1;\n        for(int i=2; i <= n; i++){\n            size = multiply(result, i, size);\n        }\n        return size;\n    }\n    \n    private int multiply(int result[], int x, int size){\n        \n        int carry = 0;\n        int prod = 0;\n        int i=0;\n        for(; i < size; i++){\n            prod = result[i]*x + carry;\n            result[i] = prod%10;\n            carry = prod/10;\n        }\n        \n        while(carry != 0){\n            result[i] = carry%10;\n            carry = carry/10;\n            i++;\n        }\n        \n        return i;\n    }\n    \n    public static void main(String args[]){\n        FactorialOfLargeNumber fol = new FactorialOfLargeNumber();\n        int result[] = new int[500];\n        int size = fol.calculate(result, 126);\n        for(int i=size-1; i >=0; i--){\n            System.out.print(result[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/GenerateSignature.java",
    "content": "package com.interview.number;\n\n/**\n * You are given an array of n elements [1,2,....n]. For example {3,2,1,6,7,4,5}. Now we create a signature of this\n * array by comparing every consecutive pir of elements. If they increase, write I else write D.\n * For example for the above array, the signature would be \"DDIIDI\". The signature thus has a length of N-1.\n * Now the question is given a signature, compute the lexicographically smallest permutation of [1,2,....n].\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * Reference https://learn.hackerearth.com/forum/182/lexicographically-smallest-permutation-given-a-signature/\n */\npublic class GenerateSignature {\n\n    public int[] generate(char[] input) {\n        int n = input.length+1;\n        int[] result = new int[n];\n        int i;\n        for (i = 0; i < n; i++) {\n            result[i] = i+1;\n        }\n        i = 0;\n        while(i < n-1) {\n            int start = -1, end = -1;\n            while(i < n-1 && input[i] == 'D') {\n                if(start == -1) {\n                    start = i;\n                }\n                end = i;\n                i++;\n            }\n            if(start != -1) {\n                reverse(result, start, end+1);\n            }\n            i++;\n        }\n        return result;\n    }\n\n    private void reverse(int[] result, int start, int end) {\n\n        while(start < end) {\n            int tmp = result[start];\n            result[start] = result[end];\n            result[end] = tmp;\n            start++;\n            end--;\n        }\n    }\n    \n    public static void main(String args[]){\n        String input = \"IIIDIIDDDDIIDDD\";\n        GenerateSignature gs = new GenerateSignature();\n        int result[] = gs.generate(input.toCharArray());\n        for(int i=0; i < result.length; i++){\n            System.out.print(result[i] + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/LargestMultipleOf3inArray.java",
    "content": "package com.interview.number;\n\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.Queue;\n\n/**\n * http://www.geeksforgeeks.org/find-the-largest-number-multiple-of-3/\n */\npublic class LargestMultipleOf3inArray {\n\n    public void swap(int input[],int i, int j){\n        int temp = input[i];\n        input[i] = input[j];\n        input[j] = temp;\n    }\n    private void reverse(int input[]){\n        for(int i=0; i < input.length/2; i++){\n            swap(input,i, input.length-1-i);\n        }\n    }\n    \n    public int[] largestMultiple(int input[]){\n        Arrays.sort(input);\n        int output[];\n        Queue<Integer> q0 = new LinkedList<Integer>();\n        Queue<Integer> q1 = new LinkedList<Integer>();\n        Queue<Integer> q2 = new LinkedList<Integer>();\n        \n        int sum = 0;\n        for(int i=0; i < input.length; i++){\n            if(input[i] % 3 == 0){\n                q0.add(input[i]);\n            }\n            if(input[i] % 3 == 1){\n                q1.add(input[i]);\n            }\n            if(input[i] % 3 == 2){\n                q2.add(input[i]);\n            }\n            sum += input[i];\n        }\n    \n        if(sum % 3 == 0){\n            output = new int[input.length];\n            for(int i=0; i < input.length; i++){\n                output[input.length-1-i] = input[i];\n            }\n            return output;\n        }\n        else if(sum % 3 == 1){\n            int len = input.length;\n            if(q1.size() > 0){\n                q1.poll();\n                len--;\n            }else if (q2.size() > 1){\n                q2.poll();\n                q2.poll();\n                len -= 2;\n            }else{\n                return null;\n            }\n            output = new int[len];\n            int i=0;\n            while(q0.size() > 0){\n                output[i] = q0.poll();\n                i++;\n            }\n            while(q1.size() > 0){\n                output[i] = q1.poll();\n                i++;\n            }\n            while(q2.size() > 0){\n                output[i] = q2.poll();\n                i++;\n            }\n            Arrays.sort(output);\n            reverse(output);\n        }else{\n            int len = input.length;\n            if(q2.size() > 0){\n                q2.poll();\n                len--;\n            }else if(q1.size() > 1){\n                q1.poll();\n                q1.poll();\n                len -= 2;\n            }else{\n                return null;\n            }\n            output = new int[len];\n            int i=0;\n            while(q0.size() > 0){\n                output[i] = q0.poll();\n                i++;\n            }\n            while(q1.size() > 0){\n                output[i] = q1.poll();\n                i++;\n            }\n            while(q2.size() > 0){\n                output[i] = q2.poll();\n                i++;\n            }\n            Arrays.sort(output);\n            reverse(output);\n        }\n        return output;\n    }\n    \n    public static void main(String args[]){\n        int input[] = {8,9,0,2,2,2};\n        LargestMultipleOf3inArray lma = new LargestMultipleOf3inArray();\n        int output[] = lma.largestMultiple(input);\n        for(int a : output){\n            System.out.print(a + \" \");\n        }\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/number/LuckyNumbers.java",
    "content": "package com.interview.number;\n\n/**\n * http://www.geeksforgeeks.org/lucky-numbers/\n */\npublic class LuckyNumbers {\n\n    public boolean isLuck(int n,int counter){\n        if(n < counter){\n            return true;\n        }\n        if(n % counter == 0){\n            return false;\n        }\n        \n        return isLuck( n - n/counter,counter+1);\n    }\n    \n    public static void main(String args[]){\n        LuckyNumbers ln = new LuckyNumbers();\n        System.out.println(ln.isLuck(19, 2));\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/number/MedianOf3Number.java",
    "content": "package com.interview.number;\n\npublic class MedianOf3Number {\n\n    public int median(int arr[]){\n        int l = 0;\n        int h = 2;\n        int m =1;\n        \n        if(arr[m] >= arr[l]){\n            if(arr[m] <= arr[h]){\n                return arr[m];\n            }else if(arr[l] >= arr[h]){\n                return arr[l];\n            }\n        }else{\n            if(arr[l] <= arr[h]){\n                return arr[l];\n            }else if(arr[m] >= arr[h]){\n                return arr[m];\n            }\n        }\n        return arr[h];\n    }\n    \n    public int median2Comparison(int arr[]){\n        int l = 0;\n        int h = 2;\n        int m =1;\n        \n        if((arr[l] - arr[m])*(arr[h] - arr[l]) >= 0){\n            return arr[l];\n        }else if((arr[m] - arr[l])*(arr[h] - arr[m]) >= 0){\n            return arr[m];\n        }else{\n            return arr[h];\n        }\n    }\n    \n    public int medianXORMethod(int arr[]){\n        int a = arr[0] <= arr[1] ? arr[0] : arr[1];\n        int b = arr[1] <= arr[2] ? arr[1] : arr[2];\n        int c = arr[0] <= arr[2] ? arr[0] : arr[2];\n        return a^b^c;\n    }\n\n    public static void main(String args[]){\n        MedianOf3Number mn = new MedianOf3Number();\n        int arr[] = {2,0,1};\n        System.out.println(mn.medianXORMethod(arr));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/MthNumberInNSizeArray.java",
    "content": "package com.interview.number;\n\nimport java.util.Arrays;\n\n/**\n * @author Tushar Roy\n * Date 01/21/2016\n *\n * Given a number n, find mth value in permutation of array consisting of [1..n] values.\n * mth is defined by lexicographical order.\n */\npublic class MthNumberInNSizeArray {\n\n    public int[] find(int n, int m) {\n        boolean used[] = new boolean[n];\n        int result[] = new int[n];\n        find(result, used, 0, n, m);\n        return result;\n    }\n\n    private void find(int result[], boolean used[], int start, int n, int m) {\n        if(1 == m) {\n            fillupRemaining(result, used, start);\n            return;\n        }\n        int index = binarySearch(m, start + 1, n, factorial(n - start - 1));\n        int i = nthUnused(used, index);\n        used[i] = true;\n        result[start] = i + 1;\n        find(result, used, start + 1, n, m - (index-1)*factorial(n - start - 1));\n    }\n\n    private int binarySearch(int m, int start, int end, int factorial) {\n        int i = 1;\n        int j = end - start + 1;\n        while (i <= j) {\n            int middle = (i + j)/2;\n            if (factorial*(middle) >= m && factorial*(middle - 1) < m) {\n                return middle;\n            } else if (factorial*middle < m){\n                i = middle + 1;\n            } else {\n                j = middle - 1;\n            }\n        }\n        throw new IllegalArgumentException();\n     }\n    private void fillupRemaining(int result[], boolean used[], int index) {\n        int j = 0;\n        for(int i = index; i < result.length; i++) {\n            while (true) {\n                if (!used[j]) {\n                    result[i] = j + 1;\n                    used[j] = true;\n                    break;\n                }\n                j++;\n            }\n        }\n    }\n\n    private int nthUnused(boolean used[], int n) {\n        int unused = 0;\n        for ( int i = 0; i < used.length; i++) {\n            if (!used[i]) {\n                unused++;\n                if (unused == n) {\n                    return i;\n                }\n            }\n        }\n        throw new IllegalArgumentException();\n    }\n\n    private int factorial(int n) {\n        int result = 1;\n        for ( int i = 1; i <= n; i++) {\n            result = result*i;\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        MthNumberInNSizeArray mn = new MthNumberInNSizeArray();\n        int n = 5;\n        int m = 120;\n        for ( int i = 1; i <= m; i++) {\n            int result[] = mn.find(n, i);\n            Arrays.stream(result).forEach(r -> System.out.print(r + \" \"));\n            System.out.print(\"\\n\");\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "src/com/interview/number/NBy2PairSumToK.java",
    "content": "package com.interview.number;\n\n/**\n * Write a program to determine whether n/2 distinctive pairs can be formed \n * from given n integers where n is even and each pair's sum is divisible by given k. \n * Numbers cannot be repeated in the pairs, that means only you can form total n/2 pairs.\n */\npublic class NBy2PairSumToK {\n\n    //assuming input is from 1 to n. If input can contain 0 special logic will be needed\n    //to handle that.\n    public boolean pair(int input[],int k){\n        int count[] = new int[k];\n        for(int i=0; i < input.length; i++){\n            count[input[i]%k]++;\n        }\n        \n        if(count[0]%2 != 0){\n            return false;\n        }\n        if(k%2==0){\n            if(count[k/2]%2 != 0){\n                return false;\n            }\n        }\n        for(int i=1; i <= k/2; i++){\n            if(count[i] != count[k-i]){\n                return false;\n            }\n        }\n        return true;\n    }\n    \n    public static void main(String args[]){\n        int input[] = {5,7,6,8,2,6,10,4};\n        NBy2PairSumToK nb = new NBy2PairSumToK();\n        System.out.println(nb.pair(input, 6));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/NextLargestPalindrome.java",
    "content": "package com.interview.number;\n\n/**\n http://www.geeksforgeeks.org/given-a-number-find-next-smallest-palindrome-larger-than-this-number/\n */\npublic class NextLargestPalindrome {\n\n    public void nextPalindrome(int num[]){\n        \n        int mid = num.length/2;\n        \n        int i = mid-1;\n        int j  = num.length % 2 == 0 ? mid :  mid+1;\n        \n        while(i >= 0 && j <= num.length-1 && num[i] == num[j]){\n            i--;\n            j++;\n        }\n        \n        boolean leftSmaller = false;\n        if(i < 0 || num[i] < num[j]){\n            leftSmaller = true;\n        }\n        \n        if(!leftSmaller){\n            while(i >= 0){\n                num[j] = num[i];\n                i--;\n                j++;\n            }\n        }else{\n            int carry =0;\n            if(num.length % 2 != 0){\n                num[mid] = num[mid] + 1;\n                carry = num[mid]/10;\n                num[mid] = num[mid]%10;\n                j = mid+1;\n            }else{\n                j = mid;\n                carry = 1;\n            }\n            i = mid-1;\n            while(i >= 0){\n                num[i] = carry + num[i];\n                carry = num[i]/10;\n                num[i] = num[i]%10;\n                num[j] = num[i];\n                i--;\n                j++;\n            }\n        }\n    }\n    \n    public void printArray(int num[]){\n        for(int i=0; i < num.length; i++){\n            System.out.print(num[i] + \" \");\n        }\n    }\n    \n    public static void main(String args[]){\n        \n        NextLargestPalindrome nextLargestPalindrom = new NextLargestPalindrome();\n        int num[] = {6,5,4,4,5,6};\n        //handle case of 999 separately\n        nextLargestPalindrom.nextPalindrome(num);\n        nextLargestPalindrom.printArray(num);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/NotIncluding4.java",
    "content": "package com.interview.number;\n\n/**\n * http://saikatd.wordpress.com/author/saikatd/page/4/\n * In a number system where 4 is not there, how do you convert such a number system to decimal\n * Here basically we have base 9 and convert it to base 10. Just be careful when you convert\n * anything from 5 to 9 because they are basically 4 to 8 in base 9 system. So subtract them \n * by 1 when doing multiplications.\n */\npublic class NotIncluding4 {\n\n    public int number(int chinaNumber){\n        \n        int result = 0;\n        int mul = 1;\n        while(chinaNumber > 0){\n            int r = chinaNumber % 10;\n            chinaNumber /= 10;\n            if(r == 4){\n                throw new IllegalArgumentException();\n            }\n            if(r >=5){\n                r--;\n            }\n            result += r*mul;\n            mul = mul*9;\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        NotIncluding4 ni = new NotIncluding4();\n        System.out.print(ni.number(16));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/NumberOfCombinationsForStairs.java",
    "content": "package com.interview.number;\n\nimport java.util.Iterator;\nimport java.util.LinkedList;\n\n\n/**\n * A man is walking up a set of stairs. He can either take 1 or 2 steps at a time. \n * Given n number of steps,\n * find out how many combinations of steps he can take to reach the top of the stairs.\n * Its like building a fibonaaci series but instead of looking back 2 you have to \n * look back k elements\n */\npublic class NumberOfCombinationsForStairs {\n\n    /**\n     * Assumption is k is always greater than or equal to 2\n     */\n    public int numberOfWays(int n,int k){\n        if(k < 2){\n            throw new IllegalArgumentException();\n        }\n        LinkedList<Integer> queue = new LinkedList<Integer>();\n        queue.add(1);\n        queue.add(2);\n        int count=0;\n        for(int i=2; i < k ; i++){\n            Iterator<Integer> itr = queue.iterator();\n            count = 0;\n            while(itr.hasNext()){\n                count += itr.next();\n            }\n            queue.offerLast(count);\n        }\n        for(int i = k; i < n ; i++){\n            Iterator<Integer> itr = queue.iterator();\n            count = 0;\n            while(itr.hasNext()){\n                count += itr.next();\n            }\n            queue.pollFirst();\n            queue.offerLast(count);\n        }\n        return queue.pollLast();\n    }\n    \n    public static void main(String args[]){\n        NumberOfCombinationsForStairs noc = new NumberOfCombinationsForStairs();\n        System.out.println(noc.numberOfWays(7, 4));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/PermutationBiggerThanNumber.java",
    "content": "package com.interview.number;\n\nimport com.interview.sort.QuickSort;\n\n/**\n * Date 02/17/2016\n * @author Tushar Roy\n * Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.\n * If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).\n * \n * Time complexity is O(n)\n * Space complexity is O(1)\n *\n * https://leetcode.com/problems/next-permutation/\n * e.g 1 7 9 8 4 will transform to 1 8 4 7 9\n * or  4 2 6 4 3 will transform to 4 3 2 4 6\n */\npublic class PermutationBiggerThanNumber {\n\n    public void nextPermutation(int[] nums) {\n        int i;\n        for (i = nums.length - 2; i >= 0 ; i--) {\n            if (nums[i] < nums[i + 1]) {\n                break;\n            }\n        }\n\n        if (i != -1) {\n            int pos = ceiling(nums[i], i + 1, nums.length - 1, nums);\n            int t = nums[pos];\n            nums[pos] = nums[i];\n            nums[i] = t;\n        }\n        reverse(nums, i + 1, nums.length - 1);\n    }\n\n    private void reverse(int nums[], int start, int end) {\n        while (start <= end) {\n            int t = nums[start];\n            nums[start] = nums[end];\n            nums[end] = t;\n            start++;\n            end--;\n        }\n    }\n\n    private int ceiling(int val, int start, int end, int[] nums) {\n        while (start <= end) {\n            int middle = (start + end)/2;\n            if (nums[middle] > val && (middle + 1 == nums.length || nums[middle+1] <= val)) {\n                return middle;\n            } else if (nums[middle] > val) {\n                start = middle + 1;\n            } else {\n                end = middle - 1;\n            }\n        }\n        throw new IllegalArgumentException();\n    }\n\n    public static void main(String args[]){\n        PermutationBiggerThanNumber pb = new PermutationBiggerThanNumber();\n        int arr[] = {1,7,9,8,4};\n        pb.nextPermutation(arr);\n        for(int i=0; i < arr.length; i++){\n            System.out.print(arr[i] + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/PermutationLargerThanGivenArray.java",
    "content": "package com.interview.number;\n\nimport java.util.Arrays;\n\n/**\n * e.g if src array is {1,2,5,7,8} and dest is {5,8,1,9,8}\n * permute src in such a way that it is greater than dest but diff is minimal\n * so here we will have {5,8,2,1,7}\n *\n */\npublic class PermutationLargerThanGivenArray {\n\n    public int[] findBiggerNumber(int src[],int dest[]){\n        int result[] = new int[src.length];\n        boolean[] used = new boolean[src.length];\n        boolean r = findNumber(src, dest, result, 0, used);\n        if(!r){\n            return null;\n        }\n        return result;\n    }\n    \n    private void sortRemaining(int src[],int result[],boolean used[],int pos){\n        int pos1 = pos;\n        for(int i=0; i < src.length; i++){\n            if(!used[i]){\n                result[pos1] = src[i];\n                pos1++;\n            }\n        }\n        Arrays.sort(result,pos,result.length);\n    }\n    \n    private boolean findNumber(int src[],int dest[],int result[],int pos,boolean used[]){\n        \n        if(pos == result.length){\n            return false;\n        }\n        \n        boolean hasEqual = false;\n        int nextGreaterIndex = -1;\n        int equalIndex = -1;\n        int nextGreaterDiff = Integer.MAX_VALUE;\n        for(int i=0; i < src.length; i++){\n            if(used[i]){\n                continue;\n            }\n            if(dest[pos] == src[i]){\n                hasEqual = true;\n                equalIndex = i;\n                continue;\n            }\n            if(src[i] > dest[pos]){\n                if(src[i] - dest[pos] < nextGreaterDiff){\n                    nextGreaterIndex = i;\n                    nextGreaterDiff = src[i] - dest[pos];\n                }\n            }\n        }\n        //first try with equal item and see next numbers in array might find larger one.\n        //if it fail try next larger number\n        if(hasEqual){\n            used[equalIndex] = true;\n            result[pos] = src[equalIndex];\n            if(findNumber(src,dest,result,pos+1,used)){\n                return true;\n            }\n            used[equalIndex] = false;\n        }\n        if(nextGreaterIndex != -1){\n            used[nextGreaterIndex] = true;\n            result[pos] = src[nextGreaterIndex];\n            sortRemaining(src, result, used, pos+1);\n            return true;\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        int src[] = {1,2,5,7,8};\n        int dest[] = {5,8,1,9,8};\n        PermutationLargerThanGivenArray nld = new PermutationLargerThanGivenArray();\n        int result[] = nld.findBiggerNumber(src, dest);\n        if(result != null){\n            for(int i=0; i < result.length; i++){\n                System.out.print(result[i] + \" \");\n            }\n        }else{\n            System.out.println(\"Cant find bigger permutation\");\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/number/PowerFunction.java",
    "content": "package com.interview.number;\n\n/**\n * Date 03/13/2016\n * @author Tushar Roy\n *\n * Find power of 2 numbers.\n *\n * Time complexity O(logn)\n * Space complexity O(1)\n *\n * https://leetcode.com/problems/powx-n/\n * http://www.geeksforgeeks.org/write-a-c-program-to-calculate-powxn/\n */\npublic class PowerFunction {\n\n    public int power(int n, int m){\n        if(m == 0){\n            return 1;\n        }\n        int pow = power(n,m/2);\n        if(m % 2 ==0){\n            return pow*pow;\n        }else{\n            return n*pow*pow;\n        }\n    }\n\n\n    public double powerUsingBit(double x, int n) {\n        if (n == 0) {\n            return 1;\n        }\n        long r = n;\n        if (r < 0) {\n            x = 1/x;\n            r = -r;\n        }\n        double power = x;\n        double result = x;\n        double result1 = 1;\n        while (r > 1) {\n            result *= result;\n            if ((r & 1) != 0) {\n                result1 = result1 * power;\n            }\n            r = r >> 1;\n            power = power * power;\n        }\n        return result * result1;\n    }\n    \n    public static void main(String args[]){\n        PowerFunction pf = new PowerFunction();\n        long pow = pf.power(3, 5);\n        System.out.print(pow);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/RearrangeNumberInArrayToFormLargestNumber.java",
    "content": "package com.interview.number;\n\nimport java.util.Arrays;\nimport java.util.Comparator;\n\n/**\n * Given a list of non negative integers, arrange them such that they form the largest number.\n * For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.\n * \n * https://leetcode.com/problems/largest-number/\n */\npublic class RearrangeNumberInArrayToFormLargestNumber {\n\n    public String largestNumber(int[] nums) {\n        Integer[] nums1 = new Integer[nums.length];\n        int i = 0;\n        for (int n : nums) {\n            nums1[i++] = n;\n        }\n\n        IntegerComparator comparator = new IntegerComparator();\n        Arrays.sort(nums1, comparator);\n        StringBuffer buff = new StringBuffer();\n\n        //handle 0s in the front by removing them.\n        for (i = 0; i < nums1.length; i++) {\n            if (nums1[i] != 0) {\n                break;\n            }\n        }\n        //if no element is left means return one 0\n        if (i == nums1.length) {\n            return \"0\";\n        }\n        for (;i < nums1.length; i++) {\n            buff.append(nums1[i]);\n        }\n        return buff.toString();\n    }\n    \n    public static void main(String args[]){\n        RearrangeNumberInArrayToFormLargestNumber rni = new RearrangeNumberInArrayToFormLargestNumber();\n        int[] input = {999999998, 999999997, 999999999};\n        int[] input1 = {0, 9, 8};\n        int[] input2 = {0, 0};\n\n        String result = rni.largestNumber(input2);\n        System.out.print(result);\n    }\n\n    class IntegerComparator implements Comparator<Integer> {\n        @Override\n        public int compare(Integer o1, Integer o2) {\n            int pow1 = 10;\n            while(pow1 <= o1){\n                pow1 *= 10;\n            }\n            int pow2 = 10;\n            while(pow2 <= o2){\n                pow2 *= 10;\n            }\n            int r1 = o1*pow2 + o2;\n            int r2 = o2*pow1 + o1;\n            return r2 - r1;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/RussianPeasantMultiplication.java",
    "content": "package com.interview.number;\n\n/**\n * http://www.geeksforgeeks.org/fast-multiplication-method-without-using-multiplication-operator-russian-peasants-algorithm/\n * Test cases\n * Division by 0\n * Negative numbers\n */\npublic class RussianPeasantMultiplication {\n\n    public int multiply(int a,int b){\n        int res = 0;\n        while(b > 0){\n            if(b % 2 != 0){\n                res += a;\n            }\n            a = a<<1;\n            b = b>>1;\n        }\n        return res;\n    }\n    \n    public static void main(String args[]){\n        RussianPeasantMultiplication rpm = new RussianPeasantMultiplication();\n        System.out.println(rpm.multiply(7, 13));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/SmallestNumberGreaterThanGiveNumberIncreasingSequence.java",
    "content": "package com.interview.number;\n\n/**\n * http://www.careercup.com/question?id=4857362737266688\n * Test cases : \n * 6 2 3 -> 6 7 8\n * 1 2 3 -> 1 2 4\n * 1,7,9 -> 1,8,9\n * 1,8,9 -> 2,3,4\n * 9,8,7 -> 1,2,3,4\n * 2,6   -> 2,7\n */\npublic class SmallestNumberGreaterThanGiveNumberIncreasingSequence {\n\n    public int[] getNextInt(int []input){\n        int result[] = new int[input.length];\n        boolean flag = getNextInt(input,result,0);\n        if(flag){\n            return result;\n        }else{\n            result = new int[input.length+1];\n            fillRestOfArray(result, 0, (input[0] +1)%9);\n            return result;\n        }\n    }\n    \n    private boolean getNextInt(int input[], int result[], int pos){\n        if(pos == input.length-1){\n            int higher = getHigherNumber(input[pos]+1,pos,input.length);\n            if(higher == -1){\n                return false;\n            }else{\n                result[pos] = input[pos]+1;\n                return true;\n            }\n        }\n        \n        if(pos != 0 && input[pos] <= input[pos-1]){\n            int higher = getHigherNumber(input[pos-1] +1,pos,input.length);\n            if(higher == -1){\n                return false;\n            }else{\n                fillRestOfArray(result, pos, input[pos-1]+1);\n                return true;\n            }\n        }\n        if(input[pos] + (input.length - 1 -pos) <=9){\n            result[pos] = input[pos];\n            boolean flag = getNextInt(input,result,pos+1);\n            if(flag){\n                return true;\n            }\n            int higher = getHigherNumber(input[pos]+1,pos,input.length);\n            if(higher == -1){\n                return false;\n            }else{\n                fillRestOfArray(result,pos,input[pos]+1);\n                return true;\n            }\n            \n        }else{\n            return false;\n        }\n        \n    }\n    \n    private void fillRestOfArray(int result[],int pos,int val){\n        for(int i=pos; i < result.length ; i++){\n            result[i] = val;\n            val++;\n        }\n    }\n    \n    private int getHigherNumber(int input, int i, int len){\n        if(input + len - i-1 <=9){\n            return input;\n        }\n        return -1;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {2,6};\n        SmallestNumberGreaterThanGiveNumberIncreasingSequence sm = new SmallestNumberGreaterThanGiveNumberIncreasingSequence();\n        int result[] = sm.getNextInt(arr);\n        for(int i : result){\n            System.out.print(i);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/SquareRoot.java",
    "content": "package com.interview.number;\n\n/**\n * Babylonian method for calculating square root\n */\npublic class SquareRoot {\n\n    double findRoot(int num){\n        double start =0;\n        double end = num;\n        while(Math.abs(start - end) > 0.01){\n            end = (start + end)/2;\n            start = num/end;\n        }\n        \n        return end;\n    }\n    \n    public static void main(String args[]){\n        SquareRoot sr = new SquareRoot();\n        System.out.println(sr.findRoot(144));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/StrobogrammaticNumber.java",
    "content": "package com.interview.number;\n\n/**\n * A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down).\n * https://leetcode.com/problems/strobogrammatic-number/\n */\npublic class StrobogrammaticNumber {\n    public boolean isStrobogrammatic(String num) {\n\n        for (int i = 0; i <= num.length()/2; i++) {\n            char ch1 = num.charAt(i);\n            char ch2 = num.charAt(num.length() - i - 1);\n\n            if (ch1 != ch2) {\n                if ((ch1 != '9' || ch2 != '6') && (ch1 != '6' || ch2 != '9')) {\n                    return false;\n                }\n            } else {\n                if (ch1 != '0' && ch1 != '1' && ch1 != '8') {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/Trailing0sinFactorial.java",
    "content": "package com.interview.number;\n\n/**\n * 150qs hard section\n * lets consider 625. First we divide 625 by 5 and that takes care of one 5\n * till 625. Then we divide 625 with 25 and that takes care of numbers with 2\n * 5s. We keep doing this till divisor becomes greater than number.\n */\npublic class Trailing0sinFactorial {\n\n    public int trailing0s(int num){\n        int pow = 5;\n        int count = 0;\n        while(pow <= num){\n            count += num/pow;\n            pow *= 5;\n        }\n        return count;\n    }\n    \n    public static void main(String args[]){\n        Trailing0sinFactorial t0 = new Trailing0sinFactorial();\n        System.out.println(t0.trailing0s(625));\n        System.out.println(t0.trailing0s(146));\n        System.out.println(t0.trailing0s(1046));\n        System.out.println(t0.trailing0s(4617));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/number/UniquePartitionOfInteger.java",
    "content": "package com.interview.number;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * http://www.geeksforgeeks.org/generate-unique-partitions-of-an-integer/\n * Test cases:\n * 0 or negative number\n */\npublic class UniquePartitionOfInteger {\n\n    public void partition(int n){\n        List<Integer> result = new ArrayList<Integer>();\n        partition(n,n,result);\n    }\n    \n    private void partition(int n, int max,List<Integer> result){\n        if(n < 0){\n            return ;\n        }\n        if(n == 0){\n            result.forEach(i -> System.out.print(i + \" \"));\n            System.out.println();\n            return;\n        }\n        for(int i=Math.min(n, max); i > 0 && i <= max; i--){\n            result.add(i);\n            partition(n-i,i, result);\n            result.remove(result.size()-1);\n        }\n   }\n    \n    public static void main(String args[]){\n        UniquePartitionOfInteger upi = new UniquePartitionOfInteger();\n        upi.partition(12);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/playground/TestInnerClass.java",
    "content": "package com.interview.playground;\n\nimport java.util.Random;\n\n/**\n * Created by tushar_v_roy on 5/18/16.\n */\npublic class TestInnerClass {\n\n    int t = 20;\n    Random random;\n    public Okay test() {\n        final int r = 10;\n        return\n                 random::nextInt;\n\n    }\n\n    public void test1() {\n        random = new Random();\n        Okay o1 = test();\n        System.out.print(o1.next());\n        Okay o2 = test();\n        random = null;\n        System.out.print(o2.next());\n    }\n\n    public static void main(String args[]) {\n        TestInnerClass testInnerClass = new TestInnerClass();\n        testInnerClass.test1();\n    }\n}\n\ninterface Okay {\n    int next();\n}\n"
  },
  {
    "path": "src/com/interview/random/Rand7UsingRand5.java",
    "content": "package com.interview.random;\n\npublic class Rand7UsingRand5 {\n\n\tpublic int rand7(){\n\t\tint r = (rand5()-1)*5 + rand5();\n\t\twhile(r > 21){   // I just need to ignore [22, 25] \n\t\t\tr = (rand5()-1)*5 + rand5();\n\t\t}\n\t\treturn (r%7) + 1;\n\t}\n\t\n\tprivate int rand5(){\n\t\treturn (int)(Math.ceil(Math.random()*5));\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\tRand7UsingRand5 rr = new Rand7UsingRand5();\n\t\tfor(int i=0; i < 10; i++){\n\t\t\tSystem.out.print(rr.rand7());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/interview/random/RandomCountrySelectionByPopluation.java",
    "content": "package com.interview.random;\n\npublic class RandomCountrySelectionByPopluation {\n\n\tpublic int getRandom(int []arr){\n\t\tint sum[] = new int[arr.length];\n\t\tsum[0] = arr[0];\n\t\tint n = arr[0];\n\t\tfor(int i=1; i < sum.length; i++){\n\t\t\tsum[i] = sum[i-1] + arr[i];\n\t\t\tn += arr[i];\n\t\t}\n\t\t\n\t\tint ran = (int)(Math.random()*n + 1);\n\t\t\n\t\tint low = 0;\n\t\tint high = arr.length-1;\n\t\tint mid = (high + low)/2;\n\t\twhile(true){\n\t\t\tif(sum[mid] >= ran && (mid-1 == -1 || sum[mid-1] < ran)){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(sum[mid] > ran){\n\t\t\t\thigh = mid-1;\n\t\t\t}else{\n\t\t\t\tlow = mid+1;\n\t\t\t}\n\t\t\tmid = (high + low)/2;\n\t\t}\n\t\treturn mid;\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\t\n\t\tRandomCountrySelectionByPopluation rcsp = new RandomCountrySelectionByPopluation();\n\t\tint arr[] = {5,5,2,3,7,1};\n\t\tfor(int i=0; i < 10; i++){\n\t\t\tSystem.out.print(rcsp.getRandom(arr));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/interview/random/SelectMRandomNumbersInStream.java",
    "content": "package com.interview.random;\n\n/**\n * Reservoir Sampling\n * 150qs 18.3\n */\npublic class SelectMRandomNumbersInStream {\n\n\tpublic int[] selectRandom(int arr[],int m){\n\t\tint result[] = new int[m];\n\t\tfor(int i=0; i < m ;i++){\n\t\t\tresult[i] = arr[i];\n\t\t}\n\t\t\n\t\tfor(int i=m ; i < arr.length; i++){\n\t\t\tint random = (int)(Math.random()*i) + 1;\n\t\t\tif(random <= m){\n\t\t\t\tresult[random-1] = arr[i];\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\tSelectMRandomNumbersInStream srn = new SelectMRandomNumbersInStream();\n\t\tint arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13};\n\t\tint result[] = srn.selectRandom(arr, 5);\n\t\tfor(int i=0; i < result.length; i++){\n\t\t\tSystem.out.print(result[i] + \" \");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/interview/random/ShuffleArray.java",
    "content": "package com.interview.random;\n\n/**\n * Shuffle deck of cards\n * 150 qs 18.2\n */\npublic class ShuffleArray {\n\n\tpublic void shuffle(int arr[]){\n\t\tfor(int i=arr.length-1; i>=0; i--){\n\t\t\tint random = (int)(Math.random()*(i+1)) ;\n\t\t\tSystem.out.print(random +  \" \");\n\t\t\tswap(arr,random,i);\n\t\t}\n\t}\n\t\n\tprivate void swap(int arr[],int a,int b){\n\t\tint temp = arr[a];\n\t\tarr[a] = arr[b];\n\t\tarr[b] = temp;\n\t}\n\t\n\tpublic static void main(String args[]){\n\t\tint arr[] = {1,2,3,4,5,6,7,8};\n\t\tShuffleArray sa = new ShuffleArray();\n\t\tsa.shuffle(arr);\n\t\tSystem.out.println();\n\t\tfor(int i=0; i < arr.length; i++){\n\t\t\tSystem.out.print(arr[i] + \" \");\n\t\t}\n\t\t\n\t\tfor(int i=0; i < arr.length; i++){\n\t\t\tSystem.out.println((int)(Math.random()*10) + 1);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/interview/recursion/AllAdjacentCombination.java",
    "content": "package com.interview.recursion;\n\n/**\n * Generate all combination of size k and less of adjacent numbers\n * e.g 1,2,3,4 k = 2\n * 1 2 3 4\n * 12 3 4\n * 1 23 4\n * 1 2 3 34\n * 12 34\n * @author tusroy\n *\n */\npublic class AllAdjacentCombination {\n\n    public void combination(int input[],int result[],int k,int pos,int r){\n        \n        if(pos == input.length){\n            for(int i=0; i < r ; i++){\n                System.out.print(result[i] + \" \");\n            }\n            System.out.println();\n            return;\n        }\n        for(int i=pos; i < pos + k && i < input.length; i++ ){\n            result[r] = formNumber(input,pos,i);\n            combination(input,result,k,i+1,r+1);\n        }\n    }\n    \n    private int formNumber(int input[], int start, int end){\n        int num = 0;\n        for(int i=start; i <=end; i++){\n            num = num*10 + input[i];\n        }\n        return num;\n    }\n     \n    public static void main(String args[]){\n        AllAdjacentCombination adc = new AllAdjacentCombination();\n        int input[] = {1,2,3,4,5};\n        int result[] = new int[input.length];\n        adc.combination(input,result,3,0,0);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/Bracketology.java",
    "content": "package com.interview.recursion;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\npublic class Bracketology {\n\n    public boolean matchBracket(char str[],int openCount,int pos){\n        \n        if(str.length == pos){\n            if(openCount == 0){\n                return true;\n            }\n            return false;\n        }\n        \n        if(str[pos] == '('){\n            openCount++;\n        }else{\n            openCount--;\n        }\n        if(openCount < 0){\n            return false;\n        }\n        \n        return matchBracket(str,openCount,pos+1);\n        \n    }\n    \n    private void printArray(char result[]){\n        for(int i=0; i < result.length; i++){\n            System.out.print(result[i]);\n        }\n        System.out.println();\n    }\n    \n    public void bracketPermutation(char result[],int n, int pos,int openCount,int closeCount){\n        if(pos == 2*n){\n            printArray(result);\n            return;\n        }\n        if(openCount < n){\n            result[pos] = '(';\n            bracketPermutation(result, n, pos+1,openCount+1,closeCount);\n        }\n        if(closeCount < openCount){\n            result[pos] = ')';\n            bracketPermutation(result, n, pos+1, openCount, closeCount+1);\n        }\n    }\n    \n    public boolean matchBracket(char []brackets){\n        Deque<Character> stack = new LinkedList<Character>();\n        \n        for(Character ch : brackets){\n            char checkChar = getOpeningCharacter(ch);\n            if(checkChar == 0){\n                stack.addFirst(ch);\n            }else{\n                if(stack.size() == 0 || stack.peek() != checkChar){\n                    return false;\n                }else{\n                    stack.pop();\n                }\n            }\n        }\n        if(stack.size() > 0){\n            return false;\n        }\n        return true;\n        \n    }\n    \n    private Character getOpeningCharacter(char ch){\n        switch(ch){\n            case ')' : return '(';\n            case ']' : return '[';\n            case '}' : return '{';\n            default : return 0;\n        }\n        \n    }\n\n    \n    public static void main(String args[]){\n        \n        Bracketology matcher = new Bracketology();\n        //System.out.print(matcher.matchBracket(\"(())())\".toCharArray(), 0, 0));\n        int n=4;\n        char result[] = new char[n*2];\n//      matcher.bracketPermutation(result, n, 0, 0, 0);\n        \n        System.out.println(matcher.matchBracket(\"[({()}{}[])]\".toCharArray()));\n    }\n    \n    \n}\n"
  },
  {
    "path": "src/com/interview/recursion/ChainWordsToFormCircle.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * http://www.geeksforgeeks.org/given-array-strings-find-strings-can-chained-form-circle/\n * Test cases:\n * Empty input\n * 1 element in input\n * no chain formed\n * chain formed\n */\npublic class ChainWordsToFormCircle {\n\n    public List<String> formCircle(String input[]){\n        List<String> result = new ArrayList<String>();\n        //since chain is a circle any point can be the start point of the chain.\n        //We make input[0] as start point\n        result.add(input[0]);\n        boolean used[] = new boolean[input.length];\n        boolean r = formCircle(input,result,used,input[0].charAt(0));\n        if(!r){\n            return Collections.emptyList();\n        }\n        return result;\n    }\n    \n    //we keep track of first char of the chain and the end compare that with last char of last element of the chain\n    private boolean formCircle(String input[], List<String> result,boolean used[],char firstChar){\n        if(input.length == result.size()){\n            String str = result.get(result.size()-1);\n            if(firstChar == str.charAt(str.length()-1)){\n                return true;\n            }\n            return false;\n        }\n        String str = result.get(result.size()-1);\n        char lastChar = str.charAt(str.length()-1);\n        for(int i=1; i < input.length; i++){\n            if(used[i]){\n                continue;\n         \n            }\n            if(lastChar == input[i].charAt(0)){\n                used[i] = true;\n                result.add(input[i]);\n                boolean r = formCircle(input,result,used,firstChar);\n                if(r){\n                    return true;\n                }\n                used[i] = false;\n                result.remove(result.size()-1);\n            }\n            \n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        String notChaininput[] = {\"geeks\",\"king\", \"seeks\", \"sing\",\"gik\",\"kin\"};\n        String chainInput[] = {\"king\",\"gik\",\"geeks\", \"seeks\", \"sing\"};\n        ChainWordsToFormCircle cwt = new ChainWordsToFormCircle();\n        List<String> result = cwt.formCircle(chainInput);\n        if(result.size() == 0){\n            System.out.println(\"Not able to form a chain\");\n        }else{\n            for(String chainNode : result){\n                System.out.print(chainNode + \" \");\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/recursion/Combination.java",
    "content": "package com.interview.recursion;\n\nimport java.util.*;\n\npublic class Combination {\n\n   public void combination(char input[]){\n       Map<Character, Integer> countMap = new TreeMap<>();\n       for (char ch : input) {\n           countMap.compute(ch, (key, val) -> {\n               if (val == null) {\n                   return 1;\n               } else {\n                   return val + 1;\n               }\n           });\n       }\n       char str[] = new char[countMap.size()];\n       int count[] = new int[countMap.size()];\n       int index = 0;\n       for (Map.Entry<Character, Integer> entry : countMap.entrySet()) {\n           str[index] = entry.getKey();\n           count[index] = entry.getValue();\n           index++;\n       }\n       char[] output = new char[input.length];\n       combination(str, count, 0, output, 0);\n    }\n\n    private void combination(char input[],int count[],int pos, char output[],int len){\n        print(output, len);\n        for(int i=pos; i < input.length; i++){\n            if (count[i] == 0) {\n                continue;\n            }\n            output[len] = input[i];\n            count[i]--;\n            combination(input, count, i, output, len + 1);\n            count[i]++;\n        }\n    }\n\n    private void print(char result[],int pos){\n        for(int i=0; i < pos; i++){\n            System.out.print(result[i] + \" \");\n        }\n        System.out.println();\n    }\n\n    public void combinationEasy(char[] input) {\n        List<Character> r = new ArrayList<>();\n        Arrays.sort(input);\n        combinationEasy(input, 0, r);\n    }\n\n    private void combinationEasy(char[] input, int pos, List<Character> r) {\n\n        r.forEach(r1 -> System.out.print(r1 + \" \"));\n        System.out.println();\n        for (int i = pos; i < input.length; i++) {\n            if (i != pos && input[i] == input[i-1]) {\n                continue;\n            }\n            r.add(input[i]);\n            combinationEasy(input, i + 1, r);\n            r.remove(r.size() - 1);\n        }\n    }\n\n    public static void main(String args[]){\n        Combination c = new Combination();\n        c.combination(\"aabbc\".toCharArray());\n        c.combinationEasy(\"aabbc\".toCharArray());\n\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/recursion/CombinationOfSizeK.java",
    "content": "package com.interview.recursion;\n\n/**\n * http://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/\n */\npublic class CombinationOfSizeK {\n\n    public void combination(int arr[],int k){\n        int result[] = new int[k];\n        combinationUtil(arr,k,0,result,0);\n    }\n\n    private void combinationUtil(int arr[],int k, int pos,int result[],int start){\n        if(pos == k){\n            for(int i=0; i < k; i++){\n                System.out.print(result[i] + \" \");\n            }\n            System.out.print(\"\\n\");\n            return;\n        }\n        for(int i=start; i < arr.length; i++){\n            result[pos] = arr[i];\n            combinationUtil(arr,k,pos+1,result,i+1);\n        }\n    }\n    \n    public static void main(String args[]){\n        CombinationOfSizeK kk = new CombinationOfSizeK();\n        int arr[] = {1,2,3,4};\n        kk.combination(arr, 2);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/CombinationWithStar.java",
    "content": "package com.interview.recursion;\n\n/**\n * e.g a, b c \n * * * *\n * a * *\n * a b *\n * a b c\n * * b *\n * * b c\n * * * c\n * \n * Idea is to store the index of values in used[] array. So just\n * like regular combination if used is set print it else print *\n */\npublic class CombinationWithStar {\n\n    public void combine(char input[], int pos, boolean used[]){\n        printArray(input, used);\n        for(int i= pos; i < input.length; i++){\n            used[i] = true;\n            combine(input, i+1, used);\n            used[i] = false;\n        }\n    }\n    \n    private void printArray(char result[], boolean used[]){\n        for(int i=0; i < used.length; i++){\n            if(used[i]){\n                System.out.print(result[i] + \" \");\n            }else{\n                System.out.print(\"* \");\n            }\n        }\n        System.out.println();\n    }\n     \n    public static void main(String args[]){\n        char input[] = {'a','b','c','d'};\n        CombinationWithStar cws = new CombinationWithStar();\n        boolean used[] = new boolean[input.length];\n        cws.combine(input, 0, used);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/DifferentWaysToAddParentheses.java",
    "content": "package com.interview.recursion;\n\nimport java.util.*;\n\n/**\n https://leetcode.com/problems/different-ways-to-add-parentheses/\n */\npublic class DifferentWaysToAddParentheses {\n    public List<Integer> diffWaysToCompute(String str) {\n        List<Integer> operands = new ArrayList<>();\n        List<Character> operators = new ArrayList<>();\n        int prev = -1;\n        for (int i = 0; i < str.length(); i++) {\n            if (str.charAt(i) == '+' || str.charAt(i) == '-' || str.charAt(i) == '*') {\n                operands.add(Integer.parseInt(str.substring(prev + 1, i)));\n                operators.add(str.charAt(i));\n                prev = i;\n            }\n        }\n        operands.add(Integer.parseInt(str.substring(prev + 1, str.length())));\n        return diffWaysToComputeUtil(operands, operators, 0, operators.size() - 1);\n    }\n\n    private List<Integer> diffWaysToComputeUtil(List<Integer> operands, List<Character> operators, int start, int end) {\n        if (start > end) {\n            if (start >= 0) {\n                return Collections.singletonList(operands.get(start));\n            } else {\n                return Collections.singletonList(operands.get(end));\n            }\n        }\n        List<Integer> result = new ArrayList<>();\n        for (int i = start; i <= end; i++) {\n            List<Integer> leftResult = diffWaysToComputeUtil(operands, operators, start, i - 1);\n            List<Integer> rightResult = diffWaysToComputeUtil(operands, operators, i + 1, end);\n\n            for (int left : leftResult) {\n                for (int right : rightResult) {\n                    result.add((int)operate(left, right, operators.get(i)));\n                }\n            }\n        }\n        return result;\n     }\n\n    private long operate(int val1, int val2, char op) {\n        switch (op) {\n            case '+':\n                return val1 + val2;\n            case '-':\n                return val1 - val2;\n            case '*':\n                return val1 * val2;\n        }\n        throw new IllegalArgumentException();\n    }\n\n    public static void main(String args[]) {\n        DifferentWaysToAddParentheses df = new DifferentWaysToAddParentheses();\n        List<Integer> result = df.diffWaysToCompute(\"2*3-4*5\");\n        result.forEach(s -> System.out.println(s));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/FancyShuffle.java",
    "content": "package com.interview.recursion;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\n/**\n * Date 07/05/2015\n * @author Tushar Roy\n * \n * Given an input with duplicate characters generate a shuffle which does not have \n * two duplicate characters together\n * \n * Do regular permutation with repetition with additional constraint of keeping\n * duplicates away from each other.\n *\n */\npublic class FancyShuffle {\n\n\tpublic char[] shuffle(char input[]){\n\t\tchar result[] = new char[input.length];\n\t\t\n\t\t//create a map of character to its frequency.\n\t\tMap<Character, Integer> map = new HashMap<Character,Integer>();\n\t\tfor(int i=0; i < input.length; i++){\n\t\t\tInteger count  = map.putIfAbsent(input[i], 1);\n\t\t\tif(count != null) {\n\t\t\t\tcount++;\n\t\t\t\tmap.put(input[i], count);\n\t\t\t}\n\t\t}\n\t\tchar newInput[] = new char[map.size()];\n\t\tint freq[] = new int[map.size()];\n\t\t\n\t\t//create a new char array and freq array from map.\n\t\tint index = 0;\n\t\tfor(Entry<Character,Integer> entry :  map.entrySet()){\n\t\t\tnewInput[index] = entry.getKey();\n\t\t\tfreq[index] = entry.getValue();\n\t\t\tindex++;\n\t\t}\n\t\t//assuming char with ASCII value 0 does not exists in the input\n\t\tshuffleUtil(newInput,freq, result, 0, (char)0);\n\t\treturn result;\n\t}\n\t\n\t//regular permutation code. If we do find a permutation which satisfies the\n\t//constraint then return true and stop the process.\n\tprivate boolean shuffleUtil(char input[], int freq[], char result[], int pos, char lastVal) {\n\t\tif(pos == result.length){\n\t\t\treturn true;\n\t\t}\n\t\t\n\t\tfor(int i=0; i < input.length; i++){\n\t\t\tif(lastVal == input[i]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(freq[i] == 0) { \n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfreq[i]--;\n\t\t\tresult[pos] = input[i];\n\t\t\tif(shuffleUtil(input, freq, result, pos+1, input[i])){\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tfreq[i]++;\n\t\t}\n\t\treturn false;\n\t}\n\t\n\tpublic static void main(String args[]) {\n\t\tFancyShuffle fs = new FancyShuffle();\n\t\tchar result[] = fs.shuffle(\"bbcdaaaaa\".toCharArray());\n\t\tfor(char ch : result) { \n\t\t\tSystem.out.print(ch);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/interview/recursion/InterpretationOfArray.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * http://www.geeksforgeeks.org/find-all-possible-interpretations/\n */\npublic class InterpretationOfArray {\n\n    public void interpret(int arr[]){\n        char t[][] = new char[arr.length][2];\n        for(int i=0; i < arr.length; i++){\n            for(int j=0; j < 2; j++){\n                t[i][j] = '0';\n            }\n        }\n        for(int l=1; l <=2; l++){\n            for(int i=0; i <= arr.length -l ; i++){\n                int j = i + l-1;\n                t[i][l-1] = getRepresentation(i == j ? arr[i] : arr[i]*10 +arr[j]);\n            }\n        }\n        List<Character> result = new ArrayList<Character>();\n        interpret(arr.length,0,result,t);\n    }\n    \n    private void interpret(int len,int pos,List<Character> result,char[][] t){\n        if(pos== len){\n            print(result);\n            return;\n        }\n        if(t[pos][0] != '0'){\n            result.add(t[pos][0]);\n            interpret(len,pos+1,result,t);\n            result.remove(result.size()-1);\n        }\n        \n        if(pos+1 < len && t[pos][1] != '0'){\n            result.add(t[pos][1]);\n            interpret(len, pos+2, result, t);\n            result.remove(result.size()-1);\n        }\n            \n    }\n    \n    private void print(List<Character> result){\n        for(int i=0; i < result.size(); i++){\n            System.out.print(result.get(i) + \" \");\n        }\n        System.out.println();\n    }\n    \n    private char getRepresentation(int number){\n        if(number > 26 || number <= 0){\n            return '0';\n        }\n        return (char)('a' + number -1);\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {1,2,6,1,7};\n        InterpretationOfArray ioa = new InterpretationOfArray();\n        ioa.interpret(arr);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/recursion/KeyPadPermutation.java",
    "content": "package com.interview.recursion;\n\n/**\n * http://stackoverflow.com/questions/2344496/how-can-i-print-out-all-possible-letter-combinations-a-given-phone-number-can-re\n */\npublic class KeyPadPermutation {\n\n    public void permute(int input[]) {\n        char result[] = new char[input.length];\n        permute(input,0,result);\n    }\n\n    private void permute(int input[], int pos, char result[]) {\n        if (pos == input.length) {\n            for (int i = 0; i < result.length; i++) {\n                System.out.print(result[i]);\n            }\n            System.out.println();\n            return;\n        }\n\n        char[] str = getCharSetForNumber(input[pos]);\n        for (char ch : str) {\n            result[pos] = ch;\n            permute(input, pos+1, result);\n        }\n    }\n\n    private char[] getCharSetForNumber(int num) {\n        switch(num){\n            case 1 : return \"abc\".toCharArray();\n            case 2 : return \"def\".toCharArray();\n            case 3: return \"ghi\".toCharArray();\n            case 4: return \"jkl\".toCharArray();\n            case 5: return \"mno\".toCharArray();\n            case 6: return \"pqrs\".toCharArray();\n            case 8: return \"tuv\".toCharArray();\n            case 9: return \"wxyz\".toCharArray();\n        }\n        throw new IllegalArgumentException();\n    }\n    \n    public static void main(String args[]){\n        int input[] = {2,3,1,5};\n        KeyPadPermutation kpp = new KeyPadPermutation();\n        kpp.permute(input);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/LongestAbsolutePath.java",
    "content": "package com.interview.recursion;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Stack;\nimport java.util.StringTokenizer;\n\n/**\n * Find longest absolute path in file system indicated by \\n and \\t.\n *\n * Solution 1:\n * Create queue of file and its level. Then recurse from root towards file. Use level\n * to decide if next word in queue is in same level (so no more recursion) or next level so\n * going deep in recursion.\n *\n * Solution 2(iterative):\n * Keep pushing elements into stack till you either reach a file with . or a file whose number of tabs is less than\n * top of stack. If you reach file with extension then update the max. Otherwise keep popping from stack till number of tabs\n * at top of stack becomes less than current file. Maintain current length during push and pop.\n *\n * Time complexity O(n)\n * Space complexity O(n)\n *\n * https://leetcode.com/problems/longest-absolute-file-path/\n */\npublic class LongestAbsolutePath {\n    public int lengthLongestPath(String input) {\n        if (input.length() == 0) {\n            return 0;\n        }\n        StringTokenizer tokenizer = new StringTokenizer(input, \"\\n\");\n        Queue<Node> queue = new LinkedList<>();\n        while (tokenizer.hasMoreTokens()) {\n            queue.offer(new Node(tokenizer.nextToken()));\n        }\n        Node root = new Node(\"\", -1);\n        return lengthLongestPath(queue, root, 0);\n    }\n\n    public int lengthLongestPath(Queue<Node> queue, Node root, int currentLength) {\n        if (root.isFile) {\n            return currentLength + root.level;\n        }\n        if (queue.isEmpty()) {\n            return 0;\n        }\n        int max = 0;\n        while (!queue.isEmpty()) {\n            Node n = queue.peek();\n            if (root.level < n.level) {\n                queue.poll();\n                max = Math.max(max, lengthLongestPath(queue, n, n.file.length() + currentLength));\n            } else {\n                break;\n            }\n        }\n        return max;\n    }\n\n    class Node {\n        String file;\n        int level;\n        boolean isFile;\n        Node(String file, int level) {\n            this.file = file;\n            this.level = level;\n        }\n        Node(String file) {\n            int numberOfTabs = 0;\n            int i;\n            for (i = 0; i < file.length(); i++) {\n                if (file.charAt(i) == '\\t') {\n                    numberOfTabs++;\n                } else {\n                    break;\n                }\n            }\n            this.file = file.substring(i);\n            this.level = numberOfTabs;\n            this.isFile = file.contains(\".\");\n        }\n    }\n\n    public int lengthLongestPathIterative(String input) {\n        if (input.length() == 0) {\n            return 0;\n        }\n        String[] tokens = input.split(\"\\n\");\n        Stack<String> stack = new Stack<>();\n        Stack<Integer> stack1 = new Stack<>();\n        int len = 0;\n        int max = 0;\n        for (String token : tokens) {\n            int level = 0;\n            int i;\n            for (i = 0; i < token.length(); i++) {\n                if (token.charAt(i) == '\\t') {\n                    level++;\n                } else {\n                    break;\n                }\n            }\n            token = token.substring(i);\n            while (!stack1.isEmpty() && level <= stack1.peek()) {\n                stack1.pop();\n                String data = stack.pop();\n                len -= data.length() + 1; //+1 to account for '\\' between folders files\n            }\n            if (token.contains(\".\")) {\n                max = Math.max(max, len + token.length());\n            } else {\n                stack1.push(level);\n                stack.push(token);\n                len += token.length() + 1; //+1 to accoutn for '\\' between folders files\n            }\n        }\n        return max;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/MinimumEditForReversePolishNotation.java",
    "content": "package com.interview.recursion;\n\n/**\n *http://www.careercup.com/question?id=5762415492857856 \n */\npublic class MinimumEditForReversePolishNotation {\n\n    public int minimum(char input[]){\n        return minimum(input,0,0);\n    }\n    \n    private int minimum(char input[],int pos,int countXs){\n        if(pos == input.length){\n            //we should be always be left with 1 x otherwise notation is incomplete\n            if(countXs > 1){\n                return Integer.MAX_VALUE;\n            }\n            return 0;\n        }\n        //if input is x we can have x as it is or delete it or convert it to *.\n        //So basically we try all those options below\n        //If input is * we can take 2 xs and conver it to one x. If we dont have\n        //2xs then we can either delete this * or convert it to x.\n        //Remember adding anything does not make any sense since deleting things\n        //can achieve same things unless cost of adding is different from deleting\n        if(input[pos] == 'x'){\n            int v1 = minimum(input,pos+1,countXs+1);\n            int v2 = Integer.MAX_VALUE;\n            if(countXs > 1){\n                v2 = minimum(input,pos+1,countXs-1);\n                v2 =( v2 != Integer.MAX_VALUE ? v2 + 1 : Integer.MAX_VALUE);\n            }\n            int v3 = minimum(input,pos+1,countXs);\n            v3 =( v3 != Integer.MAX_VALUE ? v3 + 1 : Integer.MAX_VALUE);\n            return Math.min(Math.min(v1,v2),v3);\n        }else{\n            if(countXs >= 2){\n                return minimum(input,pos+1,countXs-1);\n            }else{\n                int v1 = minimum(input,pos+1,countXs);\n                v1 = (v1 != Integer.MAX_VALUE ? v1 + 1 : Integer.MAX_VALUE);\n                int v2 = minimum(input,pos+1,countXs+1);\n                v2 =( v2 != Integer.MAX_VALUE ? v2 + 1 : Integer.MAX_VALUE);\n                return Math.min(v1, v2);\n            }\n        }\n    }\n    public static void main(String args[]){\n        MinimumEditForReversePolishNotation mef = new MinimumEditForReversePolishNotation();\n        System.out.println(mef.minimum(\"xxxx*x*x*\".toCharArray()));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/NQueenProblem.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Date 02/20/2016\n * @author Tushar Roy\n *\n * Given nxn board place n queen on this board so that they dont attack each other. One solution is to find\n * any placement of queens which do not attack each other. Other solution is to find all placements of queen\n * on the board.\n *\n * Time complexity O(n*n)\n * Space complexity O(n*n)\n */\npublic class NQueenProblem {\n\n    class Position {\n        int row, col;\n        Position(int row, int col) {\n            this.row = row;\n            this.col = col;\n        }\n    }\n\n    public Position[] solveNQueenOneSolution(int n) {\n        Position[] positions = new Position[n];\n        boolean hasSolution = solveNQueenOneSolutionUtil(n, 0, positions);\n        if (hasSolution) {\n            return positions;\n        } else {\n            return new Position[0];\n        }\n    }\n\n    private boolean solveNQueenOneSolutionUtil(int n, int row, Position[] positions) {\n        if (n == row) {\n            return true;\n        }\n        int col;\n        for (col = 0; col < n; col++) {\n            boolean foundSafe = true;\n\n            //check if this row and col is not under attack from any previous queen.\n            for (int queen = 0; queen < row; queen++) {\n                if (positions[queen].col == col || positions[queen].row - positions[queen].col == row - col ||\n                        positions[queen].row + positions[queen].col == row + col) {\n                    foundSafe = false;\n                    break;\n                }\n            }\n            if (foundSafe) {\n                positions[row] = new Position(row, col);\n                if (solveNQueenOneSolutionUtil(n, row + 1, positions)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    /*\n     *Solution for https://leetcode.com/problems/n-queens/\n     */\n    public List<List<String>> solveNQueens(int n) {\n        List<List<String>> result = new ArrayList<>();\n        Position[] positions = new Position[n];\n        solve(0, positions, result, n);\n        return result;\n    }\n\n    public void solve(int current, Position[] positions, List<List<String>> result, int n) {\n        if (n == current) {\n            StringBuffer buff = new StringBuffer();\n            List<String> oneResult = new ArrayList<>();\n            for (Position p : positions) {\n                for (int i = 0; i < n; i++) {\n                    if (p.col == i) {\n                        buff.append(\"Q\");\n                    } else {\n                        buff.append(\".\");\n                    }\n                }\n                oneResult.add(buff.toString());\n                buff = new StringBuffer();\n\n            }\n            result.add(oneResult);\n            return;\n        }\n\n        for (int i = 0; i < n; i++) {\n            boolean foundSafe = true;\n            for (int j = 0; j < current; j++) {\n                if (positions[j].col == i || positions[j].col - positions[j].row == i - current || positions[j].row + positions[j].col == i + current) {\n                    foundSafe = false;\n                    break;\n                }\n            }\n            if (foundSafe) {\n                positions[current] = new Position(current, i);\n                solve(current + 1, positions, result, n);\n            }\n        }\n    }\n\n    public static void main(String args[]) {\n        NQueenProblem s = new NQueenProblem();\n        Position[] positions = s.solveNQueenOneSolution(6);\n        Arrays.stream(positions).forEach(position -> System.out.println(position.row + \" \" + position.col));\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/recursion/OneEditApart.java",
    "content": "package com.interview.recursion;\n\n/**\n * Date 03/26/2016\n * @author Tushar Roy\n * Given two strings S and T, determine if they are both one edit distance apart.\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * Reference\n * https://leetcode.com/problems/one-edit-distance/\n */\npublic class OneEditApart {\n\n    public boolean isOneEditDistance(String s, String t) {\n        String larger, smaller;\n        if (s.length() < t.length()) {\n            larger = t;\n            smaller = s;\n        } else {\n            larger = s;\n            smaller = t;\n        }\n\n        if (Math.abs(larger.length() - smaller.length()) > 1) {\n            return false;\n        }\n\n        boolean diffFound = false;\n        int j = 0;\n        for (int i = 0; i < smaller.length();) {\n            if (smaller.charAt(i) == larger.charAt(j)) {\n                i++;\n                j++;\n            } else {\n                if (diffFound) {\n                    return false;\n                } else {\n                    diffFound = true;\n                    if (smaller.length() == larger.length()) {\n                        i++; j++;\n                    } else {\n                        j++;\n                    }\n                }\n            }\n        }\n        return diffFound || j < larger.length();\n    }\n\n    public static void main(String args[]){\n        OneEditApart oea = new OneEditApart();\n        System.out.println(oea.isOneEditDistance(\"cat\", \"dog\"));\n        System.out.println(oea.isOneEditDistance(\"cat\", \"cats\"));\n        System.out.println(oea.isOneEditDistance(\"cat\", \"cut\"));\n        System.out.println(oea.isOneEditDistance(\"cats\", \"casts\"));\n        System.out.println(oea.isOneEditDistance(\"catsts\", \"casts\"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/OperatorAdditionForTarget.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 02/23/2016\n * @author Tushar Roy\n *\n * Given a string eg. 123 and target e.g 6. Put operators *, +, - between 123 so that it evaluates to 6\n *\n * https://leetcode.com/problems/expression-add-operators/\n */\npublic class OperatorAdditionForTarget {\n    public List<String> addOperators(String num, int target) {\n        if (num.length() == 0) {\n            return new ArrayList<>();\n        }\n        List<String> result = new ArrayList<>();\n        StringBuffer buff = new StringBuffer();\n        dfs(num, 0, target, 0, 0, result, buff);\n        return result;\n    }\n\n    private void dfs(String nums, int pos, int target, long runningTotal, long multiplicationVal, List<String> result, StringBuffer buff) {\n        if (pos == nums.length()) {\n            if (runningTotal == target) {\n                result.add(buff.toString());\n            }\n            return;\n        }\n\n        for (int i = pos; i < nums.length(); i++) {\n\n            if (i != pos && nums.charAt(pos) == '0') {\n                break;\n            }\n            String subStr = nums.substring(pos, i + 1);\n            long num = Long.parseLong(subStr);\n            if (pos == 0) {\n                dfs(nums, i + 1, target, num, num, result, buff.append(num));\n                buff.delete(buff.length() - subStr.length(), buff.length());\n                continue;\n            }\n            dfs(nums, i + 1, target, runningTotal + num, num, result, buff.append(\"+\").append(subStr));\n            buff.delete(buff.length() - subStr.length() - 1, buff.length());\n            dfs(nums, i + 1, target, runningTotal - num, -num, result, buff.append(\"-\").append(subStr));\n            buff.delete(buff.length() - subStr.length() - 1, buff.length());\n            dfs(nums, i + 1, target, runningTotal + num * multiplicationVal - multiplicationVal, num * multiplicationVal,\n                    result, buff.append(\"*\").append(subStr));\n            buff.delete(buff.length() - subStr.length() - 1, buff.length());\n        }\n    }\n\n    public static void main(String args[]) {\n        OperatorAdditionForTarget p = new OperatorAdditionForTarget();\n        List<String> result = p.addOperators(\"1234\", -1);\n        result.stream().forEach(s -> System.out.println(s));\n    }\n}"
  },
  {
    "path": "src/com/interview/recursion/OptimalDivision.java",
    "content": "package com.interview.recursion;\n\n/**\n * Date 05/09/2017\n * @author Tushar Roy\n *\n * https://leetcode.com/problems/optimal-division/#/description\n */\npublic class OptimalDivision {\n    public String optimalDivision(int[] nums) {\n        Result r = optimalDivison(nums, 0, nums.length - 1, true);\n        System.out.println(r.val);\n        return r.str;\n    }\n\n    private Result optimalDivison(int[] nums, int start, int end, boolean maximize) {\n        if (start == end) {\n            return new Result(nums[start], String.valueOf(nums[start]));\n        }\n\n        double maxResult = 0;\n        double minResult = Double.MAX_VALUE;\n        String result = \"\";\n        int cutI = start;\n        String part1 = \"\";\n        String part2 = \"\";\n        for (int i = start; i < end; i++) {\n            Result d1 = optimalDivison(nums, start, i, maximize);\n            Result d2 = optimalDivison(nums, i + 1, end, !maximize);\n            double val = d1.val / d2.val;\n            if (maximize) {\n                if (maxResult < val) {\n                    maxResult = val;\n                    part1 = d1.str;\n                    part2 = d2.str;\n                    cutI = i;\n                }\n            } else {\n                if (minResult > val) {\n                    minResult = val;\n                    part1 = d1.str;\n                    part2 = d2.str;\n                    cutI = i;\n                }\n            }\n        }\n        if (cutI < end - 1) {\n            result = part1 + \"/(\" + part2 + \")\";\n        } else {\n            result = part1 + \"/\" + part2;\n        }\n        return maximize ? new Result(maxResult, result) : new Result(minResult, result);\n    }\n\n    class Result {\n        double val;\n        String str;\n        Result(double val, String str) {\n            this.val = val;\n            this.str = str;\n        }\n    }\n\n    public static void main(String args[]) {\n       // int[] nums = {1000, 100, 10, 2};\n        int[] nums = {6,2,3,4,5};\n        OptimalDivision od = new OptimalDivision();\n        System.out.println(od.optimalDivision(nums));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/PrintAllPathFromTopLeftToBottomRight.java",
    "content": "package com.interview.recursion;\n\nimport java.util.Arrays;\n\n/**\n http://www.geeksforgeeks.org/print-all-possible-paths-from-top-left-to-bottom-right-of-a-mxn-matrix/\n */\npublic class PrintAllPathFromTopLeftToBottomRight {\n\n\n    public void print(int arr[][],int row, int col,int result[],int pos){\n        if(row == arr.length-1 && col == arr[0].length-1){\n            result[pos] = arr[row][col];\n            System.out.println(Arrays.toString(result));\n            return;\n        }\n        if(row >= arr.length || col >= arr[0].length){\n            return;\n        }\n        \n        result[pos] = arr[row][col];\n        print(arr,row,col+1,result,pos+1);\n        print(arr,row+1,col,result,pos+1);\n    }\n    \n    public static void main(String args[]){\n        PrintAllPathFromTopLeftToBottomRight pam = new PrintAllPathFromTopLeftToBottomRight();\n        int arr[][] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};\n        int result[] = new int[arr.length + arr[0].length-1];\n        pam.print(arr, 0, 0, result,0);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/PrintAllSubsequence.java",
    "content": "package com.interview.recursion;\n\n/**\n * Date 02/25/2016\n * @author Tushar Roy\n *\n * Print all subsequence of a given array.\n *\n * Time complexity is exponential\n * Space complexity is O(n)\n */\npublic class PrintAllSubsequence {\n    public void print(int[] input) {\n        int[] output = new int[input.length];\n        for (int i = 0; i < input.length; i++) {\n            output[0] = input[i];\n            print(input, output, 1, i + 1, true);\n        }\n    }\n\n    private void print(int[] input, int[] output, int len, int current, boolean print) {\n\n        if (print) {\n            for (int i = 0; i < len; i++) {\n                System.out.print(output[i] + \" \");\n            }\n            System.out.println();\n        }\n        if (current == input.length) {\n            return;\n        }\n\n\n        output[len] = input[current];\n        print(input, output, len + 1, current + 1, true);\n        print(input, output, len, current + 1, false);\n    }\n\n    public static void main(String args[]) {\n        PrintAllSubsequence ps = new PrintAllSubsequence();\n        int[] input = {1, 2, 3, 4};\n        ps.print(input);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/PrintArrayInAdjacentWay.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * http://www.geeksforgeeks.org/find-all-possible-interpretations/\n * This is class fibonacci series example.\n * e.g {1,1,1,1} -> when n = 4 total number of ways possible are\n * f(3) + f(2). \n * Suppose we solved for n =3 . When we add another 1 we know that total number\n * of combinations without this 1 doing anything will be f(3). Not if we involve this new 1\n * and exclude f(3) we get total of f(2) because think of as if we combined last 2 ones and \n * then see how many ways first 2 ones can combine\n * example \n * {1,1,1, new1}\n * f(3) is all combinations without including new1\n * Now lets combine {1,1,newnew1} . This gives total of f(2)\n * Test cases\n * negative number\n * 0\n * null array\n */\npublic class PrintArrayInAdjacentWay {\n\n    public void printArray(int len,int k){\n        List<Integer> result = new ArrayList<Integer>();\n        printArray(len,0,result,k);\n    }\n    \n    private void printArray(int len, int pos,List<Integer> result,int k){\n        if(pos > len){\n            return;\n        }\n        if(pos == len){\n            for(int i:result){\n                System.out.print(i + \" \");\n            }\n            System.out.println();\n            return ;\n        }\n        \n        for(int i=0; i < k ; i++){\n            result.add(i+1);\n            printArray(len,pos+i+1,result,k);\n            result.remove(result.size()-1);\n        }\n    }\n    \n    public int numberOfWaysPossible(int input[],int pos){\n        if(pos > input.length){\n            return 0;\n        }\n        if(pos == input.length){\n            return 1;\n        }\n        \n        \n        int count = numberOfWaysPossible(input,pos+1);\n        if(pos + 1 < input.length){\n            int num = input[pos]*10 + input[pos+1];\n            if(num < 27){\n                count += numberOfWaysPossible(input, pos+2);\n            }\n        }\n        return count;\n    }\n    \n    /**\n     * Since we know this is same as fibonacci series all we have to do is either use sum of last two numbers if \n     * total is less than equal to 26 or use just last number if total is greater than 26\n     * total is calculated by creating a number from current number and previous number\n     * @param input\n     * @return\n     */\n    public int numberOfWaysPossibleFaster(int input[]){\n        int a0 = 1;\n        int a1 = 1;\n        int c = 0;\n        for(int i=1; i < input.length; i++){\n            if(input[i] + input[i-1]*10 <=26){\n                c = a1 + a0;\n            }else{\n                c = a1;\n            }\n            a0 = a1;\n            a1 = c;\n        }\n        return c;\n    }\n    \n    public static void main(String args[]){\n        PrintArrayInAdjacentWay paw = new PrintArrayInAdjacentWay();\n    //  paw.printArray(5, 2);\n        int input[] = {1,3,7,7,1,7,2,3,2};\n        System.out.println(paw.numberOfWaysPossible(input, 0));\n        System.out.println(paw.numberOfWaysPossibleFaster(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/PrintArrayInCustomizedFormat.java",
    "content": "package com.interview.recursion;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * http://www.geeksforgeeks.org/custom-tree-problem/\n */\npublic class PrintArrayInCustomizedFormat {\n\n    void print(char str[][]){\n        Map<Character,Boolean> visited = new HashMap<Character,Boolean>();\n        Map<Character,Boolean> alreadyPrinted = new HashMap<Character,Boolean>();\n        for(int i=0 ; i < str.length; i++){\n            if(!visited.containsKey(str[i][0]) || !visited.get(str[i][0])){\n                \n                if(!alreadyPrinted.containsKey(str[i][0]) || !alreadyPrinted.get(str[i][0])){\n                    System.out.println(str[i][0]);\n                    alreadyPrinted.put(str[i][0],true);\n                }\n                DFS(str,i,5,visited);\n            }\n        }\n    }\n    \n    private void DFS(char str[][],int pos,int distance,Map<Character,Boolean> visited){\n        for(int i=0; i < distance; i++){\n            System.out.print(\" \");\n        }\n        System.out.println(str[pos][1]);\n        char ch = str[pos][1];\n        visited.put(ch, true);\n        int i = pos+1;\n        for(; i < str.length; i++){\n            if(ch == str[i][0]){\n                if(i != str.length){\n                    DFS(str,i,distance + 5,visited);\n                }\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        char str[][] = {{'a','b'},{'a','c'},{'b','d'},{'c','f'},{'b','e'},{'x','y'},{'y','z'}};\n        \n        PrintArrayInCustomizedFormat pac = new PrintArrayInCustomizedFormat();\n        pac.print(str);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/PrintSumCombination.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Date 07/10/2015\n * @author Tushar Roy\n *\n * Given an input and total print all combinations with repetitions in this input\n * which sums to given total.\n * e.g\n * input - {2,3,5}\n * total - 10\n *\n * Output\n * [2,2,2,2,2],\n * [2,2,3,3],\n * [2,3,5],\n * [5,5]]\n * Reference\n * https://leetcode.com/problems/combination-sum/\n */\npublic class PrintSumCombination {\n\n    public List<List<Integer>> combinationSum(int[] candidates, int target) {\n        if (candidates.length == 0) {\n            return new ArrayList<>();\n        }\n        List<List<Integer>> rr = new ArrayList<>();\n        List<Integer> r = new ArrayList<>();\n        Arrays.sort(candidates);\n        combinationSumUtil(candidates, target, r, rr, 0);\n        return rr;\n    }\n\n    private void combinationSumUtil(int[] candidates, int target, List<Integer> r, List<List<Integer>> rr, int pos) {\n        if (target == 0) {\n            List<Integer> r1 = new ArrayList<>();\n            r1.addAll(r);\n            rr.add(r1);\n            return;\n        }\n\n        if (target < 0) {\n            return;\n        }\n\n        if (pos == candidates.length) {\n            return;\n        }\n\n        r.add(candidates[pos]);\n        combinationSumUtil(candidates, target - candidates[pos], r, rr, pos);\n        r.remove(r.size() - 1);\n\n        combinationSumUtil(candidates, target, r, rr, pos + 1);\n    }\n\n    public static void main(String args[]) {\n        int input[] = {2,3,5};\n        PrintSumCombination psc = new PrintSumCombination();\n        List<List<Integer>> result = psc.combinationSum(input, 10);\n        result.forEach(r -> {\n            r.forEach(r1 -> System.out.print(r1 + \" \"));\n            System.out.println();\n        });\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/ReconstructItinerary.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Date 03/08/2016\n * @author Tushar Roy\n *\n * Reconstruct itinerary based on ticket.\n *\n * https://leetcode.com/problems/reconstruct-itinerary/\n */\npublic class ReconstructItinerary {\n    public List<String> findItinerary(String[][] tickets) {\n        List<Itinerary> input = new ArrayList<>();\n        for (String[] ticket : tickets) {\n            input.add(new Itinerary(ticket[0], ticket[1]));\n        }\n        Collections.sort(input);\n        List<String> output = new ArrayList<>();\n        boolean[] used = new boolean[input.size()];\n        findItineraryUtil(input, used, \"JFK\", output, 0);\n        return output;\n    }\n\n    boolean findItineraryUtil(List<Itinerary> input, boolean[] used, String end, List<String> output, int count) {\n        if (count == used.length) {\n            output.add(end);\n            return true;\n        }\n        for (int i = 0; i < input.size(); i++) {\n            if (used[i]) {\n                continue;\n            }\n            Itinerary itr = input.get(i);\n            if (itr.start.equals(end)) {\n                output.add(itr.start);\n                used[i] = true;\n                if (findItineraryUtil(input, used, itr.dest, output, count + 1)) {\n                    return true;\n                }\n                used[i] = false;\n                output.remove(output.size() - 1);\n            }\n        }\n        return false;\n    }\n\n    class Itinerary implements Comparable<Itinerary> {\n        String start;\n        String dest;\n        Itinerary(String start, String dest) {\n            this.start = start;\n            this.dest = dest;\n        }\n\n        @Override\n        public int compareTo(Itinerary other) {\n            if (this.start.equals(other.start)) {\n                return this.dest.compareTo(other.dest);\n            } else {\n                return this.start.compareTo(other.start);\n            }\n        }\n    }\n\n    public static void main(String args[]) {\n        String input[][] = {{\"MUC\",\"LHR\"},{\"JFK\",\"MUC\"},{\"SFO\",\"SJC\"},{\"LHR\",\"SFO\"}};\n        ReconstructItinerary ri = new ReconstructItinerary();\n        List<String> output = ri.findItinerary(input);\n        output.forEach(r -> System.out.print(r + \" \"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/RemoveInvalidParenthesis.java",
    "content": "package com.interview.recursion;\n\nimport java.util.*;\n\n/**\n * Date 03/03/2016\n * @author Tushar Roy\n * \n * Remove the minimum number of invalid parentheses in order to make the input string valid.\n * Return all possible results\n *\n * Reference\n * https://leetcode.com/problems/remove-invalid-parentheses/\n */\npublic class RemoveInvalidParenthesis {\n\n    public List<String> removeInvalidParentheses(String s) {\n        Set<String> res = new HashSet<>();\n        int rmL = 0, rmR = 0;\n        for(int i = 0; i < s.length(); i++) {\n            if(s.charAt(i) == '(') rmL++;\n            if(s.charAt(i) == ')') {\n                if(rmL != 0) rmL--;\n                else rmR++;\n            }\n        }\n        DFS(res, s, 0, rmL, rmR, 0, new StringBuilder());\n        return new ArrayList<String>(res);\n    }\n\n    public void DFS(Set<String> res, String s, int i, int rmL, int rmR, int open, StringBuilder sb) {\n        if(i == s.length() && rmL == 0 && rmR == 0 && open == 0) {\n            res.add(sb.toString());\n            return;\n        }\n        if(i == s.length() || rmL < 0 || rmR < 0 || open < 0) return;\n\n        char c = s.charAt(i);\n        int len = sb.length();\n\n        if(c == '(') {\n            DFS(res, s, i + 1, rmL - 1, rmR, open, sb);\n            DFS(res, s, i + 1, rmL, rmR, open + 1, sb.append(c));\n\n        } else if(c == ')') {\n            DFS(res, s, i + 1, rmL, rmR - 1, open, sb);\n            DFS(res, s, i + 1, rmL, rmR, open - 1, sb.append(c));\n\n        } else {\n            DFS(res, s, i + 1, rmL, rmR, open, sb.append(c));\n        }\n\n        sb.setLength(len);\n    }\n\n    public static void main(String args[]) {\n\n        String s = \"(r(()()(\";\n        RemoveInvalidParenthesis rmp = new RemoveInvalidParenthesis();\n        List<String> result = rmp.removeInvalidParentheses(s);\n        result.forEach(s1 -> System.out.println(s1));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/RestoreIPAddresses.java",
    "content": "package com.interview.recursion;\n\nimport java.util.*;\n\n/**\n * Date 04/04/2016\n * @author Tushar Roy\n *\n * Given a string containing only digits, restore it by returning all possible valid IP address combinations.\n *\n * Reference\n * https://leetcode.com/problems/restore-ip-addresses/\n */\npublic class RestoreIPAddresses {\n    public List<String> restoreIpAddresses(String s) {\n        List<String> result = new ArrayList<>();\n        List<String> current = new ArrayList<>();\n        restoreIpAddressesUtil(s, 0, 0, result, current);\n        return result;\n    }\n\n    private void restoreIpAddressesUtil(String s, int start, int count, List<String> result, List<String> current) {\n        if (start == s.length() && count == 4) {\n            StringBuffer stringBuffer = new StringBuffer(current.get(0));\n            for (int i = 1; i < current.size(); i++) {\n                stringBuffer.append(\".\").append(current.get(i));\n            }\n            result.add(stringBuffer.toString());\n            return;\n        } else if (start == s.length() || count == 4) {\n            return;\n        }\n        for (int i = start; i < s.length() && i < start + 3; i++) {\n            if (i != start && s.charAt(start) == '0') {\n                break;\n            }\n            String ip = s.substring(start, i + 1);\n            if (Integer.valueOf(ip) > 255) {\n                continue;\n            }\n            current.add(ip);\n            restoreIpAddressesUtil(s, i + 1, count + 1, result, current);\n            current.remove(current.size() - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/SetPairTogether.java",
    "content": "package com.interview.recursion;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 12/30/2015\n * @author Tushar Roy\n *\n * Given input array with every element in array having its pair element. How many minimum swaps needs to be\n * done so that all pair elements are adjacent to each other.\n *\n * Time complexity is O(2^n)\n *\n * http://www.geeksforgeeks.org/minimum-number-of-swaps-required-for-arranging-pairs-adjacent-to-each-other/\n */\npublic class SetPairTogether {\n\n    public int findMinimumSwaps(int input[], Map<Integer, Integer> pair) {\n        Map<Integer, Integer> index = new HashMap<>();\n        for (int i = 0; i < input.length; i++) {\n            index.put(input[i], i);\n        }\n        return findMinimumSwapsUtil(input, pair, index, 0);\n    }\n\n    public int findMinimumSwapsUtil(int input[], Map<Integer, Integer> pair, Map<Integer, Integer> index, int current) {\n        if (current == input.length) {\n            return 0;\n        }\n\n        int v1 = input[current];\n        int v2 = input[current + 1];\n        int pv2 = pair.get(v1);\n\n        if(pv2 == v2) {\n            return findMinimumSwapsUtil(input, pair, index, current + 2);\n        } else {\n            int idx1 = index.get(v1);\n            int idx2 = index.get(v2);\n\n            int idx3 = index.get(pair.get(v1));\n            int idx4 = index.get(pair.get(v2));\n\n            swap(index, input, idx2, idx3);\n            int val1 = findMinimumSwapsUtil(input, pair, index, current + 2);\n            swap(index, input, idx2, idx3);\n\n            swap(index, input, idx1, idx4);\n            int val2 = findMinimumSwapsUtil(input, pair, index, current + 2);\n            swap(index, input, idx1, idx4);\n\n            return 1 + Math.min(val1, val2);\n        }\n    }\n\n    private void swap(Map<Integer, Integer> index, int input[], int i, int j) {\n        index.compute(input[i], (k, v) -> j);\n        index.compute(input[j], (k, v) -> i);\n\n        int t = input[i];\n        input[i] = input[j];\n        input[j] = t;\n    }\n\n    public static void main(String args[]) {\n        SetPairTogether spt = new SetPairTogether();\n        int input[] = {3, 5, 6, 4, 1, 2};\n        Map<Integer, Integer> pair = new HashMap<>();\n        pair.put(1, 3);\n        pair.put(3, 1);\n        pair.put(2, 6);\n        pair.put(6, 2);\n        pair.put(4, 5);\n        pair.put(5 ,4);\n        System.out.println(spt.findMinimumSwaps(input, pair));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/StringInterleaving.java",
    "content": "package com.interview.recursion;\n\npublic class StringInterleaving {\n\n    private void printArray(char[] str){\n        for(int i=0; i < str.length; i++){\n            System.out.print(str[i]);\n        }\n        System.out.println();\n    }\n    \n    public void interleaving(char[] str1,char[] str2,int len1,int len2,int current, char []result){\n        \n        if(current == result.length){\n            printArray(result);\n            return;\n        }\n\n        if(len1 < str1.length){\n            result[current] = str1[len1];\n            interleaving(str1, str2, len1+1, len2, current+1, result);\n        }\n        if(len2 < str2.length){\n            result[current] = str2[len2];\n            interleaving(str1,str2,len1,len2+1,current+1,result);\n        }\n    }\n    \n    public static void main(String args[]){\n        \n        StringInterleaving si = new StringInterleaving();\n        String str1 =\"AB\";\n        String str2 = \"CDE\";\n        char[] result = new char[str1.length() + str2.length()];\n        si.interleaving(str1.toCharArray(), str2.toCharArray(), 0, 0, 0, result);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/recursion/StringPermutation.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.TreeMap;\n\n/**\n * Date 01/29/2016\n * @author Tushar Roy\n *\n * Generate all permutations of string in lexicographically sorted order where repetitions of\n * character is possible in string.\n */\npublic class StringPermutation {\n\n    public List<String> permute(char input[]) {\n        Map<Character, Integer> countMap = new TreeMap<>();\n        for (char ch : input) {\n            countMap.compute(ch, (key, val) -> {\n                if (val == null) {\n                    return 1;\n                } else {\n                    return val + 1;\n                }\n            });\n        }\n        char str[] = new char[countMap.size()];\n        int count[] = new int[countMap.size()];\n        int index = 0;\n        for (Map.Entry<Character, Integer> entry : countMap.entrySet()) {\n            str[index] = entry.getKey();\n            count[index] = entry.getValue();\n            index++;\n        }\n        List<String> resultList = new ArrayList<>();\n        char result[] = new char[input.length];\n        permuteUtil(str, count, result, 0, resultList);\n        return resultList;\n    }\n\n    public void permuteUtil(char str[], int count[], char result[], int level, List<String> resultList) {\n        if (level == result.length) {\n            resultList.add(new String(result));\n            return;\n        }\n\n        for(int i = 0; i < str.length; i++) {\n            if(count[i] == 0) {\n                continue;\n            }\n            result[level] = str[i];\n            count[i]--;\n            permuteUtil(str, count, result, level + 1, resultList);\n            count[i]++;\n        }\n    }\n\n    private void printArray(char input[]) {\n        for(char ch : input) {\n            System.out.print(ch);\n        }\n        System.out.println();\n    }\n\n    public static void main(String args[]) {\n        StringPermutation sp = new StringPermutation();\n        sp.permute(\"AABC\".toCharArray()).forEach(s -> System.out.println(s));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/StringPermutationRotation.java",
    "content": "package com.interview.recursion;\n\npublic class StringPermutationRotation {\n\n    private void swap(char arr[],int i, int j){\n        char temp = arr[i];\n        arr[i] = arr[j];\n        arr[j] =temp;\n    }\n    \n    private void printArray(char str[]){\n        for(int i=0; i< str.length; i++){\n            System.out.print(str[i]);\n        }\n        System.out.print(\"\\n\");\n    }\n    \n    public void permute(char[] str,int pos){\n        if(pos == str.length){\n            printArray(str);\n            return;\n        }\n        for(int i=pos; i < str.length; i++){\n            swap(str,pos,i);\n            permute(str,pos+1);\n            swap(str,pos,i);\n        }\n    }\n    \n    public static void main(String args[]){\n        String str = \"ABC\";\n        StringPermutationRotation sp = new StringPermutationRotation();\n        sp.permute(str.toCharArray(),0);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/SudokuSolver.java",
    "content": "package com.interview.recursion;\n\nimport java.util.Arrays;\n\n/**\n * Date 03/24/2016\n * @author Tushar Roy\n *\n * Write a program to solve a Sudoku puzzle by filling the empty cells.\n *\n * https://leetcode.com/problems/sudoku-solver/\n */\npublic class SudokuSolver {\n\n    public void solveSudoku(char[][] input) {\n        boolean[][] horizontal = new boolean[9][9];\n        boolean[][] vertical = new boolean[9][9];\n        boolean[][] box = new boolean[9][9];\n        for (int i = 0; i < input.length; i++) {\n            for (int j = 0; j < input[0].length; j++) {\n                if (input[i][j] == '.') {\n                    continue;\n                }\n                horizontal[i][input[i][j] - '1'] = true;\n                vertical[j][input[i][j] - '1'] = true;\n                int index = 3*(i/3) + j/3;\n                box[index][input[i][j] - '1'] = true;\n            }\n        }\n        solveSudokuUtil(input, horizontal, vertical, box, 0, 0);\n    }\n\n    private boolean solveSudokuUtil(char[][] input, boolean[][] horizontal, boolean[][] vertical, boolean[][] box, int row, int col) {\n        if (col == 9) {\n            row = row + 1;\n            col = 0;\n        }\n        if (row == 9) {\n            return true;\n        }\n\n        if (input[row][col] != '.') {\n            return solveSudokuUtil(input, horizontal, vertical, box, row, col + 1);\n        }\n\n        for (int val = 1; val <= 9; val++) {\n            int index = 3*(row/3) + col/3;\n            if (horizontal[row][val - 1] == false && vertical[col][val - 1] == false && box[index][val - 1] == false) {\n                horizontal[row][val - 1] = true;\n                vertical[col][val - 1] = true;\n                box[index][val - 1] = true;\n                input[row][col] = (char)(val + '0');\n                if (solveSudokuUtil(input, horizontal, vertical, box, row, col + 1)) {\n                    return true;\n                }\n                input[row][col] = '.';\n                horizontal[row][val - 1] = false;\n                vertical[col][val - 1] = false;\n                box[index][val - 1] = false;\n            }\n        }\n        return false;\n    }\n\n    public static void main(String args[]) {\n        SudokuSolver ss = new SudokuSolver();\n        char[][] input = new char[9][9];\n        for (int i = 0; i < input.length; i++) {\n            for (int j = 0; j < input.length; j++) {\n                input[i][j] = '.';\n            }\n        }\n\n        input[0] = \"..9748...\".toCharArray();\n        input[1] = \"7........\".toCharArray();\n        input[2] = \".2.1.9...\".toCharArray();\n        input[3] = \"..7...24.\".toCharArray();\n        input[4] = \".64.1.59.\".toCharArray();\n        input[5] = \".98...3..\".toCharArray();\n        input[6] = \"...8.3.2.\".toCharArray();\n        input[7] = \"........6\".toCharArray();\n        input[8] = \"...2759..\".toCharArray();\n\n        ss.solveSudoku(input);\n        for (int i = 0; i < input.length; i++) {\n            for (int j = 0; j < input.length; j++) {\n                System.out.print(input[i][j] + \" \");\n            }\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/WordCombination.java",
    "content": "package com.interview.recursion;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 07/20/2015\n * @author Tushar Roy\n *\n * Given a list of list of Strings. Print cartesian product of lists.\n * input -> {\"Hello\", \"World\"} , {\"Game\"}, {\"Go\",\"Home\"}\n * output ->\n * Hello Game Go\n * Hellow Game Home\n * World Game Go\n * World Game Home\n */\npublic class WordCombination {\n\n    public void printCombinations(List<List<String>> input) {\n        int[] result = new int[input.size()];\n        print(input,result, 0);\n    }\n\n    private void print(List<List<String>> input, int[] result, int pos) {\n\n        if(pos == result.length){\n            for (int i = 0; i < input.size(); i++) {\n                System.out.print(input.get(i).get(result[i]) + \" \");\n            }\n            System.out.println();\n            return;\n        }\n\n        for(int i=0; i < input.get(pos).size(); i++){\n            result[pos] = i;\n            print(input,result, pos+1);\n\n        }\n    }\n\n    public static void main(String args[]){\n        List<String> l1 = new ArrayList<>();\n        l1.add(\"quick\");\n        l1.add(\"slow\");\n\n        List<String> l2 = new ArrayList<>();\n        l2.add(\"brown\");\n        l2.add(\"red\");\n\n        List<String> l3 = new ArrayList<>();\n        l3.add(\"fox\");\n        l3.add(\"dog\");\n\n        List<List<String>> input = new ArrayList<>();\n        input.add(l1);\n        input.add(l2);\n        input.add(l3);\n\n        WordCombination wc = new WordCombination();\n        wc.printCombinations(input);\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/recursion/WordPattern.java",
    "content": "package com.interview.recursion;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Given a pattern and a string str, find if str follows the same pattern.\n\n Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty substring in str.\n * https://leetcode.com/problems/word-pattern-ii/\n */\npublic class WordPattern {\n    public boolean wordPatternMatch(String pattern, String str) {\n        Map<Character, String> map = new HashMap<>();\n        Set<String> set = new HashSet<>();\n        return wordPatternMatch(pattern, str, 0, 0, map, set);\n    }\n\n    public boolean wordPatternMatch(String pattern, String str, int pos1, int pos2, Map<Character, String> map, Set<String> set) {\n        if (pos1 == pattern.length()) {\n            return pos2 == str.length();\n        }\n\n        char ch = pattern.charAt(pos1);\n        String val = map.get(ch);\n        if (val != null) {\n            return pos2 + val.length() <= str.length() && val.equals(str.substring(pos2, pos2 + val.length())) && wordPatternMatch(pattern, str, pos1 + 1, pos2 + val.length(), map, set);\n        } else {\n            for (int i = pos2; i < str.length() - (pattern.length() - pos1 - 1); i++) {\n                String newStr = str.substring(pos2, i + 1);\n                if (set.contains(newStr)) {\n                    continue;\n                }\n                set.add(newStr);\n                map.put(ch, newStr);\n                if (wordPatternMatch(pattern, str, pos1 + 1, i + 1, map, set)) {\n                    return true;\n                }\n                set.remove(newStr);\n            }\n            map.remove(ch);\n        }\n        return false;\n    }\n\n    public static void main(String args[]) {\n        String pattern = \"abcbc\";\n        String str = \"bcdgflgfl\";\n        WordPattern wp = new WordPattern();\n        System.out.println(wp.wordPatternMatch(pattern, str));\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/regex/MultiSpaceReplacement.java",
    "content": "package com.interview.regex;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class MultiSpaceReplacement {\n\n    public void replace(String str){\n        Pattern pattern = Pattern.compile(\"^ +|  +| +$\");\n        Matcher matcher = pattern.matcher(str);\n        System.out.println(matcher.replaceAll(\"\"));\n        \n    }\n    \n    public static void main(String args[]){\n        String str = \"     This is Tushar  Roy  \";\n        MultiSpaceReplacement mrs = new MultiSpaceReplacement();\n        mrs.replace(str);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/sort/CountingSort.java",
    "content": "package com.interview.sort;\n\npublic class CountingSort {\n\n    private static int TOTAL = 10;\n\n    public void sort(int arr[]) {\n\n        int count[] = new int[TOTAL];\n\n        for (int i = 0; i < arr.length; i++) {\n            count[arr[i]]++;\n        }\n        int c = 0;\n        for (int i = 0; i < TOTAL; i++) {\n            while (count[i] > 0) {\n                arr[c++] = i;\n                count[i]--;\n            }\n        }\n    }\n\n    public void sort1(int arr[]) {\n\n        int count[] = new int[TOTAL];\n        int output[] = new int[arr.length];\n        for (int i = 0; i < arr.length; i++) {\n            count[arr[i]]++;\n        }\n        \n        for(int i=1; i < TOTAL; i++){\n            count[i] += count[i-1];\n        }\n        \n        for(int i=0; i <arr.length; i++){\n            output[count[arr[i]]-1] = arr[i];\n            count[arr[i]]--;\n        }\n        \n        for(int i=0; i < arr.length; i++){\n            arr[i] = output[i];\n        }\n    }\n\n    public static void main(String args[]) {\n        int arr[] = { 6, 1, 6, 7, 3, 1 };\n        CountingSort cs = new CountingSort();\n        cs.sort1(arr);\n        for (int i = 0; i < arr.length; i++) {\n            System.out.println(arr[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/sort/HeapSort.java",
    "content": "package com.interview.sort;\n\n/**\n * Date 04/03/2015\n * @author tusroy\n * \n * Heap Sort\n * Given an array sort it using heap sort\n * \n * Solution :\n * First convert the original array to create the heap out of the array\n * Then move the max element to last position and do heapify to recreate the heap\n * with rest of the array element. Repeat this process\n * \n * Time complexity\n * O(nlogn)\n * \n * Test cases\n * Null array\n * 1 element array\n * 2 element array\n * sorted array\n * reverse sorted array\n */\npublic class HeapSort {\n\n    public void sort(int arr[]){\n        for(int i=1; i < arr.length; i++){\n            heapAdd(arr, i);\n        }\n        \n        for(int i = arr.length-1; i > 0 ; i--){\n            swap(arr, 0, i);\n            heapify(arr, i-1);\n        }\n    }\n    \n    private void heapify(int arr[], int end){\n        int i = 0;\n        int leftIndex;\n        int rightIndex;\n        while(i <= end){\n            leftIndex = 2*i + 1;\n            if(leftIndex > end){\n                break;\n            }\n            rightIndex = 2*i + 2;\n            if(rightIndex > end){\n                rightIndex = leftIndex;\n            }\n            if(arr[i]  >= Math.max(arr[leftIndex], arr[rightIndex])){\n                break;\n            }\n            if(arr[leftIndex] >= arr[rightIndex]){\n                swap(arr, i, leftIndex);\n                i = leftIndex;\n            }else{\n                swap(arr, i, rightIndex);\n                i = rightIndex;\n            }\n        }\n    }\n    \n    private void swap(int arr[], int x, int y){\n        int temp = arr[x];\n        arr[x] = arr[y];\n        arr[y] = temp;\n    }\n    \n    private void heapAdd(int arr[], int end){\n        int i = end;\n        while(i > 0){\n            if(arr[i] > arr[(i-1)/2]){\n                swap(arr, i, (i-1)/2);\n                i = (i - 1)/2;\n            }else{\n                break;\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        HeapSort hs = new HeapSort();\n        int arr[] = {-1,5,8,2,-6,-8,11,5};\n        hs.sort(arr);\n        for(int a : arr){\n            System.out.println(a);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/sort/IterativeQuickSort.java",
    "content": "package com.interview.sort;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * http://www.geeksforgeeks.org/iterative-quick-sort/\n * Test case\n * 0,1 or more elements in the array\n */\npublic class IterativeQuickSort {\n\n    public void sort(int arr[]){\n        Deque<Integer> stack = new LinkedList<Integer>();\n        int l = 0;\n        int h = arr.length-1;\n        stack.offerFirst(l);\n        stack.offerFirst(h);\n        \n        while(!stack.isEmpty()){\n            h = stack.pollFirst();\n            l = stack.pollFirst();\n            \n            int p = partition(arr,l,h);\n            if(l < p-1 && h > p+1){\n                stack.offerFirst(l);\n                stack.offerFirst(p-1);\n                stack.offerFirst(p+1);\n                stack.offerFirst(h);\n            }\n            else if(l < p-1){\n                stack.offerFirst(l);\n                stack.offerFirst(p-1);\n            }else if(h > p+1){\n                stack.offerFirst(p+1);\n                stack.offerFirst(h);\n            }\n        }\n    }\n    \n    private int partition(int arr[], int low,int high){\n        int pivot = arr[low];\n        int i = low+1;\n        int j = low+1;\n        while(j <= high){\n            if(arr[j] < pivot){\n                swap(arr,i,j);\n                i++;\n            }\n            j++;\n        }\n        swap(arr,i-1,low);\n        return i-1;\n        \n    }\n    \n    private void swap(int arr[],int a,int b){\n        int temp = arr[a];\n        arr[a] = arr[b];\n        arr[b] = temp;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {3,2,8,0,11,-1,-5,4,32,-60,44};\n        IterativeQuickSort iqs = new IterativeQuickSort();\n        iqs.sort(arr);\n        for(int i=0; i < arr.length; i++){\n            System.out.print(arr[i] + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/sort/MergeSort.java",
    "content": "package com.interview.sort;\n\n/**\n * http://en.wikipedia.org/wiki/Merge_sort\n * Test cases\n * 1 element\n * 2 element\n * negative numbers\n * already sorted\n * reverse sorted\n */\npublic class MergeSort {\n\n    public void sort(int input[]){\n        sort(input, 0, input.length-1);\n    }\n    \n    private void sort(int input[], int low, int high){\n        if(low >= high){\n            return;\n        }\n        \n        int middle = (low + high)/2;\n        sort(input, low, middle);\n        sort(input, middle+1, high);\n        sortedMerge(input,low,high);\n   }\n    \n    private void sortedMerge(int input[], int low, int high){\n        int middle = (low+high)/2;\n        int temp[] = new int[high-low+1];\n        int i = low;\n        int j = middle+1;\n        int r = 0;\n        while(i <= middle && j <= high){\n            if(input[i] <= input[j]){\n                temp[r++] = input[i++];\n            }else{\n                temp[r++] = input[j++];\n            }\n        }\n        while(i <= middle){\n            temp[r++] = input[i++];\n        }\n        \n        while(j <= high){\n            temp[r++] = input[j++];\n        }\n        i = low;\n        for(int k=0; k < temp.length;){\n            input[i++] = temp[k++];\n        }\n    }\n    \n    public void printArray(int input[]){\n        for(int i : input){\n            System.out.print(i + \" \");\n        }\n        System.out.println();\n    }\n    \n    public static void main(String args[]){\n        int input1[] = {1};\n        int input2[] = {4,2};\n        int input3[] = {6,2,9};\n        int input4[] = {6,-1,10,4,11,14,19,12,18};\n        MergeSort ms = new MergeSort();\n        ms.sort(input1);\n        ms.sort(input2);\n        ms.sort(input3);\n        ms.sort(input4);\n        \n        ms.printArray(input1);\n        ms.printArray(input2);\n        ms.printArray(input3);\n        ms.printArray(input4);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/sort/PanCakeSorting.java",
    "content": "package com.interview.sort;\n\n/**\n * http://www.geeksforgeeks.org/pancake-sorting/\n * Two ways to do it\n * 1) Start i from arr.length-1 towards 0, find max from 0 to i, move this max to top\n * by one flip and then move this max to ith position by another flip\n * \n * 2) Start i from 0 towards arr.length-1, find floor of input[i] from 0 to i-1 lets call\n * f , flip 0 to f, then flip 0 to i-1 then flip 0 to i, then flip 0 to i-1.\n * e.g 1 2 3 5 4. Here i is 4 and f is 2\n * 1 2 3 5 4 flip(0,f) -> 3 2 1 5 4\n * 3 2 1 5 4 flip(0,i-1) -> 5 1 2 3 4\n * 5 1 2 3 4 flip(0,i) -> 4 3 2 1 5\n * 4 3 2 1 5 flip(0,i-1) -> 1 2 3 4 5\n */\npublic class PanCakeSorting {\n\n    public void sort(int arr[]){\n        for(int i=arr.length-1; i >= 0 ; i--){\n            int pos = findMax(arr,i);\n            flip(arr,pos);\n            flip(arr,i);\n        }\n    }\n    \n    private int findMax(int arr[],int pos){\n        int max = pos;\n        for(int i= pos-1 ;i >= 0 ;i--){\n            if(arr[i] > arr[max]){\n                max = i;\n            }\n        }\n        return max;\n    }\n    \n    private void flip(int arr[],int pos){\n        for(int i=0; i <= pos/2; i++){\n            swap(arr,i,pos-i);\n        }\n    }\n    \n    private void swap(int arr[],int i,int j){\n        int temp = arr[i];\n        arr[i] = arr[j];\n        arr[j] = temp;\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {9,2,7,11,3,6,1,10,8};\n        PanCakeSorting pcs = new PanCakeSorting();\n        pcs.sort(arr);\n        for(int i=0; i < arr.length; i++){\n            System.out.print(arr[i] + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/sort/QuickSort.java",
    "content": "package com.interview.sort;\n\npublic class QuickSort {\n\n    private void swap(int A[],int i,int j)\n    {\n        int temp = A[i];\n        A[i] = A[j];\n        A[j] = temp;\n    }\n    private int split(int A[],int low,int high)\n    {\n        int pivot = low;\n        int i = low +1;\n        int j = high;\n        while(i<j)\n        {\n            while(i<=j && A[pivot]>=A[i])\n            {\n                i++;\n            }\n            while(j>=i && A[pivot]<A[j])\n            {\n                j--;\n            }\n            if(i < j && A[i]>A[j])\n            {\n                swap(A,i++,j--);\n            }\n        }\n        if(A[pivot] > A[j]){\n            swap(A,j,pivot);\n        }\n        return j;\n    }\n\n    private int split1(int A[],int low,int high){\n        \n        int pivot = low;\n        int i = low+1;\n        int j = high;\n        while(i <= j){\n            \n            if(A[i] <= A[pivot]){\n                i++;\n                continue;\n            }\n            if(A[j] > A[pivot]){\n                j--;\n                continue;\n            }\n            swap(A,i++,j--);\n        }\n        if(A[pivot] > A[j]){\n            swap(A,pivot,j);\n            return j;\n        }\n        return pivot;\n        \n    }\n\n    public void sort(int A[],int low,int high)\n    {\n        if(low>=high)\n        {\n            return;\n        }\n        int pos = split1(A,low,high);\n        sort(A,low,pos-1);\n        sort(A,pos+1,high);\n    }   \n    \n    private void printArray(int arr[]){\n        for(int a : arr){\n            System.out.println(a);\n        }\n    }\n    public static void main(String args[]){\n        QuickSort qs = new QuickSort();\n        int A[] = {11,19,0,-1,5,6,16,-3,6,0,14,18,7,21,18,-6,-8};\n//      int A[] = {11,9,0,4,6,-1,13};\n        qs.sort(A, 0, A.length-1);\n        qs.printArray(A);\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/sort/RadixSort.java",
    "content": "package com.interview.sort;\n\npublic class RadixSort {\n\n    private void countSort(int arr[],int exp){\n        \n        int[] count = new int[10];\n        int[] output = new int[arr.length];\n        \n        for(int i=0; i < arr.length; i++){\n            count[(arr[i]/exp)%10]++;\n        }\n        \n        for(int i=1; i < count.length; i++){\n            count[i] += count[i-1];\n        }\n        \n        for(int i=arr.length-1; i >= 0; i--){\n            output[count[(arr[i]/exp)%10]-1] = arr[i];\n            count[(arr[i]/exp)%10]--;\n        }\n        \n        for(int i=0; i < arr.length; i++){\n            arr[i] = output[i];\n        }\n    }\n    \n    private int max(int arr[]){\n        int max = arr[0];\n        for(int i=1; i < arr.length; i++){\n            if(max < arr[i]){\n                max = arr[i];\n            }\n        }\n        return max;\n    }\n    \n    public void radixSort(int arr[]){\n        \n        int max = max(arr);\n        for(int exp = 1; exp <= max; exp *= 10){\n            countSort(arr,exp);\n        }\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {101,10,11,66,94,26,125};\n        RadixSort rs = new RadixSort();\n        rs.radixSort(arr);\n        for (int i = 0; i < arr.length; i++) {\n            System.out.println(arr[i]);\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/sort/Sort0toN3.java",
    "content": "package com.interview.sort;\n\n/**\n * http://www.geeksforgeeks.org/sort-n-numbers-range-0-n2-1-linear-time/\n */\npublic class Sort0toN3 {\n\n    public void sort(int arr[],int n){\n        \n        sort(arr,n,1);\n        sort(arr,n,n);\n        sort(arr,n,n*n);\n    }\n    \n    private void sort(int arr[],int n, int exp){\n        int count[] = new int[n];\n        for(int i=0; i < arr.length;i++){\n            count[(arr[i]/exp)%n]++;\n        }\n        \n        for(int i=1; i < arr.length; i++){\n            count[i] += count[i-1];\n        }\n    \n        int output[] = new int[n];\n        \n        for(int i=arr.length-1;i>=0; i--){\n            output[count[(arr[i]/exp)%n]-1] = arr[i];\n            count[(arr[i]/exp)%n]--;\n        }\n        for(int i=0; i < arr.length; i++){\n            arr[i] = output[i];\n        }\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {100,2,124,18,36};\n        Sort0toN3 sn = new Sort0toN3();\n        sn.sort(arr,arr.length);\n        for(int i=0; i < arr.length; i++){\n            System.out.print(arr[i] + \" \");\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/sort/SortArrayByFrequence.java",
    "content": "package com.interview.sort;\n\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * http://www.geeksforgeeks.org/sort-elements-by-frequency/\n */\npublic class SortArrayByFrequence {\n\n    class SortNode{\n        int count;\n        int firstIndex;\n    }\n    \n    class FrequenceComparator implements Comparator<Integer>{\n        private Map<Integer,SortNode> countMap = null;\n        FrequenceComparator(Map<Integer,SortNode> countMap){\n            this.countMap = countMap;\n        }\n        @Override\n        public int compare(Integer i1, Integer i2) {\n            SortNode n1 = countMap.get(i1);\n            SortNode n2 = countMap.get(i2);\n            if(n1.count > n2.count){\n                return -1;\n            }else if(n1.count < n2.count){\n                return 1;\n            }else{\n                return n1.firstIndex < n2.firstIndex ? -1 : 1;\n            }\n        }\n        \n    }\n    \n    public void sortByFrequence(Integer arr[]){\n        Map<Integer,SortNode> countMap = new HashMap<Integer,SortNode>();\n        int index = 0;\n        for(int a : arr){\n            if(countMap.containsKey(a)){\n                SortNode s = countMap.get(a);\n                s.count++;\n            }else{\n                SortNode s = new SortNode();\n                s.count = 1;\n                s.firstIndex = index;\n                countMap.put(a, s);\n            }\n            index++;\n        }\n        \n        FrequenceComparator freqComparator = new FrequenceComparator(countMap);\n        Arrays.sort(arr,freqComparator);\n    }\n    \n    public static void main(String args[]){\n        Integer input[] = {5,2,8,9,9,9,2};\n        SortArrayByFrequence saf = new SortArrayByFrequence();\n        saf.sortByFrequence(input);\n        for(int i : input){\n            System.out.println(i + \" \");\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/CircularQueue.java",
    "content": "package com.interview.stackqueue;\n\npublic class CircularQueue<T> {\n\n    private int QUEUE_LENGTH;\n    private T data[] = null;\n    public CircularQueue(int size){\n        this.QUEUE_LENGTH = size;\n        data = (T [])new Object[QUEUE_LENGTH];\n    }\n    private int top=-1;\n    private int end = -1;\n    public void offer(T t){\n        if(top == -1){\n            data[0] = t;\n            top =0;\n            end = 0;\n        }else if(top == (end + 1) % QUEUE_LENGTH){\n            throw new IllegalArgumentException();\n        }else{\n            end = (end + 1) % QUEUE_LENGTH;\n            data[end] = t;\n        }\n    }\n    \n    public T top(){\n        if(top == -1){\n            throw new IllegalArgumentException();\n        }else{\n            return data[top];\n        }\n    }\n    \n    public T poll(){\n        if(top == -1){\n            throw new IllegalArgumentException();\n        }else if(top == end){\n            T t =  data[top];\n            top = -1;\n            end = -1;\n            return t;\n        }\n        else{\n            T t =  data[top];\n            top = (top +1)% QUEUE_LENGTH;\n            return t;\n        }\n        \n    }\n    public boolean isEmpty(){\n        if(top == -1){\n            return true;\n        }\n        return false;\n    }\n    \n    public boolean isFull(){\n        if(top == (end + 1)% QUEUE_LENGTH){\n            return true;\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        CircularQueue<Integer> circularQueue = new CircularQueue<Integer>(5);\n        circularQueue.offer(1);\n        circularQueue.offer(2);\n        circularQueue.offer(3);\n        System.out.println(circularQueue.poll());\n        circularQueue.offer(4);\n        circularQueue.offer(5);\n        System.out.print(circularQueue.isFull());\n        circularQueue.offer(6);\n        System.out.print(circularQueue.isFull());\n    \n        while(!circularQueue.isEmpty()){\n            System.out.println(circularQueue.poll());\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/MaximumHistogram.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * 12/23/2014\n * @author tusroy\n * \n * Video link https://youtu.be/ZmnqCZp9bBs\n * \n * Given an array representing height of bar in bar graph, find max histogram\n * area in the bar graph. Max histogram will be max rectangular area in the\n * graph.\n * \n * Maintain a stack\n * \n * If stack is empty or value at index of stack is less than or equal to value at current \n * index, push this into stack.\n * Otherwise keep removing values from stack till value at index at top of stack is \n * less than value at current index.\n * While removing value from stack calculate area\n * if stack is empty \n * it means that till this point value just removed has to be smallest element\n * so area = input[top] * i\n * if stack is not empty then this value at index top is less than or equal to \n * everything from stack top + 1 till i. So area will\n * area = input[top] * (i - stack.peek() - 1);\n * Finally maxArea is area if area is greater than maxArea.\n * \n * \n * Time complexity is O(n)\n * Space complexity is O(n)\n * \n * References:\n * http://www.geeksforgeeks.org/largest-rectangle-under-histogram/\n */\npublic class MaximumHistogram {\n\n    public int maxHistogram(int input[]){\n        Deque<Integer> stack = new LinkedList<Integer>();\n        int maxArea = 0;\n        int area = 0;\n        int i;\n        for(i=0; i < input.length;){\n            if(stack.isEmpty() || input[stack.peekFirst()] <= input[i]){\n                stack.offerFirst(i++);\n            }else{\n                int top = stack.pollFirst();\n                //if stack is empty means everything till i has to be\n                //greater or equal to input[top] so get area by\n                //input[top] * i;\n                if(stack.isEmpty()){\n                    area = input[top] * i;\n                }\n                //if stack is not empty then everythin from i-1 to input.peek() + 1\n                //has to be greater or equal to input[top]\n                //so area = input[top]*(i - stack.peek() - 1);\n                else{\n                    area = input[top] * (i - stack.peekFirst() - 1);\n                }\n                if(area > maxArea){\n                    maxArea = area;\n                }\n            }\n        }\n        while(!stack.isEmpty()){\n            int top = stack.pollFirst();\n            //if stack is empty means everything till i has to be\n            //greater or equal to input[top] so get area by\n            //input[top] * i;\n            if(stack.isEmpty()){\n                area = input[top] * i;\n            }\n            //if stack is not empty then everything from i-1 to input.peek() + 1\n            //has to be greater or equal to input[top]\n            //so area = input[top]*(i - stack.peek() - 1);\n            else{\n                area = input[top] * (i - stack.peekFirst() - 1);\n            }\n        if(area > maxArea){\n                maxArea = area;\n            }\n        }\n        return maxArea;\n    }\n    \n    public static void main(String args[]){\n        MaximumHistogram mh = new MaximumHistogram();\n        int input[] = {2,2,2,6,1,5,4,2,2,2,2};\n        int maxArea = mh.maxHistogram(input);\n        //System.out.println(maxArea);\n        assert maxArea == 12;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/MedianFinder.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.Collections;\nimport java.util.PriorityQueue;\n\n/**\n * Date 03/03/2016\n * @author Tushar Roy\n *\n * Find median in stream of numbers\n * \n * https://leetcode.com/problems/find-median-from-data-stream/\n */\npublic class MedianFinder {\n\n    PriorityQueue<Integer> minPq = new PriorityQueue<>();\n    PriorityQueue<Integer> maxPq = new PriorityQueue<>();\n\n    public MedianFinder() {\n        minPq = new PriorityQueue<>();\n        maxPq = new PriorityQueue<>(20, Collections.reverseOrder());\n    }\n\n    // Adds a number into the data structure.\n    public void addNum(int num) {\n        if (maxPq.size() == 0) {\n            maxPq.add(num);\n            return;\n        }\n        if (maxPq.size() == minPq.size()) {\n            if (minPq.peek() < num) {\n                maxPq.offer(minPq.poll());\n                minPq.offer(num);\n            } else {\n                maxPq.offer(num);\n            }\n        } else {\n            int toBeOffered = 0;\n            if (num >= maxPq.peek()) {\n                toBeOffered = num;\n            } else {\n                toBeOffered = maxPq.poll();\n                maxPq.offer(num);\n            }\n            minPq.offer(toBeOffered);\n        }\n    }\n    // Returns the median of current data stream\n    public double findMedian() {\n        if (minPq.size() == maxPq.size()) {\n            return ((double)minPq.peek() + (double)maxPq.peek())/2;\n        } else {\n            return maxPq.peek();\n        }\n    }\n\n    public static void main(String args[]) {\n        MedianFinder mf = new MedianFinder();\n        mf.addNum(4);\n        System.out.println(mf.findMedian());\n        mf.addNum(8);\n        System.out.println(mf.findMedian());\n        mf.addNum(2);\n        System.out.println(mf.findMedian());\n        mf.addNum(11);\n        System.out.println(mf.findMedian());\n        mf.addNum(13);\n        System.out.println(mf.findMedian());\n        mf.addNum(14);\n        System.out.println(mf.findMedian());\n        mf.addNum(-1);\n        System.out.println(mf.findMedian());\n\n    }\n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/RealTimeCounter.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\n\npublic class RealTimeCounter {\n\n    private Queue<Long> secQueue = new LinkedList<Long>();\n    private long secCount;\n    \n    public void add(long currentTimeInMills){\n        while(secQueue.size() > 0 && currentTimeInMills - 1000 > secQueue.peek()){\n            secCount--;\n            secQueue.poll();\n        }\n        \n        secCount++;\n        secQueue.offer(currentTimeInMills);\n    }\n    \n    public long getCallsInLastSec(long currentTimeInMills){\n        while(secQueue.size() > 0 && currentTimeInMills - 1000 > secQueue.peek()){\n            secCount--;\n            secQueue.poll();\n        }\n        return secCount;\n    }\n    \n    public static void main(String args[]){\n        RealTimeCounter rtc = new RealTimeCounter();\n        rtc.add(100);\n        rtc.add(300);\n        rtc.add(550);\n        System.out.println(rtc.getCallsInLastSec(780));\n        System.out.println(rtc.getCallsInLastSec(1280));\n        rtc.add(1540);\n        System.out.println(rtc.getCallsInLastSec(1551));\n        rtc.add(1570);\n        System.out.println(rtc.getCallsInLastSec(2651));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/RealTimeCounterUsingCircularQueue.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\npublic class RealTimeCounterUsingCircularQueue {\n\n    class Node {\n        long time;\n        int count;\n    }\n\n    private static int MAX_SIZE = 0;\n    private static int BOUND = 100;\n    private static int MAX_BOUND = 1000;\n    int count = 0;\n    private int currentSize = 0;\n\n    Deque<Node> queue = new LinkedList<Node>();\n\n    public void add(long time) {\n        Node last = queue.peekLast();\n        if(last != null){\n            if (time - last.time < BOUND) {\n                last.count++;\n                count++;\n                return;\n            } else if (time - last.time > MAX_BOUND) {\n                queue.clear();\n                Node n = new Node();\n                n.time = time/BOUND * BOUND;\n                n.count = 1;\n                queue.add(n);\n                count++;\n                return;\n            }\n        }\n        while(queue.size() > 0){\n            Node t1 = queue.peekFirst();\n            if(time - t1.time > MAX_BOUND){\n                count = count - t1.count;\n                queue.pollFirst();\n            }else{\n                break;\n            }\n        }\n    \n        Node n = new Node();\n        n.time = time/BOUND * BOUND;\n        n.count = 1;\n        queue.add(n);\n        count++;\n    }\n\n    public int getCount(int time){\n        while(queue.size() > 0){\n            Node t1 = queue.peekFirst();\n            if(time - t1.time > MAX_BOUND){\n                count = count - t1.count;\n                queue.pollFirst();\n            }else{\n                break;\n            }\n        }\n        return count;\n    }\n    \n    public static void main(String args[]){\n        RealTimeCounterUsingCircularQueue src = new RealTimeCounterUsingCircularQueue();\n        src.add(10);\n        src.add(70);\n        src.add(80);\n        src.add(120);\n        src.add(150);\n        src.add(450);\n        src.add(750);\n        src.add(799);\n        src.add(1001);\n        src.add(1010);\n        src.add(1210);\n        System.out.print(src.getCount(1515));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/RemoveDuplicateMaintainingOrder.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.*;\n\n/**\n * Date 02/29/2016\n * @author Tushar Roy\n *\n * Given a string remove duplicates from the string maintaining order\n * and getting lexicographically smallest string.\n *\n * Reference:\n * https://leetcode.com/problems/remove-duplicate-letters/\n */\npublic class RemoveDuplicateMaintainingOrder {\n    public String removeDuplicateLetters(String s) {\n        Deque<Character> stack = new LinkedList<>();\n        Map<Character, Integer> count = new HashMap<>();\n        for (int i = 0; i < s.length(); i++) {\n            count.compute(s.charAt(i), (key, val) -> {\n                if (val == null) {\n                    return 1;\n                } else {\n                    return val + 1;\n                }\n            });\n        }\n\n        Set<Character> visited = new HashSet<>();\n        for (int i = 0; i < s.length(); i++) {\n            char ch = s.charAt(i);\n            count.put(ch, count.get(ch) - 1);\n            if (visited.contains(ch)) {\n                continue;\n            }\n            while (!stack.isEmpty() && stack.peekFirst() > ch && count.get(stack.peekFirst()) > 0) {\n                visited.remove(stack.peekFirst());\n                stack.pollFirst();\n            }\n\n            stack.offerFirst(ch);\n            visited.add(ch);\n        }\n\n        StringBuffer buff = new StringBuffer();\n        while (!stack.isEmpty()) {\n            buff.append(stack.pollLast());\n        }\n        return buff.toString();\n    }\n\n    public static void main(String args[]) {\n        RemoveDuplicateMaintainingOrder rm = new RemoveDuplicateMaintainingOrder();\n        System.out.println(rm.removeDuplicateLetters(\"cbacdcbc\"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/RemoveExtraBrackets.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * Date 03/17/2015\n * @author tusroy\n * \n * Given a string with unbalanced brackets how do you remove minimum number\n * of extra brackets so that you are left with balanced brackets in the string\n * \n * e.g )( -> empty string\n *     (a) -> (a)\n *     ((mnq)abc))) -> ((mna)abc)\n *     (abc)(( -> (abc)\n * \n * Solution 1\n * Keep a stack. When non bracket character shows up just skip it.\n * When an opening bracket shows up just add it.\n * When closing bracket shows up, see if top of stack is opening bracket. If yes\n * then just remove that from stack else add closing bracket into the stack.\n * \n * Solution 2\n * This can be done without stack as well. Keep count of open and close brackets.\n * Any time closeBracket gets more than openBracket do not put it in result.\n * After we are done iterating input again if openBracket is more than closeBracket\n * get rid of last (openBracket-closeBracket) open brackets.\n * \n * Test cases:\n * empty string\n * String with )(\n * String with all opening brackets\n * String with all closing brackets\n * String with mix of open close brackets and characters between them\n * String with already balanced parenthesis\n *\n */\npublic class RemoveExtraBrackets {\n\n    public int remove(char input[]){\n        if(input == null){\n            return 0;\n        }\n        Deque<Integer> dq = new LinkedList<Integer>();\n        for(int i=0; i < input.length; i++){\n            //skip non bracket characters\n            if(input[i] != '(' && input[i] != ')'){\n                continue;\n            }\n            \n            //add opening brackets\n            if(input[i] == '('){\n                dq.addFirst(i);\n            }\n            else if(input[i] == ')'){\n                //if top is opening bracket just remove from stack else add closing bracket\n                if(!dq.isEmpty() && input[dq.peekFirst()] == '('){\n                    dq.pollFirst();\n                }else{\n                    dq.addFirst(i);\n                }\n            }\n        }\n        int index = 0;\n        //iterate through list again and don't add leftover\n        //characters from stack in final result\n        for(int i=0; i < input.length; i++){\n            if(!dq.isEmpty() && i == dq.peekLast()) {\n                dq.pollLast();\n            }else {\n                input[index++] = input[i];\n            }\n        }\n        return index;\n    }\n    \n    /**\n     * This method does not uses stack and does inplace conversion\n     */\n    public int removeWithoutExtraSpace(char input[]){\n        int openBrackets = 0;\n        int closeBrackets = 0;\n        \n        int index = 0;\n        for(int i=0; i < input.length; i++){\n            if(input[i] != '(' && input[i] != ')'){\n                input[index++] = input[i]; \n                continue;\n            }\n            if(input[i] == '('){\n                openBrackets++;\n                input[index++] = input[i];\n            }else {\n                //add close bracket to input only if it is \n                //less than open bracket count.\n                if(closeBrackets < openBrackets){\n                    input[index++] = input[i];\n                    closeBrackets++;\n                }\n            }\n        }\n        \n        //iterate through result get rid of extra open brackets if any towards\n        //the end\n        if(openBrackets > closeBrackets){\n            int newIndex = 0;\n            int seenOpenBracket = 0;\n            for(int i=0; i < index; i++){\n                if(input[i] == '('){\n                    seenOpenBracket++;\n                }\n                if(input[i] != '(' || seenOpenBracket <= closeBrackets){\n                    input[newIndex++] = input[i];\n                }\n            }\n            index = newIndex;\n        }\n        return index;\n    }\n    \n    public static void printArray(char input[], int size) {\n        for(int i=0; i < size; i++){\n            System.out.print(input[i] + \" \");\n        }\n        System.out.println();\n    }\n    \n    public static void main(String args[]){\n        RemoveExtraBrackets reb = new RemoveExtraBrackets();\n        char input1[] = \")(\".toCharArray();\n        int pos = reb.remove(input1);\n        printArray(input1, pos);\n      \n        char input1_1[] = \")(\".toCharArray();\n        pos = reb.removeWithoutExtraSpace(input1_1);\n        printArray(input1_1, pos);\n      \n        char input2[] = \"(((abc)(lm)(()\".toCharArray();\n        pos = reb.remove(input2);\n        printArray(input2, pos);\n \n        char input2_1[] = \"(((abc)(lm)(()\".toCharArray();\n        pos = reb.removeWithoutExtraSpace(input2_1);\n        printArray(input2_1, pos);\n \n        char input3[] = \"(((c)(l))))(()))\".toCharArray();\n        pos = reb.remove(input3);\n        printArray(input3, pos);\n \n        char input3_1[] = \"(((c)(l))))(()))\".toCharArray();\n        pos = reb.removeWithoutExtraSpace(input3_1);\n        printArray(input3_1, pos);\n \n        char input4[] = \"((((\".toCharArray();\n        pos = reb.remove(input4);\n        printArray(input4, pos);\n \n        char input4_1[] = \"((((\".toCharArray();\n        pos = reb.removeWithoutExtraSpace(input4_1);\n        printArray(input4_1, pos);\n \n        char input5[] = \"))))\".toCharArray();\n        pos = reb.remove(input5);\n        printArray(input5, pos);\n \n        char input5_1[] = \"))))\".toCharArray();\n        pos = reb.removeWithoutExtraSpace(input5_1);\n        printArray(input5_1, pos);\n\n        char input6[] = \"((Test))(Great)\".toCharArray();\n        pos = reb.remove(input6);\n        printArray(input6, pos);\n \n        char input6_1[] = \"((Test))(Great)\".toCharArray();\n        pos = reb.removeWithoutExtraSpace(input6_1);\n        printArray(input6_1, pos);\n \n    }\n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/ReverseStackUsingRecursion.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.Deque;\nimport java.util.Iterator;\nimport java.util.LinkedList;\n\n/**\n * http://www.geeksforgeeks.org/reverse-a-stack-using-recursion/\n */\npublic class ReverseStackUsingRecursion {\n\n    public void reverse(Deque<Integer> stack){\n        if(stack.size() == 0){\n            return;\n        }\n        int temp = stack.pollFirst();\n        reverse(stack);\n        \n        pushAtBottom(stack,temp);\n    }\n    \n    private void pushAtBottom(Deque<Integer> stack,int data){\n        if(stack.size() == 0){\n            stack.offerFirst(data);\n            return;\n        }\n        int temp = stack.pollFirst();\n        pushAtBottom(stack, data);\n        stack.offerFirst(temp);\n    }\n    \n    public static void main(String args[]){\n        Deque<Integer> stack = new LinkedList<Integer>();\n        stack.push(1);\n        stack.push(2);\n        stack.push(3);\n        stack.push(4);\n        stack.push(5);\n        stack.push(6);\n        \n        Iterator<Integer> itr =  stack.iterator();\n        while(itr.hasNext()){\n            System.out.println(itr.next());\n        }\n        \n        ReverseStackUsingRecursion rsu = new ReverseStackUsingRecursion();\n        rsu.reverse(stack);\n        \n        itr =  stack.iterator();\n        while(itr.hasNext()){\n            System.out.println(itr.next());\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/SimplyPath.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\nimport java.util.StringTokenizer;\n\n/**\n * Date 04/18/2016\n * @author Tushar Roy\n *\n * Given an absolute path for a file (Unix-style), simplify it.\n * For example,\n * path = \"/home/\", => \"/home\"\n * path = \"/a/./b/../../c/\", => \"/c\"\n *\n * Space complexity O(n)\n * Time complexity O(n)\n *\n * https://leetcode.com/problems/simplify-path/\n */\npublic class SimplyPath {\n\n    public String simplifyPath(String path) {\n        Deque<String> stack = new LinkedList<>();\n        StringTokenizer token = new StringTokenizer(path, \"/\");\n        while (token.hasMoreTokens()) {\n            String tok = token.nextToken();\n            if (tok.equals(\".\")) {\n                continue;\n            } else if (tok.equals(\"..\")) {\n                stack.pollFirst();\n            } else {\n                stack.offerFirst(tok);\n            }\n        }\n        StringBuffer buff = new StringBuffer();\n        if (stack.isEmpty()) {\n            buff.append(\"/\");\n        }\n        while(!stack.isEmpty()) {\n            buff.append(\"/\").append(stack.pollLast());\n        }\n        return buff.toString();\n    }\n    \n    public static void main(String args[]){\n        String absCurrentFolder = \"/home/tusroy\";\n        SimplyPath mfc = new SimplyPath();\n        System.out.println(mfc.simplifyPath(absCurrentFolder));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/stackqueue/StockSpanProblem.java",
    "content": "package com.interview.stackqueue;\n\nimport java.util.ArrayDeque;\nimport java.util.Arrays;\nimport java.util.Deque;\n\n/**\n * Created by saitejatokala on 21/11/15.\n * http://www.geeksforgeeks.org/the-stock-span-problem/\n * Question:\n * The stock span problem is a financial problem where we have a series of n daily price quotes for a stock and we need to calculate span of stock’s price for all n days.\n * The span Si of the stock’s price on a given day i is defined as the maximum number of consecutive days just before the given day, for which the price of the stock on the current day is less than or equal to its price on the given day.\n * For example, if an array of 7 days prices is given as {100, 80, 60, 70, 60, 75, 85}, then the span values for corresponding 7 days are {1, 1, 1, 2, 1, 4, 6}\n *\n * Solution 1:\n * We see that S[i] on day i can be easily computed if we know the closest day preceding i, such that the price is greater than on that day than the price on day i. If such a day exists, let’s call it h(i), otherwise, we define h(i) = -1.\n * The span is now computed as S[i] = i – h(i). See the following diagram.\n */\npublic class StockSpanProblem {\n    public static int[] stockSpan(int[] prices){\n        Deque<Integer> stack = new ArrayDeque<>();\n        int[] stockSpan = new int[prices.length];\n        stockSpan[0] = 1;\n        stack.offerFirst(0);\n        for (int i = 1; i < prices.length ; i++) {\n            while (!stack.isEmpty() && prices[stack.peekFirst()] < prices[i]) {\n                stack.pollFirst();\n            }\n            if (stack.isEmpty()) {\n                stockSpan[i] = i + 1;\n            } else {\n                stockSpan[i] = i - stack.peekFirst();\n            }\n            stack.offerFirst(i);\n        }\n        return stockSpan;\n    }\n\n    public static void main(String[] args) {\n        int[] prices = {100, 80, 60, 70, 60, 75, 85};\n        int[] result = stockSpan(prices);\n        System.out.print(Arrays.toString(result));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/AnagramOfFirstAsSubstring.java",
    "content": "package com.interview.string;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * http://www.careercup.com/question?id=5389078581215232\n * Given two strings tells if anagram of first is substring of another\n * Keep map of characters in array1 and keep checking if array2 has these characters.\n * main string : a b a c a b b and looking for a a b b c when 3rd a is encountered\n * we move index to second a and start from there.\n * \n * Another idea is to keep a sorted linklist of string in comparison. Whenever a new character\n * is to be added remove last character from linklist and add this new one.\n */\npublic class AnagramOfFirstAsSubstring {\n\n    public boolean isSubString(char str1[], char str2[]) {\n        int index = 0;\n        int curLen = 0;\n        Map<Character, Integer> count = new HashMap<Character, Integer>();\n        for (int i = 0; i < str1.length; i++) {\n            incrementCount(str1[i], count);\n        }\n        Map<Character, Integer> currentCount = new HashMap<Character, Integer>();\n        Map<Character, Integer> pos = new HashMap<Character, Integer>();\n        while (index < str2.length) {\n            if (containsAndUpdate(currentCount, count, str2[index], pos, index)) {\n                index++;\n                curLen++;\n            } else {\n                Integer p = pos.get(str2[index]);\n                if (p != null) {\n                    curLen = index - p;\n                    index = p;\n                } else {\n                    index++;\n                }\n                currentCount.clear();\n                pos.clear();\n            }\n            if (curLen == str1.length) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private boolean containsAndUpdate(Map<Character, Integer> currentCount,\n            Map<Character, Integer> count, Character ch,\n            Map<Character, Integer> pos, int index) {\n        if (count.containsKey(ch)) {\n            if(currentCount.containsKey(ch)) {\n                if (currentCount.get(ch) < count.get(ch)) {\n                    if (currentCount.get(ch) == 1) {\n                        pos.put(ch, index);\n                    }\n                    currentCount.put(ch, currentCount.get(ch) + 1);\n                    return true;\n                }\n            }else{\n                currentCount.put(ch, 1);\n                pos.put(ch,index);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private void incrementCount(Character ch, Map<Character, Integer> count) {\n        if (count.containsKey(ch)) {\n            int c = count.get(ch);\n            count.put(ch, c + 1);\n        } else {\n            count.put(ch, 1);\n        }\n    }\n    \n    public static void main(String args[]){\n        char str1[] = \"aaabccde\".toCharArray();\n        char str2[] = \"tbcdaacaaecbd\".toCharArray();\n        AnagramOfFirstAsSubstring ana = new AnagramOfFirstAsSubstring();\n        System.out.println(ana.isSubString(str1, str2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/CycleLeaderIteration.java",
    "content": "package com.interview.string;\n\npublic class CycleLeaderIteration {\n\n    //assumption that size is going to be 3^k +1 from start to end\n    public void iterate(char str[],int start,int end){\n        int len = end - start +1;\n        int power = 1;\n        while(power < len){\n            int index = power;\n            int newIndex = -1;\n            char temp = str[start+index];\n            char temp1;\n            while(newIndex != power){\n                if(index % 2 ==0){\n                    newIndex = index/2;\n                }else{\n                    newIndex = len/2 + index/2;\n                }\n                temp1 = str[start + newIndex];\n                str[start+newIndex] = temp;\n                temp = temp1;\n                index = newIndex;\n            }\n            power = power*3;        \n        }\n    }\n    \n    public static void main(String args[]){\n        String str = \"1a2b3c4d5e6f7g8h9iAjBkClDmEn\";\n        char[] str1 = str.toCharArray();\n        CycleLeaderIteration cli = new CycleLeaderIteration();\n        cli.iterate(str1, 0, str1.length);\n        for(char ch: str1){\n            System.out.print(ch + \" \");\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/string/GroupAnagramsTogether.java",
    "content": "package com.interview.string;\n\nimport java.util.*;\n\n/**\n * https://leetcode.com/problems/anagrams/\n */\npublic class GroupAnagramsTogether {\n    public List<List<String>> groupAnagrams(String[] strs) {\n        if (strs == null || strs.length == 0)\n            return new ArrayList<List<String>>();\n        \n        int listIndex = 0;\n        List<List<String>> result = new ArrayList<>();\n        Map<String, Integer> anagramGroup = new HashMap<>();\n        \n        for (String str : strs) {\n            char[] chars = str.toCharArray();\n            Arrays.sort(chars);\n            String sorted = new String(chars);\n            if (anagramGroup.containsKey(sorted)) {\n                int index = anagramGroup.get(sorted);\n                List<String> listResult = result.get(index);    \n                listResult.add(str);\n            } else {\n                List<String> resultList = new ArrayList<>();\n                resultList.add(str);\n                result.add(listIndex, resultList);\n                anagramGroup.put(sorted, listIndex);\n                listIndex++;\n            }\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/InPlaceTransformationOfString.java",
    "content": "package com.interview.string;\n\n/**\n * http://www.geeksforgeeks.org/an-in-place-algorithm-for-string-transformation/\n */\npublic class InPlaceTransformationOfString {\n\n    private void reverse(char []str, int low, int high){\n        while(low<high){\n            swap(str,low,high);\n            low++;\n            high--;\n        }\n    }\n    \n    private void swap(char str[],int index1,int index2){\n        char temp = str[index1];\n        str[index1] = str[index2];\n        str[index2] = temp;\n    }\n    \n    public void cycleLeaderIteration(char []str,int start,int end){\n        \n        int power = 1;\n        int index = start,new_index;\n        int len = end -start +1;\n        char temp,temp1;\n        while(power < len){\n            index = start+power;\n            new_index = start;\n            temp = str[index];\n            while(new_index != power + start){\n                if(index % 2 == 0){\n                    new_index = (index+start)/2;\n                }else{\n                    new_index = len/2 + (index+start)/2;\n                }\n                temp1 = str[new_index];\n                str[new_index] = temp;\n                temp = temp1;\n                index = new_index;\n            }\n            power *= 3;\n        }\n    }\n    \n    public void inPlaceTransformationImproved(char str[]){\n        int low=0;\n        int size = str.length;\n        while(size > 0){\n            int end = get3PowerK1(size);\n            size = size-end;\n            CycleLeaderIteration cli = new CycleLeaderIteration();\n            cli.iterate(str, low, end + low-1);\n            low = low+end;\n        }\n        size = str.length;\n        low =0;\n        int end = get3PowerK1(size);\n        while(end < str.length){\n            int nextEnd = get3PowerK1(str.length-end);\n            reverse(str,end/2,end-1);\n            reverse(str,end/2,end+nextEnd/2-1);\n            reverse(str,end/2,end/2+nextEnd/2-1);\n    //      size = str.length - (end + nextEnd);\n            end = end + nextEnd;\n        }\n    }\n    \n    private int get3PowerK1(int size){\n        int power = 1;\n        while((power*3 +1)<= size){\n            power = power*3;\n        }\n        return power+1;\n    }\n    \n    public static void main(String args[]){\n        char str[] = {'a','1','b','2','c','3','d','4','e','5','f','6','g','7','h','8','i','9','j','A','k','B','l','C','m','D'};\n        InPlaceTransformationOfString ip = new InPlaceTransformationOfString();\n        ip.inPlaceTransformationImproved(str);\n        for(int i=0; i < str.length; i++){\n            System.out.print(str[i]);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/string/LexicographicRankInPermutation.java",
    "content": "package com.interview.string;\n\npublic class LexicographicRankInPermutation {\n\n    //you can create a AVL tree to efficiently find total\n    //number of smaller characters.\n    //You can keep size of subtree at root and keep moving left or right\n    //depending on the character you looking for\n    private int findNumberOfSmallerCharactersOnRight(int index,char []str){\n        int count=0;\n        for(int i=index+1; i < str.length; i++){\n            if(str[i] < str[index]){\n                count++;\n            }\n        }\n        return count;\n    }\n    \n    private int factorial(int n){\n        int fact = 1;\n        for(int i =1; i <=n; i++){\n            fact = i*fact;\n        }\n        return fact;\n    }\n    \n    public int rank(char []str){\n        \n        int rank =0;\n        for(int i=0; i < str.length;i++){\n            int num = findNumberOfSmallerCharactersOnRight(i, str);\n            rank += factorial(str.length -i-1)*num;\n        }\n        return rank+1;\n        \n    }\n    \n    public static void main(String args[]){\n        LexicographicRankInPermutation lrp = new LexicographicRankInPermutation();\n        int rank = lrp.rank(\"STRING\".toCharArray());\n        System.out.println(rank);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/LongestPalindromeSubstring.java",
    "content": "package com.interview.string;\n\n/**\n * Date 07/29/2015\n * @author Tushar Roy\n *\n * Given a string find longest palindromic substring in this string.\n *\n * References\n * http://www.geeksforgeeks.org/longest-palindrome-substring-set-1/\n * http://www.geeksforgeeks.org/longest-palindromic-substring-set-2/\n * http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html\n * http://www.akalin.cx/longest-palindrome-linear-time\n * http://tarokuriyama.com/projects/palindrome2.php\n */\npublic class LongestPalindromeSubstring {\n\n    public int longestPalindromeSubstringEasy(char arr[]) {\n\n        int longest_substring = 1;\n        for (int i = 0; i < arr.length; i++) {\n\n            int x, y;\n            int palindrome;\n            x = i;\n            y = i + 1;\n            palindrome = 0;\n            while (x >= 0 && y < arr.length && arr[x] == arr[y]) {\n                x--;\n                y++;\n                palindrome += 2;\n            }\n            longest_substring = Math.max(longest_substring, palindrome);\n            \n            x = i - 1;\n            y = i + 1;\n            palindrome = 1;\n            while (x >= 0 && y < arr.length && arr[x] == arr[y]) {\n                x--;\n                y++;\n                palindrome += 2;\n            }\n            longest_substring = Math.max(longest_substring, palindrome);\n        }\n        return longest_substring;\n    }\n\n    /**\n     * Linear time Manacher's algorithm to find longest palindromic substring.\n     * There are 4 cases to handle\n     * Case 1 : Right side palindrome is totally contained under current palindrome. In this case do not consider this as center.\n     * Case 2 : Current palindrome is proper suffix of input. Terminate the loop in this case. No better palindrom will be found on right.\n     * Case 3 : Right side palindrome is proper suffix and its corresponding left side palindrome is proper prefix of current palindrome. Make largest such point as\n     * next center.\n     * Case 4 : Right side palindrome is proper suffix but its left corresponding palindrome is be beyond current palindrome. Do not consider this\n     * as center because it will not extend at all.\n     *\n     * To handle even size palindromes replace input string with one containing $ between every input character and in start and end.\n     */\n    public int longestPalindromicSubstringLinear(char input[]) {\n        int index = 0;\n        //preprocess the input to convert it into type abc -> $a$b$c$ to handle even length case.\n        //Total size will be 2*n + 1 of this new array.\n        char newInput[] = new char[2*input.length + 1];\n        for(int i=0; i < newInput.length; i++) {\n            if(i % 2 != 0) {\n                newInput[i] = input[index++];\n            } else {\n                newInput[i] = '$';\n            }\n        }\n\n        //create temporary array for holding largest palindrome at every point. There are 2*n + 1 such points.\n        int T[] = new int[newInput.length];\n        int start = 0;\n        int end = 0;\n        //here i is the center.\n        for(int i=0; i < newInput.length; ) {\n            //expand around i. See how far we can go.\n            while(start >0 && end < newInput.length-1 && newInput[start-1] == newInput[end+1]) {\n                start--;\n                end++;\n            }\n            //set the longest value of palindrome around center i at T[i]\n            T[i] = end - start + 1;\n\n            //this is case 2. Current palindrome is proper suffix of input. No need to proceed. Just break out of loop.\n            if(end == T.length -1) {\n                break;\n            }\n            //Mark newCenter to be either end or end + 1 depending on if we dealing with even or old number input.\n            int newCenter = end + (i%2 ==0 ? 1 : 0);\n\n            for(int j = i + 1; j <= end; j++) {\n\n                //i - (j - i) is left mirror. Its possible left mirror might go beyond current center palindrome. So take minimum\n                //of either left side palindrome or distance of j to end.\n                T[j] = Math.min(T[i - (j - i)], 2 * (end - j) + 1);\n                //Only proceed if we get case 3. This check is to make sure we do not pick j as new center for case 1 or case 4\n                //As soon as we find a center lets break out of this inner while loop.\n                if(j + T[i - (j - i)]/2 == end) {\n                    newCenter = j;\n                    break;\n                }\n            }\n            //make i as newCenter. Set right and left to atleast the value we already know should be matching based of left side palindrome.\n            i = newCenter;\n            end = i + T[i]/2;\n            start = i - T[i]/2;\n        }\n\n        //find the max palindrome in T and return it.\n        int max = Integer.MIN_VALUE;\n        for(int i = 0; i < T.length; i++) {\n            int val;\n      /*      if(i%2 == 0) {\n                val = (T[i] -1)/2;\n            } else {\n                val = T[i]/2;\n            }*/\n            val = T[i]/2;\n            if(max < val) {\n                max = val;\n            }\n        }\n        return max;\n    }\n\n    public int longestPalindromeDynamic(char []str){\n        boolean T[][] = new boolean[str.length][str.length];\n        \n        for(int i=0; i < T.length; i++){\n            T[i][i] = true;\n        }\n        \n        int max = 1;\n        for(int l = 2; l <= str.length; l++){\n            int len = 0;\n            for(int i=0; i < str.length-l+1; i++){\n                int j = i + l-1;\n                len = 0;\n                if(l == 2){\n                    if(str[i] == str[j]){\n                        T[i][j] = true;\n                        len = 2;\n                    }\n                }else{\n                    if(str[i] == str[j] && T[i+1][j-1]){\n                        T[i][j] = true;\n                        len = j -i + 1;\n                    }\n                }\n                if(len > max){\n                    max = len;\n                }\n            }\n        }\n        return max;\n    }\n\n    public static void main(String args[]) {\n        LongestPalindromeSubstring lps = new LongestPalindromeSubstring();\n        System.out.println(lps.longestPalindromicSubstringLinear(\"abba\".toCharArray()));\n        System.out.println(lps.longestPalindromicSubstringLinear(\"abbababba\".toCharArray()));\n        System.out.println(lps.longestPalindromicSubstringLinear(\"babcbaabcbaccba\".toCharArray()));\n        System.out.println(lps.longestPalindromicSubstringLinear(\"cdbabcbabdab\".toCharArray()));\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/string/LongestSubstringWithKDistinctCharacters.java",
    "content": "package com.interview.string;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 04/03/2016\n * @author Tushar Roy\n *\n * Given a string, find the length of the longest substring T that contains at most k distinct characters.\n * For example, Given s = “eceba” and k = 2,\n * T is \"ece\" which its length is 3.\n *\n * Time complexity O(n)\n * Space complexity O(n)\n *\n * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/\n */\npublic class LongestSubstringWithKDistinctCharacters {\n    public int lengthOfLongestSubstringKDistinct(String s, int k) {\n        if (k == 0 || s.length() == 0) {\n            return 0;\n        }\n        int[] ascii = new int[256];\n        int count = 0;\n        int start = 0;\n        int max = 0;\n        for (int i = 0; i < s.length(); i++) {\n            int ch = s.charAt(i);\n            if (count < k) {\n                if (ascii[ch] == 0) {\n                    count++;\n                }\n            } else if (ascii[ch] == 0){\n                while (start < i) {\n                    char ch1 = s.charAt(start++);\n                    ascii[ch1]--;\n                    if (ascii[ch1] == 0) {\n                        break;\n                    }\n                }\n            }\n            ascii[ch]++;\n            max = Math.max(max, i - start + 1);\n        }\n        return max;\n    }\n\n    public int lengthOfLongestSubstringKDistinctUsingMap(String s, int k) {\n        if (k == 0 || s.length() == 0) {\n            return 0;\n        }\n        Map<Character, Integer> countMap = new HashMap<>();\n        int max = 0;\n        int start = 0;\n        for (int i = 0; i < s.length(); i++) {\n            char ch = s.charAt(i);\n            if (!countMap.containsKey(ch) && countMap.size() >= k) {\n                while (start < i) {\n                    countMap.compute(s.charAt(start), (key, val) -> {\n                        if (val == 1) {\n                            return null;\n                        } else {\n                            return val - 1;\n                        }\n                    });\n                    start++;\n                    if (countMap.size() < k) {\n                        break;\n                    }\n                }\n            }\n            countMap.compute(ch, (key, val) -> {\n                if (val == null) {\n                    return 1;\n                } else {\n                    return val + 1;\n                }\n            });\n            max = Math.max(max, i - start + 1);\n        }\n        return max;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/LongestSubstringWithoutRepetingCharacter.java",
    "content": "package com.interview.string;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * References\n * http://www.geeksforgeeks.org/length-of-the-longest-substring-without-repeating-characters/\n * https://leetcode.com/problems/longest-substring-without-repeating-characters/\n */\npublic class LongestSubstringWithoutRepetingCharacter {\n\n    public int lengthOfLongestSubstring(String s) {\n        Set<Character> uniqueSet = new HashSet<>();\n        int maxSize = 0;\n        int start = 0;\n        for(int i = 0; i < s.length(); i++) {\n            if(!uniqueSet.contains(s.charAt(i))) {\n                uniqueSet.add(s.charAt(i));\n                if(uniqueSet.size() > maxSize) {\n                    maxSize = uniqueSet.size();\n                }\n            } else {\n                while (s.charAt(start) != s.charAt(i)) {\n                    uniqueSet.remove(s.charAt(start));\n                    start++;\n                }\n                start++;\n            }\n        }\n        return maxSize;\n    }\n    \n    public static void main(String args[]){\n        LongestSubstringWithoutRepetingCharacter lsw = new LongestSubstringWithoutRepetingCharacter();\n        System.out.println(lsw.lengthOfLongestSubstring(\"ABCDECAMNCZB\"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/MultiplyStrings.java",
    "content": "package com.interview.string;\n\n/**\n * https://leetcode.com/discuss/questions/oj/multiply-strings\n */\npublic class MultiplyStrings {\n\n    public String multiply(String num1, String num2) {\n        String output = multiply(num1, num2, 0, num1.length() - 1, 0, num2.length() - 1);\n        return output;\n    }\n\n    private String multiply(String num1, String num2, int start1, int end1, int start2, int end2) {\n        if (end1 - start1 == 0 || end2 - start2 == 0) {\n            return simpleMultiply(num1.substring(start1, end1 + 1), num2.substring(start2, end2 + 1));\n        }\n\n        int mid1 = (start1 + end1)/2;\n        int mid2 = (start2 + end2)/2;\n\n        int count1 = end1 - mid1;\n        int count2 = end2 - mid2;\n\n        String v1 = multiply(num1, num2, start1, mid1, start2, mid2);\n        String v2 = multiply(num1, num2, start1, mid1, mid2 + 1, end2);\n        String v3 = multiply(num1, num2, mid1 + 1, end1, start2, mid2);\n        String v4 = multiply(num1, num2, mid1 + 1, end1, mid2 + 1, end2);\n\n        v1 = append0s(v1, count1 + count2);\n        v2 = append0s(v2, count1);\n        v3 = append0s(v3, count2);\n\n        v1 = add(v1.toCharArray(), v2.toCharArray());\n        v3 = add(v3.toCharArray(), v4.toCharArray());\n        return add(v1.toCharArray(), v3.toCharArray());\n    }\n\n    private String simpleMultiply(String num1, String num2) {\n        String smaller;\n        String larger;\n        if (num1.length() == 1) {\n            smaller = num1;\n            larger = num2;\n        } else {\n            smaller = num2;\n            larger = num1;\n        }\n        int r2 = smaller.charAt(0) - '0';\n        if (r2 == 0) {\n            return \"0\";\n        }\n        int carry = 0;\n        StringBuffer stringBuffer = new StringBuffer();\n        for (int i = larger.length() - 1; i >= 0; i--) {\n            int r1 = larger.charAt(i) - '0';\n            int r = r1 * r2 + carry;\n            stringBuffer.append(r%10);\n            carry = r / 10;\n        }\n        if (carry != 0) {\n            stringBuffer.append(carry);\n        }\n        return stringBuffer.reverse().toString();\n    }\n\n    private String append0s(String v1, int count ) {\n        StringBuffer buff = new StringBuffer(v1);\n        for (int i = 0; i < count; i++) {\n            buff.append(\"0\");\n        }\n        return buff.toString();\n    }\n\n    public String add(char[] num1,char[] num2){\n        int index1 = num1.length -1;\n        int index2 = num2.length -1;\n        int carry = 0;\n        StringBuffer buffer = new StringBuffer();\n        while(index1 >= 0 && index2 >= 0){\n            int r1 = num1[index1] - '0';\n            int r2 = num2[index2] - '0';\n            int r = r1 + r2 + carry;\n            buffer.append(r%10);\n            carry = r/10;\n            index1--;\n            index2--;\n        }\n        while(index1 >= 0){\n            int r1 = num1[index1] - '0';\n            int r = r1 + carry;\n            buffer.append(r%10);\n            carry = r/10;\n            index1--;\n        }\n        while(index2 >= 0){\n            int r2 = num2[index2] - '0';\n            int r = r2 + carry;\n            buffer.append(r%10);\n            carry = r/10;\n            index2--;\n        }\n        if (carry != 0) {\n            buffer.append(carry);\n        }\n        return buffer.reverse().toString();\n    }\n\n    public static void main(String args[]) {\n        MultiplyStrings ms = new MultiplyStrings();\n        System.out.print(ms.multiply(\"6752716719037375654442652725945722915786612669126862029212\",\"2840271321219335147\"));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/NTMatch.java",
    "content": "package com.interview.string;\n\n/**\n.Given an input string S write a function which returns true if it satisfies S = nT. Basically you have to find if a given string can be represented from a substring by iterating it �n� times. n >= 2\nAn example would suffice \nFunction should return true if\n1) S = abab\n2) S = abcdabcd\n3) S = abcabcabc\n4) S = zzxzzxzzx\n\nFunction should return false if\n1) S = abac\n2) S = abcdabbd\n3) S = abcabcefg\n4) S = zzxzzyzzx\n */\npublic class NTMatch {\n\n    public boolean match(char str[]){\n        int kmp[] = buildKMP(str);\n        int index = kmp[str.length-1];\n        //reason end is this rather than index+1 because\n        //if our string was ababab for KMP we would have index as 4 at str.length-1 and we\n        //want end to be 1 rather than 5\n        int end = str.length - index-1;\n        if(end >= str.length/2){\n            return false;\n        }\n        int j = end+1;\n        int i = 0;\n        while(j < str.length){\n            if(str[i] != str[j]){\n                return false;\n            }\n            i = (i+1)%(end+1);\n            j++;\n        }\n        \n        if(i == 0){\n            return true;\n        }\n        return false;\n    }\n    \n    private int[] buildKMP(char str[]){\n\n        int result[] = new int[str.length];\n        \n        int i =1;\n        result[0] = 0;\n        int len =0;\n        while(i < str.length){\n            if(str[i] == str[len]){\n                len++;\n                result[i] = len;\n                i++;\n            }else{\n                if(len != 0){\n                    len = result[len-1];\n                }else{\n                    len =0;\n                    result[i] = 0;\n                    i++;\n                }\n            }\n        }\n        return result;\n    }\n    \n    public static void main(String args[]){\n        NTMatch ntMatch = new NTMatch();\n        System.out.println(ntMatch.match(\"bababababa\".toCharArray()));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/PalindromePair.java",
    "content": "package com.interview.string;\n\nimport java.util.*;\n\n/**\n * Given a list of unique words. Find all pairs of distinct indices (i, j) in the given list,\n * so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.\n *\n * Solution -\n * First keep mapping of word and its index.\n * Then iterate through every word and split it into every possible 2 substring. Then if first substring is palindrome\n * and reverse of second substring is in map means you can form a palindrome by combing this word with the word\n * in the map.\n *\n * Time complexity is O(n*k*k)\n *\n * Reference\n * https://leetcode.com/problems/palindrome-pairs/\n */\npublic class PalindromePair {\n\n    public List<List<Integer>> palindromePairs(String[] words) {\n        if (words == null || words.length < 2) {\n            return Collections.EMPTY_LIST;\n        }\n        Map<String, Integer> wordMap = new HashMap<>();\n        List<List<Integer>> result = new ArrayList<>();\n\n        for (int i = 0; i < words.length; i++) {\n            wordMap.put(words[i], i);\n        }\n\n        for (int i = 0; i < words.length; i++) {\n            for (int j = 0; j < words[i].length(); j++) {\n                String str1 = words[i].substring(0, j + 1);\n                String str2 = words[i].substring(j + 1, words[i].length());\n                if (isPalindrome(str2)) {\n                    String revStr1 = new StringBuilder(str1).reverse().toString();\n                    Integer index = wordMap.get(revStr1);\n                    if (index != null) {\n                        createList(i, wordMap.get(revStr1), result);\n                    }\n                }\n                if (isPalindrome(str1)) {\n                    String revStr2 = new StringBuilder(str2).reverse().toString();\n                    Integer index = wordMap.get(revStr2);\n                    if (index != null) {\n                        createList(wordMap.get(revStr2), i, result);\n                        if (revStr2.equals(\"\")) {\n                            createList(i, wordMap.get(revStr2), result);\n                        }\n                    }\n                }\n            }\n        }\n        return result;\n    }\n\n    private boolean isPalindrome(String word) {\n        int start = 0;\n        int end = word.length() - 1;\n        while (start < end) {\n            if (word.charAt(start) != word.charAt(end)) {\n                return false;\n            }\n            start++;\n            end--;\n        }\n        return true;\n    }\n\n    private void createList(int i1, int i2, List<List<Integer>> result) {\n        if (i1 == i2) {\n            return;\n        }\n        List<Integer> r = new ArrayList<>();\n        r.add(i1);\n        r.add(i2);\n        result.add(r);\n    }\n\n    public static void main(String args[]) {\n        PalindromePair palindromePair = new PalindromePair();\n        String[] words = {\"bat\", \"tab\"};\n        List<List<Integer>> result = palindromePair.palindromePairs(words);\n        System.out.println(result);\n        String[] words1 = {\"abcd\", \"dcba\", \"lls\", \"s\", \"sssll\"};\n        result = palindromePair.palindromePairs(words1);\n        System.out.println(result);\n        String[] words2 = {\"\", \"abcd\", \"abba\"};\n        result = palindromePair.palindromePairs(words2);\n        System.out.println(result);\n        String[] words3 = {\"a\",\"abc\",\"aba\",\"\"};\n        result = palindromePair.palindromePairs(words3);\n        System.out.println(result);\n        String[] words4 = {\"abcd\",\"dcba\",\"lls\",\"s\",\"sssll\"};\n        result = palindromePair.palindromePairs(words4);\n        System.out.println(result);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/PrintAnagramTogether.java",
    "content": "package com.interview.string;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\npublic class PrintAnagramTogether {\n\n    public void print(String[] string){\n        Map<String,List<Integer>> invertedIndex = new HashMap<String,List<Integer>>();\n        int index = 0;\n        for(String str : string){\n            char [] charArray = str.toCharArray();\n            Arrays.sort(charArray);\n            String newString = new String(charArray);\n            if(invertedIndex.containsKey(newString)){\n                List<Integer> pos = invertedIndex.get(newString);\n                pos.add(index);\n            }else{\n                List<Integer> pos = new ArrayList<Integer>();\n                pos.add(index);\n                invertedIndex.put(newString, pos);\n            }\n            index++;\n        }\n        for(List<Integer> result  : invertedIndex.values()){\n            for(Integer i : result){\n                System.out.println(string[i]);\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        String str[] = {\"cat\",\"dog\",\"tac\",\"god\",\"act\"};\n        PrintAnagramTogether pat = new PrintAnagramTogether();\n        pat.print(str);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/string/RabinKarpSearch.java",
    "content": "package com.interview.string;\n\n/**\n * Date 09/25/2014\n * @author Tushar Roy\n *\n * Rabin Karp algorith for substring matching.\n *\n * Time complexity in worst case O(n^2)(depends on hash function)\n * Space complexity O(1)\n *\n * References\n * https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm\n */\npublic class RabinKarpSearch {\n\n    private int prime = 101;\n    \n    public int patternSearch(char[] text, char[] pattern){\n        int m = pattern.length;\n        int n = text.length;\n        long patternHash = createHash(pattern, m - 1);\n        long textHash = createHash(text, m - 1);\n        for (int i = 1; i <= n - m + 1; i++) {\n            if(patternHash == textHash && checkEqual(text, i - 1, i + m - 2, pattern, 0, m - 1)) {\n                return i - 1;\n            }\n            if(i < n - m + 1) {\n                textHash = recalculateHash(text, i - 1, i + m - 1, textHash, m);\n            }\n        }\n        return -1;\n    }\n    \n    private long recalculateHash(char[] str,int oldIndex, int newIndex,long oldHash, int patternLen) {\n        long newHash = oldHash - str[oldIndex];\n        newHash = newHash/prime;\n        newHash += str[newIndex]*Math.pow(prime, patternLen - 1);\n        return newHash;\n    }\n    \n    private long createHash(char[] str, int end){\n        long hash = 0;\n        for (int i = 0 ; i <= end; i++) {\n            hash += str[i]*Math.pow(prime,i);\n        }\n        return hash;\n    }\n    \n    private boolean checkEqual(char str1[],int start1,int end1, char str2[],int start2,int end2){\n        if(end1 - start1 != end2 - start2) {\n            return false;\n        }\n        while(start1 <= end1 && start2 <= end2){\n            if(str1[start1] != str2[start2]){\n                return false;\n            }\n            start1++;\n            start2++;\n        }\n        return true;\n    }\n    \n    public static void main(String args[]){\n        RabinKarpSearch rks = new RabinKarpSearch();\n        System.out.println(rks.patternSearch(\"TusharRoy\".toCharArray(), \"sharRoy\".toCharArray()));\n        System.out.println(rks.patternSearch(\"TusharRoy\".toCharArray(), \"Roy\".toCharArray()));\n        System.out.println(rks.patternSearch(\"TusharRoy\".toCharArray(), \"shas\".toCharArray()));\n        System.out.println(rks.patternSearch(\"TusharRoy\".toCharArray(), \"usha\".toCharArray()));\n        System.out.println(rks.patternSearch(\"TusharRoy\".toCharArray(), \"Tus\".toCharArray()));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/RearrangeDuplicateCharsdDistanceAway.java",
    "content": "package com.interview.string;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.PriorityQueue;\nimport java.util.Set;\n\n/**\n * http://www.geeksforgeeks.org/rearrange-a-string-so-that-all-same-characters-become-at-least-d-distance-away/\n * \n */\npublic class RearrangeDuplicateCharsdDistanceAway {\n\n    class CharCount implements Comparable<CharCount>{\n        char ch;\n        int count;\n        @Override\n        public int hashCode() {\n            final int prime = 31;\n            int result = 1;\n            result = prime * result + getOuterType().hashCode();\n            result = prime * result + ch;\n            return result;\n        }\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj)\n                return true;\n            if (obj == null)\n                return false;\n            if (getClass() != obj.getClass())\n                return false;\n            CharCount other = (CharCount) obj;\n            if (!getOuterType().equals(other.getOuterType()))\n                return false;\n            if (ch != other.ch)\n                return false;\n            return true;\n        }\n        private RearrangeDuplicateCharsdDistanceAway getOuterType() {\n            return RearrangeDuplicateCharsdDistanceAway.this;\n        }\n        \n        \n        @Override\n        public String toString() {\n            return \"CharCount [ch=\" + ch + \", count=\" + count + \"]\";\n        }\n        @Override\n        public int compareTo(CharCount cc) {\n            if(this.count >= cc.count){\n                return -1;\n            }else{\n                return 1;\n            }\n        }\n        \n    }\n    \n    public boolean rearrangeExactKDistanceAway(char input[],int d){\n        PriorityQueue<CharCount> heap = new PriorityQueue<CharCount>();\n        Map<Character,Integer> map = new HashMap<Character,Integer>();\n        for(int i=0; i < input.length; i++){\n            int count = 1;\n            if(map.containsKey(input[i])){\n                count = map.get(input[i]);\n                count++;\n            }\n            map.put(input[i], count);\n            input[i] = 0;\n        }\n        for(Character ch : map.keySet()){\n            CharCount cc = new CharCount();\n            cc.ch = ch;\n            cc.count = map.get(ch);\n            heap.add(cc);\n        }\n        \n        while(heap.size() > 0){\n            CharCount cc = heap.poll();\n            int i;\n            for(i=0; i < input.length && input[i] != 0; i++);\n            if(i == input.length){\n                return false;\n            }\n            while(cc.count > 0 && i < input.length){\n                input[i] = cc.ch;\n                i = i + d;\n                cc.count--;\n            }\n            if(cc.count > 0){\n                return false;\n            }\n        }\n        return true;\n    }\n    \n    private void getAllFeasibleCharacters(char output[], int k,int pos,Set<Character> allChars){\n        for(int i = pos-1; i > pos -k && i >=0; i--){\n            allChars.remove(output[i]);\n        }\n    }\n    \n    public boolean rearrangeAtleastkDistanceAway(char input[],int k){\n        Map<Character,Integer> map = new HashMap<Character,Integer>();\n        for(int i=0; i < input.length; i++){\n            int count = 1;\n            if(map.containsKey(input[i])){\n                count = map.get(input[i]);\n                count++;\n            }\n            map.put(input[i], count);\n            input[i] = 0;\n        }\n        return rearrangeAtleastkDistanceAway(map, input, 0, k);\n    }\n    \n    public boolean rearrangeAtleastkDistanceAway(Map<Character,Integer> charCount,char output[],int pos,int k){\n        if(pos == output.length && charCount.size() == 0){\n            return true;\n        }\n        Set<Character> allChars = new HashSet<Character>();\n        for(char ch : charCount.keySet()){\n            allChars.add(ch);\n        }\n        getAllFeasibleCharacters(output,k,pos,allChars);\n        for(char ch : allChars){\n            output[pos] = ch;\n            int c = charCount.get(ch);\n            if(c -1 == 0){\n                charCount.remove(ch);\n            }else{\n                charCount.put(ch, c-1);\n            }\n            boolean r = rearrangeAtleastkDistanceAway(charCount, output, pos+1, k);\n            if(r){\n                return true;\n            }\n            charCount.put(ch, c);\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        String str = \"ABBACCCCDD\"; \n        char input[] = str.toCharArray();\n        RearrangeDuplicateCharsdDistanceAway rdc  =new RearrangeDuplicateCharsdDistanceAway();\n        boolean r =rdc.rearrangeAtleastkDistanceAway(input, 3);\n        if(r){\n            for(char ch : input){\n                System.out.print(ch + \" \");\n            }\n        }else{\n            System.out.println(\"Not possible\");\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/string/RemoveConsecutiveDuplicate.java",
    "content": "package com.interview.string;\n\n/**\n * Remove consecutive duplicate characters\n * e.g\n * AABBCDDAAB -> ABCDAB\n * ABBBCCD -> ABCD\n * Test cases\n * Empty string\n * all unique\n * all duplicates\n * duplicates at certain different places\n */\npublic class RemoveConsecutiveDuplicate {\n\n    public int removeDuplicates(char input[]){\n        int slow = 0;\n        int fast = 0;\n        int index = 0;\n        while(fast < input.length){\n            while(fast < input.length && input[slow] == input[fast]){\n                fast++;\n            }\n            input[index++] = input[slow];\n            slow = fast;\n        }\n        return index;\n    }\n    \n    public static void main(String args[]){\n        String str = \"AAABBCCDDDEFGH\";\n        char input[] = str.toCharArray();\n        RemoveConsecutiveDuplicate rcd = new RemoveConsecutiveDuplicate();\n        int len = rcd.removeDuplicates(input);\n        for(int i=0; i < len; i++){\n            System.out.print(input[i] + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/RunLengthEncoding.java",
    "content": "package com.interview.string;\n\npublic class RunLengthEncoding {\n\n    private int updateCounter(char[] result, int current, int counter){\n    \n        int tempCounter = counter;\n        int len = 1;\n        while(tempCounter > 0){\n            len = len*10;\n            tempCounter /= 10;\n        }\n        len = len/10;\n        \n        while(counter > 0){\n            result[current++] = (char)((counter/len) + '0');\n            counter = counter%len;\n            len /= 10;\n        }\n        return current;\n    }\n    \n    public int encoding(char[] str,char[] result){\n\n        char pickedChar = str[0];\n        int current =0;\n        int counter =1;\n        for(int i=1; i < str.length; i++){\n            if(str[i] == pickedChar){\n                counter++;\n            }\n            else{\n                result[current++] = pickedChar;\n                current = updateCounter(result, current, counter);\n                pickedChar = str[i];\n                counter =1;\n            }\n        }\n        result[current++] = pickedChar;\n        current = updateCounter(result, current, counter);\n        return current;\n    }\n    \n    public static void main(String args[]){\n        \n        String str = \"AAAAAAAAAAAAABBCDDEEEEE\";\n        char result[] = new char[str.length()*2];\n        RunLengthEncoding rle = new RunLengthEncoding();\n        int current = rle.encoding(str.toCharArray(),result);\n        for(int i=0; i < current; i++){\n            System.out.print(result[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/SmallestWindowContaingAllCharacters.java",
    "content": "package com.interview.string;\n\n/**\n * References\n * https://leetcode.com/problems/minimum-window-substring/\n * http://www.geeksforgeeks.org/find-the-smallest-window-in-a-string-containing-all-characters-of-another-string/\n */\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class SmallestWindowContaingAllCharacters {\n\n    public String minWindow(String s, String t) {\n        Map<Character, Integer> countMap = new HashMap<>();\n        for (char ch : t.toCharArray()) {\n            Integer val = countMap.get(ch);\n            if (val == null) {\n                val = 0;\n            }\n            countMap.put(ch, val + 1);\n        }\n        int start = 0;\n        int currLen = t.length();\n        int minWindow = Integer.MAX_VALUE;\n        int minStart = 0;\n        int i = 0;\n        while (i < s.length()) {\n            Integer val = countMap.get(s.charAt(i));\n            if (val == null) {\n                i++;\n                continue;\n            }\n            if (val > 0) {\n                currLen--;\n            }\n            val--;\n            countMap.put(s.charAt(i), val);\n            while (currLen == 0) {\n                if (minWindow > i - start + 1) {\n                    minWindow = i - start + 1;\n                    minStart = start;\n                }\n                Integer val1 = countMap.get(s.charAt(start));\n                if (val1 != null) {\n                    if (val1 == 0) {\n                        break;\n                    } else {\n                        val1++;\n                        countMap.put(s.charAt(start), val1);\n                    }\n                }\n                start++;\n            }\n            i++;\n        }\n\n        return minWindow != Integer.MAX_VALUE ? s.substring(minStart, minStart + minWindow) : \"\";\n    }\n\n    public static void main(String args[]) {\n\n        String str = \"Tsuaosyogrlmnsluuorjkoruost\";\n        String subString = \"soor\";\n        SmallestWindowContaingAllCharacters swcac = new SmallestWindowContaingAllCharacters();\n        String result = swcac.minWindow(str, subString);\n        System.out.println(result);\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/string/StringEncoderDecoder.java",
    "content": "package com.interview.string;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 04/06/2016\n * @author Tushar Roy\n *\n * Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network\n * and is decoded back to the original list of strings.\n *\n * Reference\n * https://leetcode.com/problems/encode-and-decode-strings/\n */\npublic class StringEncoderDecoder {\n\n    // Encodes a list of strings to a single string.\n    public String encode(List<String> strs) {\n        StringBuffer buff = new StringBuffer();\n        for (String str : strs) {\n            String size = toFixedLength(str.length());\n            buff.append(size);\n            buff.append(str);\n        }\n        return buff.toString();\n    }\n\n    private String toFixedLength(int len) {\n        StringBuffer buff = new StringBuffer();\n        for (int i = 0; i < 4; i++) {\n            char b1 = (char) len;\n            buff.append(b1);\n            len = len >> 8;\n        }\n        return buff.toString();\n    }\n\n    private int toSize(String str) {\n        int val = 0;\n        for (int i = str.length() - 1; i > 0; i--) {\n            val += str.charAt(i);\n            val = val << 8;\n        }\n        val += str.charAt(0);\n        return val;\n    }\n\n    // Decodes a single string to a list of strings.\n    public List<String> decode(String s) {\n        List<String> result = new ArrayList<>();\n        while (s.length() != 0) {\n            int size = toSize(s.substring(0, 4));\n            result.add(s.substring(4, size + 4));\n            s = s.substring(size + 4);\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/SubstringSearch.java",
    "content": "package com.interview.string;\n\n/**\n * Date 09/22/2014\n * @author tusroy\n * \n * Do pattern matching using KMP algorithm\n * \n * Runtime complexity - O(m + n) where m is length of text and n is length of pattern\n * Space complexity - O(n)\n */\npublic class SubstringSearch {\n\n    /**\n     * Slow method of pattern matching\n     */\n    public boolean hasSubstring(char[] text, char[] pattern){\n        int i=0;\n        int j=0;\n        int k = 0;\n        while(i < text.length && j < pattern.length){\n            if(text[i] == pattern[j]){\n                i++;\n                j++;\n            }else{\n                j=0;\n                k++;\n                i = k;\n            }\n        }\n        if(j == pattern.length){\n            return true;\n        }\n        return false;\n    }\n    \n    /**\n     * Compute temporary array to maintain size of suffix which is same as prefix\n     * Time/space complexity is O(size of pattern)\n     */\n    private int[] computeTemporaryArray(char pattern[]){\n        int [] lps = new int[pattern.length];\n        int index =0;\n        for(int i=1; i < pattern.length;){\n            if(pattern[i] == pattern[index]){\n                lps[i] = index + 1;\n                index++;\n                i++;\n            }else{\n                if(index != 0){\n                    index = lps[index-1];\n                }else{\n                    lps[i] =0;\n                    i++;\n                }\n            }\n        }\n        return lps;\n    }\n    \n    /**\n     * KMP algorithm of pattern matching.\n     */\n    public boolean KMP(char []text, char []pattern){\n        \n        int lps[] = computeTemporaryArray(pattern);\n        int i=0;\n        int j=0;\n        while(i < text.length && j < pattern.length){\n            if(text[i] == pattern[j]){\n                i++;\n                j++;\n            }else{\n                if(j!=0){\n                    j = lps[j-1];\n                }else{\n                    i++;\n                }\n            }\n        }\n        if(j == pattern.length){\n            return true;\n        }\n        return false;\n    }\n        \n    public static void main(String args[]){\n        \n        String str = \"abcxabcdabcdabcy\";\n        String subString = \"abcdabcy\";\n        SubstringSearch ss = new SubstringSearch();\n        boolean result = ss.KMP(str.toCharArray(), subString.toCharArray());\n        System.out.print(result);\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/SubtringWithConcatentationOfWords.java",
    "content": "package com.interview.string;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * References\n * https://leetcode.com/problems/substring-with-concatenation-of-all-words/\n */\npublic class SubtringWithConcatentationOfWords {\n    public List<Integer> findSubstring(String s, String[] words) {\n        Map<String, Integer> actual = new HashMap<>();\n        Map<String, Integer> used = new HashMap<>();\n        set(actual, words);\n        List<Integer> output = new ArrayList<>();\n        int len = words[0].length();\n        int count = words.length;\n        int k = words.length * len;\n\n        for (int i = 0; i <= s.length() - k; i++) {\n            int j = i;\n            int currentCount = 0;\n            while (true) {\n                if(j + len > s.length()) {\n                    break;\n                }\n                String sub = s.substring(j, j + len);\n                Integer actualCount = actual.get(sub);\n                if (actualCount != null) {\n                    Integer usedCount = used.get(sub);\n                    if ( usedCount == null) {\n                        usedCount = 0;\n                    }\n                    if ( actualCount > usedCount) {\n                        j = j + len;\n                        currentCount++;\n                        used.put(sub, usedCount + 1);\n                    } else {\n                        break;\n                    }\n                } else {\n                    break;\n                }\n                if ( currentCount == count) {\n                    break;\n                }\n            }\n            used.clear();\n            if (currentCount == count) {\n                output.add(i);\n            }\n        }\n        return output;\n    }\n\n    private void set(Map<String, Integer> actual, String[] words) {\n        for (String word : words) {\n            if (actual.containsKey(word)) {\n                actual.put(word,  actual.get(word) + 1);\n            } else {\n                actual.put(word, 1);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/ValidPalindrome.java",
    "content": "package com.interview.string;\n\n/**\n * Date 04/09/2016\n * @author Tushar Roy\n *\n * Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.\n * For example,\n * \"A man, a plan, a canal: Panama\" is a palindrome.\n * \"race a car\" is not a palindrome.\n *\n * https://leetcode.com/problems/valid-palindrome/\n */\npublic class ValidPalindrome {\n    public boolean isPalindrome(String s) {\n        int start = 0;\n        int end = s.length() - 1;\n        while (start < end) {\n            if (!isAlphaNum(s.charAt(start))) {\n                start++;\n            } else if (!isAlphaNum(s.charAt(end))) {\n                end--;\n            } else {\n                if (Character.toLowerCase(s.charAt(start++)) != Character.toLowerCase(s.charAt(end--))) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n\n    private boolean isAlphaNum(char ch) {\n        if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {\n            return true;\n        }\n        return false;\n    }\n}"
  },
  {
    "path": "src/com/interview/string/ValidWordAbbreviation.java",
    "content": "package com.interview.string;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Date 04/15/2016\n * @author Tushar Roy\n *\n * Given a dictionary of words and a word tell if there is unique abbrreviation of this word in the dictionary.\n */\npublic class ValidWordAbbreviation {\n    private final Map<String, Map<Integer, Integer>> map = new HashMap<>();\n    public ValidWordAbbreviation(String[] dictionary) {\n        for (String str : dictionary) {\n            String key = \"\";\n            int len = 0;\n            if (str.length() > 0) {\n                key = str.charAt(0) + \"\" + str.charAt(str.length() - 1);\n                len = str.length() - 2;\n            }\n            Map<Integer, Integer> innerMap = map.get(key);\n            if (innerMap == null) {\n                innerMap = new HashMap<>();\n                map.put(key, innerMap);\n            }\n            Integer count = innerMap.get(len);\n            if (count == null) {\n                count = 0;\n            }\n            innerMap.put(len, count + 1);\n        }\n    }\n\n    public boolean isUnique(String word) {\n        if (word.length() == 0 || word.length() == 1) {\n            return true;\n        }\n        String key = \"\";\n        int len = 0;\n        if (word.length() > 0) {\n            key = word.charAt(0) + \"\" + word.charAt(word.length() - 1);\n            len = word.length() - 2;\n        }\n        Map<Integer, Integer> set = map.get(key);\n        if (set == null) {\n            return true;\n        }\n        Integer count = set.get(len);\n        return count == null || count == 1;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/WordAbbreviationCombination.java",
    "content": "package com.interview.string;\n\nimport java.util.*;\n\n/**\n * Date 04/17/2106\n * @author Tushar Roy\n *\n * Write a function to generate the generalized abbreviations of a word.\n * Example:\n * Given word = \"word\", return the following list (order does not matter):\n * [\"word\", \"1ord\", \"w1rd\", \"wo1d\", \"wor1\", \"2rd\", \"w2d\", \"wo2\", \"1o1d\", \"1or1\", \"w1r1\", \"1o2\", \"2r1\", \"3d\", \"w3\", \"4\"]\n *\n * https://leetcode.com/problems/generalized-abbreviation/\n */\npublic class WordAbbreviationCombination {\n\n    public List<String> generateAbbreviations(String word) {\n        List<String> result = new ArrayList<>();\n        generateAbbreviationsUtil(word, result, \"\", 0, 0);\n        return result;\n    }\n\n    public void generateAbbreviationsUtil(String input, List<String> result, String current, int pos, int count) {\n        if (input.length() == pos) {\n            if (count > 0) {\n                result.add(current + count);\n            } else {\n                result.add(current);\n            }\n            return;\n        }\n\n        generateAbbreviationsUtil(input, result, current, pos + 1, count + 1);\n        generateAbbreviationsUtil(input, result, current + (count > 0 ? count : \"\") + input.charAt(pos), pos + 1, 0);\n    }\n\n    public static void main(String args[]) {\n        WordAbbreviationCombination ssc = new WordAbbreviationCombination();\n        List<String> result = ssc.generateAbbreviations(\"word\");\n        result.forEach(r -> System.out.println(r));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/string/ZAlgorithm.java",
    "content": "package com.interview.string;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 10/31/2015\n * @author Tushar Roy\n *\n * Z algorithm to pattern matching\n *\n * Time complexity - O(n + m)\n * Space complexity - O(n + m)\n *\n * http://www.geeksforgeeks.org/z-algorithm-linear-time-pattern-searching-algorithm/\n * http://www.utdallas.edu/~besp/demo/John2010/z-algorithm.htm\n */\npublic class ZAlgorithm {\n\n    private int[] calculateZ(char input[]) {\n        int Z[] = new int[input.length];\n        int left = 0;\n        int right = 0;\n        for(int k = 1; k < input.length; k++) {\n            if(k > right) {\n                left = right = k;\n                while(right < input.length && input[right] == input[right - left]) {\n                    right++;\n                }\n                Z[k] = right - left;\n                right--;\n            } else {\n                //we are operating inside box\n                int k1 = k - left;\n                //if value does not stretches till right bound then just copy it.\n                if(Z[k1] < right - k + 1) {\n                    Z[k] = Z[k1];\n                } else { //otherwise try to see if there are more matches.\n                    left = k;\n                    while(right < input.length && input[right] == input[right - left]) {\n                        right++;\n                    }\n                    Z[k] = right - left;\n                    right--;\n                }\n            }\n        }\n        return Z;\n    }\n\n    /**\n     * Returns list of all indices where pattern is found in text.\n     */\n    public List<Integer> matchPattern(char text[], char pattern[]) {\n        char newString[] = new char[text.length + pattern.length + 1];\n        int i = 0;\n        for(char ch : pattern) {\n            newString[i] = ch;\n            i++;\n        }\n        newString[i] = '$';\n        i++;\n        for(char ch : text) {\n            newString[i] = ch;\n            i++;\n        }\n        List<Integer> result = new ArrayList<>();\n        int Z[] = calculateZ(newString);\n\n        for(i = 0; i < Z.length ; i++) {\n            if(Z[i] == pattern.length) {\n                result.add(i - pattern.length - 1);\n            }\n        }\n        return result;\n    }\n\n    public static void main(String args[]) {\n        String text = \"aaabcxyzaaaabczaaczabbaaaaaabc\";\n        String pattern = \"aaabc\";\n        ZAlgorithm zAlgorithm = new ZAlgorithm();\n        List<Integer> result = zAlgorithm.matchPattern(text.toCharArray(), pattern.toCharArray());\n        result.forEach(System.out::println);\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/interview/suffixprefix/SuffixArray.java",
    "content": "package com.interview.suffixprefix;\n\nimport java.util.Arrays;\nimport java.util.Comparator;\n\n/**\n http://www.geeksforgeeks.org/suffix-array-set-1-introduction/\n */\npublic class SuffixArray {\n\n    public static class SuffixSort implements Comparator<Integer>{\n        \n        private char str[] = null;\n        \n        public SuffixSort(char str[]){\n            this.str = str;\n        }\n        \n        @Override\n        public int compare(Integer i1, Integer i2) {\n            while(i1 < str.length && i2 < str.length && str[i1] == str[i2]){\n                i1++;\n                i2++;\n            }\n            if(i2 == str.length && i1 == str.length){\n                return 0;\n            }\n            else if(i1 == str.length){\n                return -1;\n            }else if(i2 == str.length){\n                return 1;\n            }else return str[i1] < str[i2] ? -1 : 1;\n            \n        }\n    }\n    \n    public Integer[] createSuffixArray(char str[]){\n    \n        SuffixSort sort = new SuffixSort(str);\n        Integer suffix[] = new Integer[str.length];\n        for(int i=0; i < suffix.length; i++){\n            suffix[i] = i;\n        }\n        Arrays.sort(suffix,sort);\n        return suffix;  \n    }\n    \n    private int stringCompare(char str[],char subString[],int pos){\n        int i=0;\n        while(pos < str.length && i < subString.length && str[pos] == subString[i]){\n            pos++;\n            i++;\n        }\n        if(i == subString.length){\n            return 0;\n        }\n        if(pos == str.length){\n            return -1;\n        }\n        return str[pos] < subString[i] ? -1 : 1;  \n    }\n    \n    public int subStringSearch(char str[],char subString[], Integer suffix[]){\n        int low =0;\n        int high = suffix.length-1;\n        while(low <= high){\n            int mid = (low + high)/2;\n            int result = stringCompare(str, subString, suffix[mid]);\n            if(result == 0){\n                return suffix[mid];\n            }\n            if(result > 0){\n                high = mid-1;\n            }else{\n                low = mid+1;\n            }\n        }\n        return -1;\n    }\n    \n    public static void main(String args[]){\n        SuffixArray suffix = new SuffixArray();\n        String str = \"missisippi\";\n        Integer result[] = suffix.createSuffixArray(str.toCharArray());\n        System.out.print(suffix.subStringSearch(str.toCharArray(), \"sippi\".toCharArray(), result));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/suffixprefix/SuffixTree.java",
    "content": "package com.interview.suffixprefix;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 06/01/2015\n * @author tusroy\n * \n * Construct suffix tree using Ukkonen's algorithm\n * \n * Solution\n * Rule 1: For phase i+1 if S[j..i] ends at last character of leaf edge then add S[i+1] at \n * the end.\n * Rule 2: For phase i+1 if S[j..i] ends somewhere in middle of edge and next character is\n * not S[i+1] then a new leaf edge with label S[i+1] should be created\n * Rule 3: For phase i+1 if S[j..i] ends somewhere in middle of edge and next character is\n * S[i+1] then do nothing(resulting in implicit tree)\n * \n * Suffix Link:\n * For every node with label x@ where x is a single character and @ is possibly empty substring\n * there is another node with label x. This node is suffix link of first node. If @ is\n * empty then suffix link is root.\n * \n * Trick1\n * Skip/Count trick\n * While traveling down if number of characters on edge is less than number of characters\n * to traverse then skip directly to the end of the edge. If number of characters on label\n * is more than number of characters to traverse then go directly to that character\n * we care about.\n * \n * Edge-label compression\n * Instead of storing actual characters on the path store start and end indices on the \n * path.\n * \n * Trick2 - Stop process as soon as you hit rule 3. Rule 3 is show stopper\n * \n * Trick3 - Keep a global end on leaf to do rule 1 extension.\n * \n * Active point - It is the point from which traversal starts for next extension or next phase.\n * Active point always starts from root. Other extension will get active point set up\n * correctly by last extension.\n * \n * Active node - Node from which active point will start\n * Active Edge - It is used to choose the edge from active node. It has index of character. \n * Active Length - How far to go on active edge.\n * \n * Active point rules\n * 1) If rule 3 extension is applied then active length will increment by 1 if active length is not greater then length of path on edge.\n * 2) If rule 3 extension is applied and if active length gets greater than length path of edge then change active node, active edge and active length\n * 3) If active length is 0 then always start looking for the character from root.\n * 4) If rule 2 extension is applied and if active node is root then active edge is active edge + 1 and active length is active lenght -1\n * 5) If rule 2 extension is applied and if active node is not root then follow suffix link and make active node as suffix link and do no change \n * anything.\n * \n * Test cases \n * adeacdade\n * abcabxabcd\n * abcdefabxybcdmnabcdex\n * abcadak\n * dedododeodo\n * abcabxabcd\n * mississippi\n * banana\n * ooooooooo\n * \n * References\n * http://web.stanford.edu/~mjkay/gusfield.pdf\n * http://www.geeksforgeeks.org/ukkonens-suffix-tree-construction-part-6/\n * https://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf\n * https://gist.github.com/axefrog/2373868\n */\npublic class SuffixTree {\n\n    public static void main(String args[]){\n        SuffixTree st = new SuffixTree(\"mississippi\".toCharArray());\n        st.build();\n        st.dfsTraversal();\n        System.out.println(st.validate());\n    }\n    \n    private SuffixNode root;\n    private Active active;\n    private int remainingSuffixCount;\n    private End end;\n    private char input[];\n    private static char UNIQUE_CHAR = '$';\n    \n    public SuffixTree(char input[]){\n        this.input = new char[input.length+1];\n        for(int i=0; i < input.length; i++){\n            this.input[i] = input[i];\n        }\n        this.input[input.length] = UNIQUE_CHAR;\n    }\n    \n    public void build(){\n        root = SuffixNode.createNode(1, new End(0));\n        root.index = -1;\n        active = new Active(root);\n        this.end = new End(-1);\n        //loop through string to start new phase\n        for(int i=0; i < input.length; i++){\n            startPhase(i);\n        }\n\n        if (remainingSuffixCount != 0) {\n            System.out.print(\"Something wrong happened\");\n        }\n        //finally walk the tree again and set up the index.\n        setIndexUsingDfs(root, 0, input.length);\n    }\n    \n    private void startPhase(int i){\n        //set lastCreatedInternalNode to null before start of every phase.\n        SuffixNode lastCreatedInternalNode = null;\n        //global end for leaf. Does rule 1 extension as per trick 3 by incrementing end.\n        end.end++;\n        \n        //these many suffixes need to be created.\n        remainingSuffixCount++;\n        while(remainingSuffixCount > 0){\n            //if active length is 0 then look for current character from root.\n            if(active.activeLength == 0){\n                //if current character from root is not null then increase active length by 1 \n                //and break out of while loop. This is rule 3 extension and trick 2 (show stopper)\n                if(selectNode(i) != null){\n                    active.activeEdge = selectNode(i).start;\n                    active.activeLength++;\n                    break;\n                } //create a new leaf node with current character from leaf. This is rule 2 extension.\n                else {\n                    root.child[input[i]] = SuffixNode.createNode(i, end);\n                    remainingSuffixCount--;\n                }\n            } else{\n                //if active length is not 0 means we are traversing somewhere in middle. So check if next character is same as\n                //current character. \n                try {\n                    char ch = nextChar(i);\n                    //if next character is same as current character then do a walk down. This is again a rule 3 extension and\n                    //trick 2 (show stopper).\n                    if(ch == input[i]){\n                        //if lastCreatedInternalNode is not null means rule 2 extension happened before this. Point suffix link of that node\n                        //to selected node using active point.\n                        //TODO - Could be wrong here. Do we only do this if when walk down goes past a node or we do it every time.\n                        if(lastCreatedInternalNode != null){\n                            lastCreatedInternalNode.suffixLink = selectNode();\n                        }\n                        //walk down and update active node if required as per rules of active node update for rule 3 extension.\n                        walkDown(i);\n                        break;\n                    }\n                    else {\n                        //next character is not same as current character so create a new internal node as per \n                        //rule 2 extension.\n                        SuffixNode node = selectNode();\n                        int oldStart = node.start;\n                        node.start = node.start + active.activeLength;\n                        //create new internal node\n                        SuffixNode newInternalNode = SuffixNode.createNode(oldStart, new End(oldStart + active.activeLength - 1));\n\n                        //create new leaf node\n                        SuffixNode newLeafNode = SuffixNode.createNode(i, this.end);\n\n                        //set internal nodes child as old node and new leaf node.\n                        newInternalNode.child[input[newInternalNode.start + active.activeLength]] = node;\n                        newInternalNode.child[input[i]] = newLeafNode;\n                        newInternalNode.index = -1;\n                        active.activeNode.child[input[newInternalNode.start]] = newInternalNode;\n\n                        //if another internal node was created in last extension of this phase then suffix link of that\n                        //node will be this node.\n                        if (lastCreatedInternalNode != null) {\n                            lastCreatedInternalNode.suffixLink = newInternalNode;\n                        }\n                        //set this guy as lastCreatedInternalNode and if new internalNode is created in next extension of this phase\n                        //then point suffix of this node to that node. Meanwhile set suffix of this node to root.\n                        lastCreatedInternalNode = newInternalNode;\n                        newInternalNode.suffixLink = root;\n\n                        //if active node is not root then follow suffix link\n                        if(active.activeNode != root){\n                            active.activeNode = active.activeNode.suffixLink;\n                        }\n                        //if active node is root then increase active index by one and decrease active length by 1\n                        else{\n                            active.activeEdge = active.activeEdge  + 1;\n                            active.activeLength--;\n                        }\n                        remainingSuffixCount--;\n                    }\n           \n                } catch (EndOfPathException e) {\n\n                    //this happens when we are looking for new character from end of current path edge. Here we already have internal node so\n                    //we don't have to create new internal node. Just create a leaf node from here and move to suffix new link.\n                    SuffixNode node = selectNode();\n                    node.child[input[i]] = SuffixNode.createNode(i, end);\n                    if (lastCreatedInternalNode != null) {\n                        lastCreatedInternalNode.suffixLink = node;\n                    }\n                    lastCreatedInternalNode = node;\n                    //if active node is not root then follow suffix link\n                    if(active.activeNode != root){\n                        active.activeNode = active.activeNode.suffixLink;\n                    }\n                    //if active node is root then increase active index by one and decrease active length by 1\n                    else{\n                        active.activeEdge = active.activeEdge + 1;\n                        active.activeLength--;\n                    }\n                    remainingSuffixCount--;\n                }\n            }\n        }\n    }\n    \n    private void walkDown(int index){\n        SuffixNode node = selectNode();\n        //active length is greater than path edge length.\n        //walk past current node so change active point.\n        //This is as per rules of walk down for rule 3 extension.\n        if(diff(node) < active.activeLength){\n            active.activeNode = node;\n            active.activeLength = active.activeLength - diff(node);\n            active.activeEdge = node.child[input[index]].start;\n        }else{\n            active.activeLength++;\n        }\n    }\n    \n    //find next character to be compared to current phase character.\n    private char nextChar(int i) throws EndOfPathException{\n        SuffixNode node = selectNode();\n        if(diff(node) >= active.activeLength){\n            return input[active.activeNode.child[input[active.activeEdge]].start + active.activeLength];\n        }\n        if(diff(node) + 1 == active.activeLength ){\n            if(node.child[input[i]] != null){\n                return input[i];\n            }\n        }\n        else{\n            active.activeNode = node;\n            active.activeLength = active.activeLength - diff(node) -1;\n            active.activeEdge = active.activeEdge + diff(node)  +1;\n            return nextChar(i);\n        }\n        \n        throw new EndOfPathException();\n    }\n    \n    private static class EndOfPathException extends Exception{\n        \n    }\n    \n    private SuffixNode selectNode(){\n        return active.activeNode.child[input[active.activeEdge]];\n    }\n    \n    private SuffixNode selectNode(int index){\n        return active.activeNode.child[input[index]];\n    }\n    \n    \n    private int diff(SuffixNode node){\n        return node.end.end - node.start;\n    }\n  \n    private void setIndexUsingDfs(SuffixNode root,int val, int size){\n        if(root == null){\n            return;\n        }\n        \n        val += root.end.end - root.start + 1;\n        if(root.index != -1){\n            root.index = size - val;\n            return;\n        }\n        \n        for(SuffixNode node : root.child){\n            setIndexUsingDfs(node, val, size);\n        }\n    }\n    \n    /**\n     * Do a DFS traversal of the tree.\n     */\n    public void dfsTraversal(){\n        List<Character> result = new ArrayList<>();\n        for(SuffixNode node : root.child){\n            dfsTraversal(node, result);\n        }\n    }\n    \n    private void dfsTraversal(SuffixNode root, List<Character> result){\n        if(root == null){\n            return;\n        }\n        if(root.index != -1){\n            for(int i=root.start; i <= root.end.end; i++){\n                result.add(input[i]);\n            }\n            result.stream().forEach(System.out::print);\n            System.out.println(\" \" + root.index);\n            for(int i=root.start; i <= root.end.end; i++){\n                result.remove(result.size()-1);\n            }\n            return;\n        }\n        \n        for(int i=root.start; i <= root.end.end; i++){\n            result.add(input[i]);\n        }\n        \n        for(SuffixNode node : root.child){\n            dfsTraversal(node, result);\n        }\n        \n        for(int i=root.start; i <= root.end.end; i++){\n            result.remove(result.size()-1);\n        }\n       \n    }\n    \n    /**\n     * Do validation of the tree by comparing all suffixes and their index at leaf node.\n     */\n    private boolean validate(SuffixNode root, char[] input, int index, int curr){\n        if(root == null){\n            System.out.println(\"Failed at \" + curr + \" for index \" + index);\n            return false;\n        }\n        \n        if(root.index != -1){\n            if(root.index != index){\n                System.out.println(\"Index not same. Failed at \" + curr + \" for index \" + index);\n                return false;        \n            }else{\n                return true;\n            }\n        }\n        if(curr >= input.length){\n            System.out.println(\"Index not same. Failed at \" + curr + \" for index \" + index);\n            return false;        \n        }\n        \n        SuffixNode node = root.child[input[curr]];\n        if(node == null){\n            System.out.println(\"Failed at \" + curr + \" for index \" + index);\n            return false;\n        }\n        int j = 0;\n        for(int i=node.start ; i <= node.end.end; i++){\n            if(input[curr+j] != input[i] ){\n                System.out.println(\"Mismatch found \" + input[curr+j] + \" \" + input[i]);\n                return false;\n            }\n            j++;\n        }\n        curr += node.end.end - node.start + 1;\n        return validate(node, input, index, curr);\n    }\n    \n    public boolean validate(){\n        for(int i=0; i < this.input.length; i++){\n            if(!validate(this.root, this.input, i, i)){\n                System.out.println(\"Failed validation\");\n                return false;\n            }\n        }\n        return true;\n    }\n}\n\nclass SuffixNode{\n    \n    private SuffixNode(){\n    }\n    \n    private static final int TOTAL = 256;\n    SuffixNode[] child = new SuffixNode[TOTAL];\n    \n    int start;\n    End end;\n    int index;\n    \n    SuffixNode suffixLink;\n    \n    public static SuffixNode createNode(int start, End end){\n        SuffixNode node = new SuffixNode();\n        node.start = start;\n        node.end = end;\n        return node;\n    }\n\n    @Override\n    public String toString() {\n        StringBuffer buffer = new StringBuffer();\n        int i=0;\n        for(SuffixNode node : child){\n            if(node != null){\n                buffer.append((char)i + \" \");\n            }\n            i++;\n        }\n        return \"SuffixNode [start=\" + start + \"]\" + \" \" + buffer.toString();\n    }\n }\n\nclass End{\n    public End(int end){\n        this.end = end;\n    }\n    int end;\n}\n\nclass Active{\n    Active(SuffixNode node){\n        activeLength = 0;\n        activeNode = node;\n        activeEdge = -1;\n    }\n    \n    @Override\n    public String toString() {\n        \n        return \"Active [activeNode=\" + activeNode + \", activeIndex=\"\n                + activeEdge + \", activeLength=\" + activeLength + \"]\";\n    }\n\n    SuffixNode activeNode;\n    int activeEdge;\n    int activeLength;\n}"
  },
  {
    "path": "src/com/interview/suffixprefix/TernaryTree.java",
    "content": "package com.interview.suffixprefix;\n\n/**\n * http://www.geeksforgeeks.org/ternary-search-tree/\n */\npublic class TernaryTree {\n\n    private Node root = null;\n    \n    class Node{\n        char data;\n        boolean isLeaf;\n        Node left, right, eq;\n    }\n    \n    public void insert(String data){\n        Node root = insert(this.root,data,0);\n        this.root = root;\n    }\n    \n    public boolean search(String data){\n        return search(root,data,0);\n    }\n    \n    private boolean search(Node root,String data,int pos){\n        if(pos == data.length()){\n            return true;\n        }\n        if(root == null){\n            return false;\n        }\n        if(root.data == data.charAt(pos)){\n            boolean result = search(root.eq,data,pos+1);\n            if(pos == data.length() -1){\n                return result && root.isLeaf;\n            }\n            return result;\n        }else if(root.data < data.charAt(pos)){\n            return search(root.right,data,pos);\n        }else{\n            return search(root.left,data,pos);\n        }\n    }\n    private Node insert(Node root,String data,int pos){\n        if(pos == data.length()){\n            return root;\n        }\n        if(root == null){\n            root = new Node();\n            root.data = data.charAt(pos);\n            root.eq = insert(root.eq,data,pos+1);\n            if(pos == (data.length()-1)){\n                root.isLeaf = true;\n            }\n        }else{\n            if(root.data == data.charAt(pos)){\n                root.eq = insert(root.eq,data,pos+1);\n                if(pos == (data.length()-1)){\n                    root.isLeaf = true;\n                }\n            }\n            else if(root.data < data.charAt(pos)){\n                root.right = insert(root.right,data,pos);\n            }else{\n                root.left = insert(root.left,data,pos);\n            }\n        }\n        return root;\n    }\n    \n    public static void main(String args[]){\n        TernaryTree tt = new TernaryTree();\n        tt.insert(\"cute\");\n        tt.insert(\"as\");\n        tt.insert(\"at\");\n        tt.insert(\"cut\");\n        tt.insert(\"cup\");\n        tt.insert(\"time\");\n        tt.insert(\"tax\");\n        tt.insert(\"bat\");\n        System.out.println(tt.search(\"cute\"));\n        System.out.println(tt.search(\"cut\"));\n        System.out.println(tt.search(\"tax\"));\n        System.out.println(tt.search(\"as\"));\n        System.out.println(tt.search(\"abat\"));\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/suffixprefix/Trie.java",
    "content": "package com.interview.suffixprefix;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Date 04/25/2016\n * @author Tushar Roy\n *\n * Insert/delete/search into trie data structure\n *\n * Reference\n * https://en.wikipedia.org/wiki/Trie\n */\npublic class Trie {\n\n    private class TrieNode {\n        Map<Character, TrieNode> children;\n        boolean endOfWord;\n        public TrieNode() {\n            children = new HashMap<>();\n            endOfWord = false;\n        }\n    }\n\n    private final TrieNode root;\n    public Trie() {\n        root = new TrieNode();\n    }\n\n    /**\n     * Iterative implementation of insert into trie\n     */\n    public void insert(String word) {\n        TrieNode current = root;\n        for (int i = 0; i < word.length(); i++) {\n            char ch = word.charAt(i);\n            TrieNode node = current.children.get(ch);\n            if (node == null) {\n                node = new TrieNode();\n                current.children.put(ch, node);\n            }\n            current = node;\n        }\n        //mark the current nodes endOfWord as true\n        current.endOfWord = true;\n    }\n\n    /**\n     * Recursive implementation of insert into trie\n     */\n    public void insertRecursive(String word) {\n        insertRecursive(root, word, 0);\n    }\n\n\n    private void insertRecursive(TrieNode current, String word, int index) {\n        if (index == word.length()) {\n            //if end of word is reached then mark endOfWord as true on current node\n            current.endOfWord = true;\n            return;\n        }\n        char ch = word.charAt(index);\n        TrieNode node = current.children.get(ch);\n\n        //if node does not exists in map then create one and put it into map\n        if (node == null) {\n            node = new TrieNode();\n            current.children.put(ch, node);\n        }\n        insertRecursive(node, word, index + 1);\n    }\n\n    /**\n     * Iterative implementation of search into trie.\n     */\n    public boolean search(String word) {\n        TrieNode current = root;\n        for (int i = 0; i < word.length(); i++) {\n            char ch = word.charAt(i);\n            TrieNode node = current.children.get(ch);\n            //if node does not exist for given char then return false\n            if (node == null) {\n                return false;\n            }\n            current = node;\n        }\n        //return true of current's endOfWord is true else return false.\n        return current.endOfWord;\n    }\n\n    /**\n     * Recursive implementation of search into trie.\n     */\n    public boolean searchRecursive(String word) {\n        return searchRecursive(root, word, 0);\n    }\n    private boolean searchRecursive(TrieNode current, String word, int index) {\n        if (index == word.length()) {\n            //return true of current's endOfWord is true else return false.\n            return current.endOfWord;\n        }\n        char ch = word.charAt(index);\n        TrieNode node = current.children.get(ch);\n        //if node does not exist for given char then return false\n        if (node == null) {\n            return false;\n        }\n        return searchRecursive(node, word, index + 1);\n    }\n\n    /**\n     * Delete word from trie.\n     */\n    public void delete(String word) {\n        delete(root, word, 0);\n    }\n\n    /**\n     * Returns true if parent should delete the mapping\n     */\n    private boolean delete(TrieNode current, String word, int index) {\n        if (index == word.length()) {\n            //when end of word is reached only delete if currrent.endOfWord is true.\n            if (!current.endOfWord) {\n                return false;\n            }\n            current.endOfWord = false;\n            //if current has no other mapping then return true\n            return current.children.size() == 0;\n        }\n        char ch = word.charAt(index);\n        TrieNode node = current.children.get(ch);\n        if (node == null) {\n            return false;\n        }\n        boolean shouldDeleteCurrentNode = delete(node, word, index + 1);\n\n        //if true is returned then delete the mapping of character and trienode reference from map.\n        if (shouldDeleteCurrentNode) {\n            current.children.remove(ch);\n            //return true if no mappings are left in the map.\n            return current.children.size() == 0;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/AVLTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 07/04/2014\n * @author tusroy\n *\n * Video link - https://youtu.be/rbg7Qf8GkQ4\n *\n * Write a program to insert into an AVL tree.\n * \n * AVL tree is self balancing binary tree. Difference of height of left or right subtree\n * cannot be greater than one.\n * \n * There are four different use cases to insert into AVL tree\n * left left - needs ones right rotation\n * left right - needs one left and one right rotation\n * right left - needs one right and one left rotation\n * right right - needs one left rotation\n * \n * Follow rotation rules to keep tree balanced.\n * \n * At every node we will also keep height of the tree so that we don't\n * have to recalculate values again.\n * \n * Runtime complexity to insert into AVL tree is O(logn).\n * \n * References \n * http://en.wikipedia.org/wiki/AVL_tree\n * http://www.geeksforgeeks.org/avl-tree-set-1-insertion/\n * \n */\npublic class AVLTree {\n\n    private Node leftRotate(Node root){\n        Node newRoot = root.right;\n        root.right = root.right.left;\n        newRoot.left = root;\n        root.height = setHeight(root);\n        root.size = setSize(root);\n        newRoot.height = setHeight(newRoot);\n        newRoot.size = setSize(newRoot);\n        return newRoot;\n    }\n    \n    private Node rightRotate(Node root){\n        Node newRoot = root.left;\n        root.left = root.left.right;\n        newRoot.right = root;\n        root.height = setHeight(root);\n        root.size = setSize(root);\n        newRoot.height = setHeight(newRoot);\n        newRoot.size = setSize(newRoot);\n        return newRoot;\n    }\n\n    private int setHeight(Node root){\n        if(root == null){\n            return 0;\n        }\n        return 1 + Math.max((root.left != null ? root.left.height : 0), (root.right != null ? root.right.height : 0));\n    }\n    \n    private int height(Node root){\n        if(root == null){\n            return 0;\n        }else {\n            return root.height;\n        }\n    }\n    \n    private int setSize(Node root){\n        if(root == null){\n            return 0;\n        }\n        return 1 + Math.max((root.left != null ? root.left.size : 0), (root.right != null ? root.right.size : 0));\n    }\n    \n    public Node insert(Node root, int data){\n        if(root == null){\n            return Node.newNode(data);\n        }\n        if(root.data <= data){\n            root.right = insert(root.right,data);\n        }\n        else{\n            root.left = insert(root.left,data);\n        }\n        int balance = balance(root.left, root.right);\n        if(balance > 1){\n            if(height(root.left.left) >= height(root.left.right)){\n                root = rightRotate(root);\n            }else{\n                root.left = leftRotate(root.left);\n                root = rightRotate(root);\n            }\n        }else if(balance < -1){\n            if(height(root.right.right) >= height(root.right.left)){\n                root = leftRotate(root);\n            }else{\n                root.right = rightRotate(root.right);\n                root = leftRotate(root);\n            }\n        }\n        else{\n            root.height = setHeight(root);\n            root.size = setSize(root);\n        }\n        return root;\n    }\n    \n    private int balance(Node rootLeft, Node rootRight){\n        return height(rootLeft) - height(rootRight);\n    }\n    \n    public static void main(String args[]){\n        AVLTree avlTree = new AVLTree();\n        Node root = null;\n        root = avlTree.insert(root, -10);\n        root = avlTree.insert(root, 2);\n        root = avlTree.insert(root, 13);\n        root = avlTree.insert(root, -13);\n        root = avlTree.insert(root, -15);\n        root = avlTree.insert(root, 15);\n        root = avlTree.insert(root, 17);\n        root = avlTree.insert(root, 20);\n        \n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(root);\n        System.out.println();\n        tt.preOrder(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/AddGreaterValueNodeToEveryNode.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/add-greater-values-every-node-given-bst/\n * Test cases:\n * Empty tree\n * One node tree\n * Two node tree\n */\n\nclass IntegerRef{\n    int val;\n}\n\npublic class AddGreaterValueNodeToEveryNode {\n\n    public void add(Node root,IntegerRef ref){\n        if(root == null){\n            return ;\n        }\n        add(root.right,ref);\n        root.data += ref.val;\n        ref.val = root.data;\n        add(root.left,ref);\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(5, root);\n        root = bt.addNode(20, root);\n        root = bt.addNode(15, root);\n        root = bt.addNode(25, root);\n        AddGreaterValueNodeToEveryNode agv = new AddGreaterValueNodeToEveryNode();\n        IntegerRef ir = new IntegerRef();\n        ir.val = 0;\n        agv.add(root, ir);\n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ArbitaryTreeToChildSumTree.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/convert-an-arbitrary-binary-tree-to-a-tree-that-holds-children-sum-property/\n * Only operation you can do is increase data on the node. No decrement of data\n * Test case\n * Root greater than children\n * Root less than children\n * Root equal to children\n */\npublic class ArbitaryTreeToChildSumTree {\n\n    public void childSumTree(Node root){\n        toChildSumTree(root);\n    }\n    \n    private void incrementChild(Node root,int increment){\n        if(root == null || (root.left ==null && root.right == null)){\n            return;\n        }\n        if(root.left != null){\n            root.left.data = root.left.data + increment;\n            incrementChild(root.left,increment);\n        }else{\n            root.right.data = root.right.data + increment;\n            incrementChild(root.right,increment);\n        }\n    }\n    \n    private int toChildSumTree(Node root){\n        if(root == null){\n            return 0;\n        }\n        \n        if(root.left == null && root.right == null){\n            return root.data;\n        }\n        \n        int sum1 = toChildSumTree(root.left);\n        int sum2 = toChildSumTree(root.right);\n        if(root.data < sum1 + sum2){\n            root.data = sum1 + sum2;\n        }else if(root.data > sum1 + sum2){\n            incrementChild(root,root.data - sum1 - sum2);\n        }\n        return root.data;\n    }\n    \n    public static void main(String args[]){\n        ArbitaryTreeToChildSumTree att = new ArbitaryTreeToChildSumTree();\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(-1, head);\n        att.childSumTree(head);\n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(head);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/tree/BSTOneChildPreOrderTraversal.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/check-if-each-internal-node-of-a-bst-has-exactly-one-child/\n */\npublic class BSTOneChildPreOrderTraversal {\n\n    public boolean isBST(int input[]){\n        int max = Integer.MAX_VALUE;\n        int min = Integer.MIN_VALUE;\n        for(int i = 0; i < input.length-1; i++){\n            if(input[i] > min && input[i] < max){\n                if(input[i+1] < input[i]){\n                    max = input[i];\n                }else{\n                    min = input[i];\n                }\n            }else{\n                return false;\n            }\n        }\n        if(input[input.length-1] < max && input[input.length-1] > min){\n            return true;\n        }else{\n            return false;\n        }\n    }\n    \n    public static void main(String args[]){\n        int input[] = {20,10,14,15,17};\n        BSTOneChildPreOrderTraversal boc = new BSTOneChildPreOrderTraversal();\n        System.out.println(boc.isBST(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/BSTSearch.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 04/11/2015\n * @author tusroy\n * \n * Youtube link - https://youtu.be/zm83jPHZ-jA\n * \n * Given a binary search tree and a key, return node which has data as this key or return\n * null if no node has data as key.\n * \n * Solution \n * Since its BST for every node check if root.data is key and if not go either left or\n * right depending on if root.data is greater or less than key\n * \n * Time complexity is O(n) for non balanced BST\n * Time complexity is O(logn) for balanced BST\n * \n * Test cases:\n * 1) null tree\n * 2) Tree with one node and key is that node\n * 3) Tree with many nodes and key does not exist\n * 4) Tree with many nodes and key exists\n */\npublic class BSTSearch {\n    \n    public Node search(Node root, int key){\n        if(root == null){\n            return null;\n        }\n        if(root.data == key){\n            return root;\n        }else if(root.data < key){\n            return search(root.right, key);\n        }else{\n            return search(root.left, key);\n        }\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(20, root);\n        root = bt.addNode(-10, root);\n        root = bt.addNode(15, root);\n        root = bt.addNode(0, root);\n        root = bt.addNode(21, root);\n        root = bt.addNode(-1, root);\n        BSTSearch bstSearch = new BSTSearch();\n        Node result = bstSearch.search(root, 21);\n        assert result.data == 21;\n        \n        result = bstSearch.search(root, -1);\n        assert result.data == 21;\n        \n        result = bstSearch.search(root, 11);\n        assert result == null;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/BTree.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/b-tree-set-1-insert-2/\n * http://www.geeksforgeeks.org/b-tree-set-1-introduction-2/\n */\npublic class BTree {\n    private BTreeNode root = null;\n    private static int T = 2;\n    public void insert(int data){\n        if(root == null){\n            root = BTreeNode.newNode(data);\n            return;\n        }\n        SplitResult sr = insert(root,data);\n        if(sr != null){\n            BTreeNode newRoot = BTreeNode.newNode();\n            newRoot.n = 1;\n            newRoot.isLeaf = false;\n            newRoot.keys[0] = sr.c;\n            newRoot.child[0] = sr.r1;\n            newRoot.child[1] = sr.r2;\n            root = newRoot;\n        }\n    }\n    \n    public boolean search(int data){\n        return search(root,data);\n    }\n    \n    public boolean search(BTreeNode root, int data){\n        int i =0;\n        while(i < root.n && root.keys[i] < data){\n            i++;\n        }\n        if(i < root.n && root.keys[i] == data){\n            return true;\n        }\n        if(root.isLeaf){\n            return false;\n        }\n        return search(root.child[i],data);\n    }\n    \n    private SplitResult insert(BTreeNode root,int data){\n        if(root.isLeaf){\n            if(!root.isFull()){\n                root.insertKey(data, null, null);\n                return null;\n            }else{\n                SplitResult sr = splitNode(root,data,null,null);\n                return sr;\n            }\n        }else{\n            int i=0;\n            for(; i < root.n; i++){\n                if(data <= root.keys[i]){\n                    SplitResult sr = insert(root.child[i],data);\n                    if(sr == null){\n                        return null;\n                    }else{\n                        if(!root.isFull()){\n                            root.insertKey(sr.c, sr.r1, sr.r2);\n                            return null;\n                        }else{\n                            SplitResult sr1 = splitNode(root,sr.c,sr.r1,sr.r2);\n                            return sr1;\n                        }\n                    }\n                }\n            }\n            if(i == root.n){\n                SplitResult sr = insert(root.child[i],data);\n                if(sr == null){\n                    return null;\n                }else{\n                    if(!root.isFull()){\n                        root.insertKey(sr.c, sr.r1, sr.r2);\n                        return null;\n                    }else{\n                        SplitResult sr1 = splitNode(root,sr.c,sr.r1,sr.r2);\n                        return sr1;\n                    }\n                }\n            }\n        }\n        return null;\n    }\n    \n    private SplitResult splitNode(BTreeNode node,int data, BTreeNode nr1, BTreeNode nr2){\n        int c = node.keys[node.n/2];\n        BTreeNode r1 = BTreeNode.newNode();\n        BTreeNode r2 = BTreeNode.newNode();\n        r1.n = node.n/2;\n        r2.n = node.n - node.n/2-1;\n        if(!node.isLeaf){\n            r1.isLeaf = false;\n            r2.isLeaf = false;\n        }\n        int i=0;\n        for(; i < node.n/2; i++){\n            r1.keys[i] = node.keys[i];\n            r1.child[i] = node.child[i];\n        }\n        r1.child[i] = node.child[i];\n        i = node.n/2 + 1;\n        int j=0;\n        for(;i < node.n; i++,j++){\n            r2.keys[j] = node.keys[i];\n            r2.child[j] = node.child[i];\n        }\n        r2.child[j] = node.child[i];\n        if(data < c){\n            r1.insertKey(data, nr1, nr2);\n        }else{\n            r2.insertKey(data, nr1, nr2);\n        }\n        SplitResult sr = new SplitResult();\n        sr.c = c;\n        sr.r1 = r1;\n        sr.r2 = r2;\n        return sr;\n    }\n    \n    class SplitResult{\n        BTreeNode r1;\n        BTreeNode r2;\n        int c;\n    }\n    \n    public void traverse(){\n        traverse(root);\n    }\n    \n    private void traverse(BTreeNode root){\n        for(int i=0; i < root.n; i++){\n            if(!root.isLeaf){\n                traverse(root.child[i]);\n            }\n            System.out.print(root.keys[i] + \" \");\n        }\n        if(!root.isLeaf){\n            traverse(root.child[root.n]);\n        }\n    }\n    \n    static class BTreeNode{\n        int n ;\n        BTreeNode[] child = new BTreeNode[2*T];\n        int keys[] = new int[2*T-1];\n        boolean isLeaf;\n        \n        public void insertKey(int data,BTreeNode r1,BTreeNode r2){\n            int i = n-1;\n            while(i >=0 && data < keys[i]){\n                keys[i+1] = keys[i];\n                i--;\n            }\n            keys[i+1] = data;\n            int j = n;\n            while(j > i+1){\n                child[j+1] = child[j];\n                j--;\n            }\n            child[j] = r1;\n            child[j+1] = r2;\n            n++;\n        }\n        \n        public static BTreeNode newNode(int data){\n            BTreeNode node = new BTreeNode();\n            node.keys[0] = data;\n            node.isLeaf = true;\n            node.n = 1;\n            return node;\n        }\n        \n        public static BTreeNode newNode(){\n            BTreeNode node = new BTreeNode();\n            node.isLeaf = true;\n            node.n = 0;\n            return node;\n        }\n        \n        public boolean isFull(){\n            return 2*T - 1 == n;\n        }\n    }\n    \n    public static void main(String args[]){\n        BTree bTree = new BTree();\n        bTree.insert(5);\n        bTree.insert(4);\n        bTree.insert(3);\n        bTree.insert(2);\n        bTree.insert(1);\n        bTree.insert(6);\n        bTree.insert(11);\n        bTree.insert(13);\n        bTree.insert(8);\n        bTree.insert(7);\n        bTree.insert(10);\n        bTree.insert(9);\n        bTree.insert(28);\n        bTree.insert(22);\n        bTree.insert(12);\n        bTree.insert(18);\n        bTree.insert(16);\n        bTree.traverse();\n        System.out.print(bTree.search(28));\n        System.out.print(bTree.search(11));\n        System.out.print(bTree.search(5));\n        System.out.print(bTree.search(21));\n        System.out.print(bTree.search(3));\n        System.out.print(bTree.search(4));\n        System.out.print(bTree.search(14));\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/tree/BinaryTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 07/07/2014 \n * @author tusroy\n * \n * Youtube link - https://youtu.be/bmaeYtlO2OE\n * Youtube link - https://youtu.be/_SiwrPXG9-g\n * Youtube link - https://youtu.be/NA8B84DZYSA\n *\n */\nclass NodeRef{\n    Node node;\n}\n\nenum Color{\n    RED,\n    BLACK\n}\n\nclass Node{\n    Node left;\n    Node right;\n    Node next;\n    int data;\n    int lis;\n    int height;\n    int size;\n    Color color;\n    \n    public static Node newNode(int data){\n        Node n = new Node();\n        n.left = null;\n        n.right = null;\n        n.data = data;\n        n.lis = -1;\n        n.height = 1;\n        n.size = 1;\n        n.color = Color.RED;\n        return n;\n    }\n}\n\npublic class BinaryTree {\n    public Node addNode(int data, Node head){\n        Node tempHead = head;\n        Node n = Node.newNode(data);\n        if(head == null){\n            head = n;\n            return head;\n        }\n        Node prev = null;\n        while(head != null){\n            prev = head;\n            if(head.data < data){\n                head = head.right;\n            }else{\n                head = head.left;\n            }\n        }\n        if(prev.data < data){\n            prev.right = n;\n        }else{\n            prev.left = n;\n        }\n        return tempHead;\n    }\n    \n    class IntegerRef{\n        int height;\n    }\n    \n    public int height(Node root){\n        if(root == null){\n            return 0;\n        }\n        int leftHeight  = height(root.left);\n        int rightHeight = height(root.right);\n        return Math.max(leftHeight, rightHeight) + 1;\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(-1, head);\n        head = bt.addNode(21, head);\n        System.out.println(bt.height(head));\n        \n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/BinaryTreeFromParentRepresentation.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 11/01/2015\n * @author Tushar Roy\n *\n * Given an array reprsentation of binary tree where index is data while value at index is\n * parent create the binary tree. Value of -1 indicates root node.\n * \n * References:\n * http://www.geeksforgeeks.org/construct-a-binary-tree-from-parent-array-representation/\n */\npublic class BinaryTreeFromParentRepresentation {\n\n    public Node create(int input[]) {\n        Node t[] = new Node[input.length];\n\n        for(int i = 0; i < input.length; i++) {\n            t[i] = new Node();\n            t[i].data = i;\n        }\n\n        Node root = null;\n        for(int i = 0; i < input.length; i++) {\n            int parentIndex = input[i];\n            if(parentIndex == -1) {\n                root = t[i];\n                continue;\n            }\n            Node parent = t[parentIndex];\n            if(parent.left == null) {\n                parent.left = t[i];\n            } else {\n                parent.right = t[i];\n            }\n        }\n        return root;\n     }\n\n     public static void main(String args[]) {\n         BinaryTreeFromParentRepresentation btpp = new BinaryTreeFromParentRepresentation();\n         int input[] =  {1, 5, 5, 2, 2, -1, 3};\n         Node root = btpp.create(input);\n         TreeTraversals tt = new TreeTraversals();\n         tt.inOrder(root);\n         System.out.println();\n         tt.preOrder(root);\n     }\n}\n\n"
  },
  {
    "path": "src/com/interview/tree/BinaryTreeMaximumPathSum.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 03/22/2016\n * @author Tushar Roy\n *\n * Given a binary tree, find the maximum path sum. For this problem, a path is defined as any sequence of nodes\n * from some starting node to any node in the tree along the parent-child connections.\n * \n * Time complexity O(n)\n * Space complexity depends on depth of tree.\n *\n * https://leetcode.com/problems/binary-tree-maximum-path-sum/\n */\npublic class BinaryTreeMaximumPathSum {\n    int max = 0;\n\n    public int maxPathSum(Node root) {\n        max = Integer.MIN_VALUE;\n        maxPathSumUtil(root);\n        return max;\n    }\n\n    private int maxPathSumUtil(Node root) {\n        if (root == null) {\n            return 0;\n        }\n        int left = maxPathSumUtil(root.left);\n        int right = maxPathSumUtil(root.right);\n        if (left < 0) {\n            left = 0;\n        }\n        if (right < 0) {\n            right = 0;\n        }\n        max = Math.max(max, root.data + left + right);\n        return root.data + Math.max(left, right);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/BinaryTreeToCircularLinkList.java",
    "content": "package com.interview.tree;\n\n/**\n * http://cslibrary.stanford.edu/109/TreeListRecursion.html\n * Test cases\n * Null tree\n * \n */\npublic class BinaryTreeToCircularLinkList {\n\n    public Node convert(Node root){\n        if(root == null){\n            return null;\n        }\n        \n        if(root.left == null && root.right == null){\n            root.left = root;\n            root.right = root;\n            return root;\n        }\n        \n        Node left = convert(root.left);\n        Node right = convert(root.right);\n    \n        root.left = root;\n        root.right = root;\n        \n        left = join(left,root);\n        left = join(left,right);\n        return left;\n    }\n    \n    private Node join(Node r1, Node r2){\n\n        if(r1 == null){\n            return r2;\n        }\n        if(r2 == null){\n            return r1;\n        }\n        Node t1 = r2.left;\n        \n        r1.left.right = r2;\n        r2.left = r1.left;\n        r1.left = t1;\n        t1.right = r1;\n        return r1;\n    }\n    \n    private void print(Node root){\n        Node temp = root;\n        do{\n            System.out.println(temp.data);\n            temp = temp.right;\n        }while(temp != root);\n\n        System.out.println();\n        do{\n            System.out.println(temp.data);\n            temp = temp.left;\n        }while(temp != root);\n    }\n    \n    public static void main(String args[]){\n        BinaryTreeToCircularLinkList btc = new BinaryTreeToCircularLinkList();\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(3, root);\n        root = bt.addNode(-1, root);\n        root = bt.addNode(8, root);\n        root = bt.addNode(-6, root);\n        root = bt.addNode(13, root);\n        root = btc.convert(root);\n        btc.print(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/BinaryTreeToDoubleLinkList.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/convert-given-binary-tree-doubly-linked-list-set-3/\n */\npublic class BinaryTreeToDoubleLinkList {\n\n    public void toDoubleLL(Node root){\n        NodeRef prev = new NodeRef();\n        toDoubleLL(root,prev);\n    }\n    \n    private void toDoubleLL(Node root, NodeRef prev){\n        if(root == null){\n            return;\n        }\n        toDoubleLL(root.left,prev);\n        if(prev.node != null){\n            prev.node.right = root;\n            root.left = prev.node;\n            prev.node = root;\n        }else{\n            prev.node = root;\n        }\n        toDoubleLL(root.right,prev);\n    }\n    \n    public void print(Node root){\n        Node curr = null;\n        while(root != null){\n            curr = root;\n            System.out.print(root.data + \" \");\n            root = root.right;\n        }\n        System.out.println();\n        root = curr;\n        while(root != null){\n            System.out.print(root.data + \" \");\n            root = root.left;\n        }\n    }\n    \n    public static void main(String args[]){\n        BinaryTreeToDoubleLinkList btd = new BinaryTreeToDoubleLinkList();  \n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(100, head);\n        head = bt.addNode(90, head);\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(25, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(-7, head);\n        btd.toDoubleLL(head);\n        btd.print(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/BinaryTreeToSortedLinkList.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.careercup.com/question?id=6241652616200192\n * Test cases:\n * 0,1 or more nodes in the tree\n */\npublic class BinaryTreeToSortedLinkList {\n\n    public Node toSortedLinkList(Node root){\n        if(root == null){\n            return null;\n        }\n        \n        Node left = toSortedLinkList(root.left);\n        Node right = toSortedLinkList(root.right);\n        \n        root.left = null;\n        root.right = null;\n        root = merge(left,root);\n        return merge(root,right);\n    }\n    \n    private Node merge(Node head1,Node head2){\n        if(head1 == null){\n            return head2;\n        }\n        if(head2 == null){\n            return head1;\n        }\n        if(head1.data <= head2.data){\n            head1.next = merge(head1.next, head2);\n            return head1;\n        }else{\n            head2.next = merge(head1,head2.next);\n            return head2;\n        }\n    }\n    \n    private void print(Node root){\n        while(root != null){\n            System.out.print(root.data + \" \");\n            root = root.next;\n        }\n    }\n    \n    public static void main(String args[]){\n        int in[] = {-6,0,15,10,3,25,2};\n        int pre[] = {10,15,-6,0,25,3,2};\n        ConstructTreeFromInOrderPreOrder ct = new ConstructTreeFromInOrderPreOrder();\n        Node root = ct.createTree(in, pre);\n        BinaryTreeToSortedLinkList bt = new BinaryTreeToSortedLinkList();\n        root = bt.toSortedLinkList(root);\n        bt.print(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/BoundaryTraversal.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/boundary-traversal-of-binary-tree/\n * Test cases\n * All left children\n * All right children\n * Full tree\n * Complete tree\n */\npublic class BoundaryTraversal {\n\n    public void traversal(Node root){\n        //find starting point for right side\n        Node current = root;\n        while(current != null){\n            if(current.right != null && current.left != null){\n                current = current.right;\n                break;\n            }\n            current = current.left != null ? current.left : current.right;\n        }\n        printRightSide(current);\n        printLeaves(root);\n        printLeftSide(root);\n    }\n    \n    private void printRightSide(Node root){\n        if(root == null || (root.left == null && root.right == null)){\n            return;\n        }\n        System.out.println(root.data);\n        if(root.right != null){\n            printRightSide(root.right);\n        }else{\n            printRightSide(root.left);\n        }\n    }\n    \n    private void printLeftSide(Node root){\n        if(root == null || (root.left == null && root.right == null)){\n            return;\n        }\n        if(root.left != null){\n            printLeftSide(root.left);\n        }else{\n            printRightSide(root.right);\n        }\n        System.out.println(root.data);\n    }\n\n    private void printLeaves(Node root){\n        if(root == null){\n            return;\n        }\n        if(root.left == null && root.right == null){\n            System.out.println(root.data);\n        }\n        printLeaves(root.right);\n        printLeaves(root.left);\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(100, head);\n        head = bt.addNode(90, head);\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(25, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(-7, head);\n        BoundaryTraversal bd = new BoundaryTraversal();\n        bd.traversal(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ClosestValueBinaryTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target.\n * https://leetcode.com/problems/closest-binary-search-tree-value/\n */\npublic class ClosestValueBinaryTree {\n    public int closestValue(Node root, double target) {\n        int r = target > 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE;\n        return closestValueUtil(root, target, r);\n    }\n\n    private int closestValueUtil(Node root, double target, int result) {\n        if (root == null) {\n            return (int)result;\n        }\n        if (target == root.data) {\n            return root.data;\n        }\n        if (Math.abs(root.data - target) < Math.abs(result - target)) {\n            result = root.data;\n        }\n        if (target < root.data) {\n            return closestValueUtil(root.left, target, result);\n        } else {\n            return closestValueUtil(root.right, target, result);\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ConnectNodesAtSameLevel.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 03/24/2016\n * @author Tushar Roy\n *\n * Populate next pointer for each node of binary tree.\n *\n * Time complexity O(n)\n * Space complexity O(1)\n *\n * https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/\n */\npublic class ConnectNodesAtSameLevel {\n\n    public void connect(Node root) {\n        if (root == null) {\n            return;\n        }\n\n        Node firstNode = root;\n        Node prevNode = null;\n        while (firstNode != null) {\n            root = firstNode;\n            firstNode = null;\n            prevNode = null;\n            while (root != null) {\n                if (root.left != null) {\n                    if (firstNode == null) {\n                        firstNode = root.left;\n                    }\n                    if (prevNode != null) {\n                        prevNode.next = root.left;\n                    }\n                    prevNode = root.left;\n                }\n                if (root.right != null) {\n                    if (firstNode == null) {\n                        firstNode = root.right;\n                    }\n                    if (prevNode != null) {\n                        prevNode.next = root.right;\n                    }\n                    prevNode = root.right;\n                }\n                root = root.next;\n            }\n        }\n    }\n\n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(15, root);\n        root = bt.addNode(5, root);\n        root = bt.addNode(7, root);\n        root = bt.addNode(19, root);\n        root = bt.addNode(20, root);\n        root = bt.addNode(-1, root);\n        root = bt.addNode(21, root);\n        ConnectNodesAtSameLevel cns = new ConnectNodesAtSameLevel();\n\n        cns.connect(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ConstructAllBinaryTreeFromInorderTraversal.java",
    "content": "package com.interview.tree;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Date 11/07/2015\n * @author Tushar Roy\n *\n * Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.\n * Total number of binary search tree possible is Catalan number.\n *\n * https://leetcode.com/problems/unique-binary-search-trees-ii/\n */\npublic class ConstructAllBinaryTreeFromInorderTraversal {\n\n    public List<Node> generateTrees(int n) {\n        if (n == 0) {\n            return Collections.emptyList();\n        }\n        return construct(1, n);\n    }\n\n    private List<Node> construct(int start, int end) {\n        if (start > end) {\n            return Collections.singletonList(null);\n        }\n        List<Node> allTrees = new ArrayList<>();\n        for (int root = start; root <= end; root++) {\n            //get all subtrees from left and right side.\n            List<Node> allLeftSubstrees = construct(start, root - 1);\n            List<Node> allRightSubstrees = construct(root + 1, end);\n            //iterate through them in all combination and them connect them to root\n            //and add to allTrees.\n            for (Node left : allLeftSubstrees) {\n                for (Node right : allRightSubstrees) {\n                    Node node = Node.newNode(root);\n                    node.left = left;\n                    node.right = right;\n                    allTrees.add(node);\n                }\n            }\n        }\n        return allTrees;\n    }\n\n    public void printAllTrees(List<Node> allTrees) {\n        TreeTraversals tt = new TreeTraversals();\n        System.out.println(\"Total number of trees \" + allTrees.size());\n        for(Node node : allTrees) {\n            tt.inOrder(node);\n            System.out.println();\n            tt.preOrder(node);\n            System.out.print(\"\\n\\n\");\n        }\n    }\n\n    public static void main(String args[]) {\n        ConstructAllBinaryTreeFromInorderTraversal ct = new ConstructAllBinaryTreeFromInorderTraversal();\n        List<Node> allTrees = ct.generateTrees(3);\n        ct.printAllTrees(allTrees);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ConstructBSTFromPreOrderArray.java",
    "content": "package com.interview.tree;\n\nclass Index{\n    int index;\n}\n/**\n * http://www.geeksforgeeks.org/construct-bst-from-given-preorder-traversa/\n * Test case\n * empty array\n * 1,2 or more elements in the array\n */\npublic class ConstructBSTFromPreOrderArray {\n\n    public Node toBST(int preorder[]){\n        Index index = new Index();\n        return toBST(preorder,Integer.MIN_VALUE,Integer.MAX_VALUE,index);\n    }\n    \n    //stack based version\n    public Node toBSTIterative(int preorder[]){\n        return null;\n    }\n    \n    private Node toBST(int preorder[],int min, int max,Index index){\n        if(index.index >= preorder.length){\n            return null;\n        }\n        if(preorder[index.index] < min || preorder[index.index] >= max){\n            return null;\n        }\n        \n        Node node = new Node();\n        node.data = preorder[index.index];\n        index.index++;\n        node.left = toBST(preorder,min,node.data, index);\n        node.right = toBST(preorder,node.data,max,index);\n        return node;\n    }\n    \n    public static void main(String args[]){\n        int preorder[] = {10,5,1,7,40,50};\n        ConstructBSTFromPreOrderArray poa = new ConstructBSTFromPreOrderArray();\n        Node root = poa.toBST(preorder);\n        TreeTraversals tt = new TreeTraversals();\n        tt.preOrder(root);\n        System.out.println();\n        tt.inOrder(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ConstructFullTreeFromPreOrderPostOrder.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/full-and-complete-binary-tree-from-given-preorder-and-postorder-traversals/\n * Full tree is a tree with all nodes with either 0 or 2 child. Never has 1 child.\n * Test cases\n * Empty tree\n * Tree with big on left side\n * Tree with big on right side\n */\npublic class ConstructFullTreeFromPreOrderPostOrder {\n\n    public Node constructTree(int preorder[],int postorder[]){\n    \n        return constructTree(preorder, postorder, 0, postorder.length-2, 0);\n        \n    }\n    \n    private Node constructTree(int preorder[],int postorder[],int low,int high,int index){\n\n        if(low > high || index >= preorder.length-1){\n            Node node = new Node();\n            node.data = preorder[index];\n            return node;\n        }\n        \n        Node node = new Node();\n        node.data = preorder[index];\n        int i=0;\n        for(i=low; i <= high; i++){\n            if(preorder[index+1] == postorder[i]){\n                break;\n            }\n        }\n        node.left = constructTree(preorder, postorder, low, i-1, index+1);\n        node.right = constructTree(preorder, postorder, i+1, high-1, index + i-low+2);\n        return node;\n    }\n    \n    public static void main(String args[]){\n        ConstructFullTreeFromPreOrderPostOrder cft = new ConstructFullTreeFromPreOrderPostOrder();\n        int preorder[] = {1,2,3,6,7,8,9};\n        int postorder[] = {2,6,8,9,7,3,1};\n        Node root = cft.constructTree(preorder, postorder);\n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(root);\n        tt.preOrder(root);\n        tt.postOrder(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ConstructTreeFromInOrderPreOrder.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/construct-tree-from-given-inorder-and-preorder-traversal/\n * Test cases:\n * Empty tree\n * One node tree\n * All left side tree\n * All right side tree\n * Mixed tree\n * Full tree\n * complete tree\n */\npublic class ConstructTreeFromInOrderPreOrder {\n    \n    private int index = 0;\n    public Node createTree(int inorder[],int preorder[]){\n        Node result =  createTree(inorder,preorder,0,inorder.length-1);\n        index = 0;\n        return result;\n    }\n    \n    private Node createTree(int inorder[],int preorder[], int start, int end){\n        if(start > end){\n            return null;\n        }\n        int i;\n        for(i=start; i <= end; i++){\n            if(preorder[index] == inorder[i]){\n                break;\n            }\n        }\n        Node node = Node.newNode(preorder[index]);\n        index++;\n        node.left = createTree(inorder,preorder,start,i-1);\n        node.right = createTree(inorder,preorder,i+1,end);\n        return node;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ConstructTreeFromLevelOrderInOrder.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/construct-tree-inorder-level-order-traversals/\n * Test cases\n * same length of inorder and level order array\n * all elements should be same in them\n * what to do if repetition happens. This logic only works for non repeated values\n * if inorder and levelorder were represented by string how would you handle multi digits\n * e.g 1234 we don't know if it is 12 34 or 1 2 3 4 or what. Maybe use brackets\n * (12)(3)(4) to differentiate between them.\n */\npublic class ConstructTreeFromLevelOrderInOrder {\n\n    public Node constructTree(int inOrder[], int levelOrder[]){\n        return constructTree(inOrder, levelOrder,0,inOrder.length-1);\n    }\n    \n    private int[] extractArray(int inOrder[], int levelOrder[],int low, int high){\n        int result[] = new int[high - low + 1];\n        int p=0;\n        for(int i=1; i < levelOrder.length; i++){\n            int index = search(inOrder,levelOrder[i],low,high);\n            if(index != -1){\n                result[p++] = inOrder[index];\n            }\n        }\n        return result;\n    }\n    \n    private Node constructTree(int inOrder[], int levelOrder[], int low, int high){\n        if(low > high){\n            return null;\n        }\n        int lowElement = levelOrder[0];\n        Node n = Node.newNode(lowElement);\n        int index = search(inOrder,lowElement,low,high);\n        int left[] = extractArray(inOrder,levelOrder,low,index-1);\n        int right[] = extractArray(inOrder,levelOrder,index+1,high);\n        n.left = constructTree(inOrder, left, low, index-1);\n        n.right = constructTree(inOrder, right, index+1, high);\n        return n;\n    }\n    \n    private int search(int input[],int key, int low, int high){\n        if(low > high){\n            return -1;\n        }\n        int middle = (low + high)/2;\n        if(input[middle] == key){\n            return middle;\n        }else if(input[middle] > key){\n            return search(input,key,low,middle-1);\n        }else{\n            return search(input,key,middle+1,high);\n        }\n    }\n    \n    public static void main(String args[]){\n        int inOrder[] = {4,8,10,12,14,20,22};\n        int levelOrder[] = {20,8,22,4,12,10,14};\n        ConstructTreeFromLevelOrderInOrder ctf = new ConstructTreeFromLevelOrderInOrder();\n        Node root = ctf.constructTree(inOrder, levelOrder);\n        LevelOrderTraversal lot = new LevelOrderTraversal();\n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(root);\n        lot.levelOrder(root);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/tree/ConstructTreeFromPreOrderTraversalWith0or2Child.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/construct-a-special-tree-from-given-preorder-traversal/\n * Test cases:\n * Length of pre and val is not same\n * val contains values other than N or L\n */\nclass PreIndex{\n    int index;\n}\npublic class ConstructTreeFromPreOrderTraversalWith0or2Child {\n\n    public Node createTree(int pre[],char val[]){\n        PreIndex pi = new PreIndex();\n        pi.index = 0;\n        return createTree(pre, val,pi);\n    }\n    \n    private Node createTree(int pre[],char val[], PreIndex ind){\n        if(ind.index >= pre.length){\n            return null;\n        }\n        Node root = Node.newNode(pre[ind.index]);\n        \n        if(val[ind.index] == 'L'){\n            ind.index++;\n        }else{\n            ind.index++;\n            root.left = createTree(pre,val,ind);\n            root.right = createTree(pre,val,ind);\n        }\n        return root;\n    }\n    \n    public static void main(String args[]){\n        int pre[] = {10,20,30,40,50,60,70,80,90};\n        char val[] = {'N','N','N','L','L','L','N','L','L'};\n        ConstructTreeFromPreOrderTraversalWith0or2Child tfp = new ConstructTreeFromPreOrderTraversalWith0or2Child();\n        Node root = tfp.createTree(pre, val);\n        TreeTraversals tt = new TreeTraversals();\n        tt.preOrder(root);\n        System.out.println();\n        tt.inOrder(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ContructTreeFromInOrderTraversalRootGreaterThanChild.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/construct-binary-tree-from-inorder-traversal/\n * Given inorder traversal of binary tree where every node is greater than \n * its left and right child.\n * Test cases:\n * One two or more nodes in the tree\n */\npublic class ContructTreeFromInOrderTraversalRootGreaterThanChild {\n\n    public Node createTree(int inorder[]){\n        return createTree(inorder,0,inorder.length-1);\n    }\n    private Node createTree(int inorder[],int low,int high)\n    {\n        if(low > high){\n            return null;\n        }\n        int i;\n        int maxIndex = low;\n        for(i=low ; i <= high; i++){\n            if(inorder[maxIndex] > inorder[i]){\n                maxIndex = i;\n            }\n        }\n        Node root = Node.newNode(inorder[maxIndex]);\n        root.left = createTree(inorder,low,maxIndex-1);\n        root.right = createTree(inorder,maxIndex+1,high);\n        return root;\n    }\n    \n    public static void main(String args[]){\n        int inorder[] = {9,15,25,6,18,-1,3,-3};\n        ContructTreeFromInOrderTraversalRootGreaterThanChild tf = new ContructTreeFromInOrderTraversalRootGreaterThanChild();\n        Node root = tf.createTree(inorder);\n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/ContructTreeFromInorderPostOrder.java",
    "content": "package com.interview.tree;\n\n/**\n * Given inorder and postorder traversal of a tree, construct the binary tree.\n *\n * https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/\n */\npublic class ContructTreeFromInorderPostOrder {\n    public Node buildTree(int[] inorder, int[] postorder) {\n        return buildTree(inorder, postorder, 0, inorder.length - 1, postorder.length - 1);\n    }\n\n    public Node buildTree(int[] inorder, int[] postorder, int start, int end, int index) {\n        if (start > end) {\n            return null;\n        }\n\n        int i;\n        for (i = start; i <= end; i++) {\n            if (postorder[index] == inorder[i]) {\n                break;\n            }\n        }\n\n        Node tn = Node.newNode(postorder[index]);\n        tn.left = buildTree(inorder, postorder, start, i - 1, index - (end - i + 1));\n        tn.right = buildTree(inorder, postorder, i + 1, end, index - 1);\n        return tn;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/CountNodesCompleteTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 10/06/2016\n * @author Tushar Roy\n *\n * Given a complete binary tree, count the number of nodes.\n *\n * Time complexity O(log(n) ^ 2)\n *\n * Reference\n * https://leetcode.com/problems/count-complete-tree-nodes/\n */\npublic class CountNodesCompleteTree {\n\n    public int countNodes(Node root) {\n        if (root == null) {\n            return 0;\n        }\n        int lh = leftHeight(root.left);\n        int rh1 = rightHeight(root.left);\n        int rh = rightHeight(root.right);\n\n        if (lh == rh) {\n            return (1<<lh + 1) - 1;\n        } else {\n            if (lh == rh1) {\n                return 1 + countNodes(root.right) + (1<<lh) - 1;\n            } else {\n                return 1 + countNodes(root.left) + (1<<rh) - 1;\n            }\n        }\n    }\n\n    int leftHeight(Node root) {\n        int h = 0;\n        while (root != null) {\n            root = root.left;\n            h++;\n        }\n        return h;\n    }\n    int rightHeight(Node root) {\n        int h = 0;\n        while (root != null) {\n            root = root.right;\n            h++;\n        }\n        return h;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/CountNumberOfSmallerElementOnRight.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/count-smaller-elements-on-right-side/\n * Test cases\n * All same elements\n * Many duplicates\n * Negative numbers\n * 0s\n * Sorted or reverse sorted\n */\npublic class CountNumberOfSmallerElementOnRight {\n    private Node leftRotate(Node root){\n        Node newRoot = root.right;\n        root.right = root.right.left;\n        newRoot.left = root;\n        root.height = setHeight(root);\n        root.size = setSize(root);\n        newRoot.height = setHeight(newRoot);\n        newRoot.size = setSize(newRoot);\n        return newRoot;\n    }\n    \n    private Node rightRotate(Node root){\n        Node newRoot = root.left;\n        root.left = root.left.right;\n        newRoot.right = root;\n        root.height = setHeight(root);\n        root.size = setSize(root);\n        newRoot.height = setHeight(newRoot);\n        newRoot.size = setSize(newRoot);\n        return newRoot;\n    }\n\n    private int setHeight(Node root){\n        if(root == null){\n            return 0;\n        }\n        return 1 + Math.max((root.left != null ? root.left.height : 0), (root.right != null ? root.right.height : 0));\n    }\n    \n    private int height(Node root){\n        if(root == null){\n            return 0;\n        }else {\n            return root.height;\n        }\n    }\n    \n    private int setSize(Node root){\n        if(root == null){\n            return 0;\n        }\n        return 1 + Math.max((root.left != null ? root.left.size : 0), (root.right != null ? root.right.size : 0));\n    }\n    \n    private Node insert(Node root, int data,int count[],int pos,int val){\n        if(root == null){\n            count[pos] = val;\n            return Node.newNode(data);\n        }\n        if(root.data <= data){\n            val++;\n            if(root.left != null){\n                val += root.left.size;\n            }\n            root.right = insert(root.right,data,count,pos,val);\n        }\n        else{\n            root.left = insert(root.left,data,count,pos,val);\n        }\n        if(height(root.left) - height(root.right) > 1){\n            if(height(root.left.left) >= height(root.left.right)){\n                root = rightRotate(root);\n        }else{\n                root.left = leftRotate(root.left);\n                root = rightRotate(root);\n            }\n        }else if(height(root.right) - height(root.left) > 1){\n            if(height(root.right.right) >= height(root.right.left)){\n                root = leftRotate(root);\n            }else{\n                root.right = rightRotate(root.right);\n                root = leftRotate(root);\n            }\n        }\n        else{\n            root.height = setHeight(root);\n            root.size = setSize(root);\n        }\n        return root;\n    }\n    \n    public int[] count(int input[]){\n        int count[] = new int[input.length];\n        Node root = null;\n        for(int i=input.length-1; i >= 0; i--){\n            root = insert(root,input[i],count,i,0);\n        }\n        return count;\n    }\n\n    public static void main(String args[]){\n        int input[] =  {12, 1, 2, 3, 0, 11, 4};\n        CountNumberOfSmallerElementOnRight cns = new CountNumberOfSmallerElementOnRight();\n        int count[] = cns.count(input);\n        for(int c : count){\n            System.out.print(c + \" \");\n        }\n        System.out.println();\n        int input1[] = {5, 4, 3, 2, 1};\n        int count1[] = cns.count(input1);\n        for(int c : count1){\n            System.out.print(c + \" \");\n        }\n        \n        System.out.println();\n        int input2[] = {1,2,3,4,5};\n        int count2[] = cns.count(input2);\n        for(int c : count2){\n            System.out.print(c + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/CountPathSum.java",
    "content": "package com.interview.tree;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * https://leetcode.com/problems/path-sum-iii/description/\n */\npublic class CountPathSum {\n    public int pathSum(Node root, int sum) {\n        Map<Integer, Integer> map = new HashMap<>();\n        map.put(0, 1);\n        return countPathSum(root, sum, map, 0);\n    }\n\n    private int countPathSum(Node root, int sum, Map<Integer, Integer> map, int prefixSum) {\n        if (root == null) {\n            return 0;\n        }\n\n        prefixSum += root.data;\n        int count = map.getOrDefault(prefixSum - sum,0);\n        map.put(prefixSum, map.getOrDefault(prefixSum, 0) + 1);\n        count += countPathSum(root.left, sum, map, prefixSum) + countPathSum(root.right, sum, map, prefixSum);\n        map.put(prefixSum, map.getOrDefault(prefixSum, 1) - 1);\n        return count;\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/tree/CountUnivalueTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 10/07/2016\n * @author Tushar Roy\n *\n * Given a binary tree, count the number of uni-value subtrees.\n * A Uni-value subtree means all nodes of the subtree have the same value.\n *\n * https://leetcode.com/problems/count-univalue-subtrees/\n */\npublic class CountUnivalueTree {\n    private int count = 0;\n    public int countUnivalSubtrees(Node root) {\n        countUnivalSubtreesUtil(root, 0);\n        return count;\n    }\n\n    private int countUnivalSubtreesUtil(Node root, int val) {\n        if (root == null) {\n            return val;\n        }\n        int left = countUnivalSubtreesUtil(root.left, root.data);\n        int right = countUnivalSubtreesUtil(root.right, root.data);\n        if (left == right && left == root.data) {\n            count++;\n            return root.data;\n        } else {\n            return Integer.MAX_VALUE;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/CousinNodes.java",
    "content": "package com.interview.tree;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\nimport java.util.Queue;\n\n/**\n * http://www.geeksforgeeks.org/check-two-nodes-cousins-binary-tree/ Assumption\n * that both a and b are unique in tree. Test cases: Empty tree Tree with only\n * root Tree and input with a and b as cousin node Tree and input with a and b\n * not cousin node Tree with input a and b being siblings(not cousin)\n */\npublic class CousinNodes {\n\n    /**\n     * Little more efficient than other method since this guy does not need\n     * another look up to see if parent is same for found nodes.\n     */\n    public boolean areCousins1(Node root, int data1, int data2) {\n        Queue<Node> queue = new LinkedList<>();\n        queue.add(root);\n        int tempLevel = 1;\n        int level = 0;\n        boolean found1 = false;\n        boolean found2 = false;\n        Node parent1 = null;\n        Node parent2 = null;\n        while (!queue.isEmpty()) {\n            while (tempLevel > 0) {\n                root = queue.poll();\n                if (root.left != null) {\n                    if (root.left.data == data1) {\n                        found1 = true;\n                        parent1 = root;\n                    } else if (root.left.data == data2) {\n                        found2 = true;\n                        parent2 = root;\n                    } else {\n                        queue.add(root.left);\n                        level++;\n                    }\n                }\n                if (root.right != null) {\n                    if (root.right.data == data1) {\n                        found1 = true;\n                        parent1 = root;\n                    } else if (root.right.data == data2) {\n                        found2 = true;\n                        parent2 = root;\n                    } else {\n                        queue.add(root.right);\n                        level++;\n                    }\n                }\n                tempLevel--;\n            }\n            if (found1 && found2 && parent1 != parent2) {\n                return true;\n            } else if (found1 || found2) {\n                return false;\n            }\n            tempLevel = level;\n            level = 0;\n        }\n        return false;\n    }\n\n    public boolean areCousins(Node root, int a, int b) {\n        Deque<Node> queue = new LinkedList<Node>();\n        queue.offerFirst(root);\n        int levelSize = 1;\n        int tempLevelSize = 1;\n        boolean foundFirst = false;\n        while (!queue.isEmpty()) {\n            levelSize = 0;\n            while (tempLevelSize > 0) {\n                Node node = queue.pollLast();\n                // this is to make sure a and b are not siblings of each other\n                // if they are return false since they cant be cousins\n                if (checkSameParent(node, a, b)) {\n                    return false;\n                }\n                if (node.data == a || node.data == b) {\n                    if (foundFirst) {\n                        return true;\n                    }\n                    foundFirst = true;\n                }\n                if (node.left != null) {\n                    queue.offerFirst(node.left);\n                    levelSize++;\n                }\n                if (node.right != null) {\n                    queue.offerFirst(node.right);\n                    levelSize++;\n                }\n                tempLevelSize--;\n            }\n            if (foundFirst) {\n                return false;\n            }\n            tempLevelSize = levelSize;\n        }\n        return false;\n    }\n\n    private boolean checkSameParent(Node root, int a, int b) {\n        if (root.left != null && root.right != null) {\n            if ((root.left.data == a || root.left.data == b)\n                    && (root.right.data == a || root.right.data == b)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public static void main(String args[]) {\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(-1, head);\n        head = bt.addNode(21, head);\n        head = bt.addNode(-6, head);\n        CousinNodes cn = new CousinNodes();\n        System.out.println(cn.areCousins(head, 10, 19));\n        System.out.println(cn.areCousins(head, 19, 7));\n        System.out.println(cn.areCousins(head, 19, -1));\n        System.out.println(cn.areCousins(head, 19, -6));\n        System.out.println(cn.areCousins(head, -1, 7));\n        System.out.println(cn.areCousins(head, 7, -1));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/DegenerateBinaryTreeToSortedLL.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 03/16/2015\n * @author tusroy\n * \n * Given a binary tree(not BST) convert it into sorted linklist.\n * e.g          10\n *          11        15\n *        8    9    16   13\n *                           7\n *                           \n * should become 7->8->9->10->11->13->15->16\n * \n * Solution\n * Idea is that at every root, get the sorted linklist from left and right and merge them \n * along with root and return left most element in this merged linklist to upper level call.\n * \n * Test cases\n * 1) Null root\n * 2) One node root\n * 3) BST \n * 4) Reverse BST\n * 5) All on left side of root\n * \n * Reference\n * http://www.careercup.com/question?id=6241652616200192\n *\n */\npublic class DegenerateBinaryTreeToSortedLL {\n   \n    public Node degenerate(Node root){\n        if(root == null){\n            return null;\n        }\n        \n        Node left = root.left;\n        Node right = root.right;\n        root.left = null;\n        root.right = null;\n        left = degenerate(left);\n        right = degenerate(right);\n        left = merge(left, root);\n        return merge(left, right);\n    }\n    \n    private Node merge(Node root1, Node root2){\n        if(root1 == null){\n            return root2;\n        }\n        if(root2 == null){\n            return root1;\n        }\n        \n        if(root1.data <= root2.data){\n            root1.right = merge(root1.right, root2);\n            return root1;\n        }else{\n            root2.right = merge(root1, root2.right);\n            return root2;\n        }\n    }\n    \n    private void printList(Node root){\n        while(root != null){\n            System.out.print(root.data + \" \");\n            root = root.right;\n        }\n    }\n    \n    public static void main(String args[]){\n        ConstructTreeFromInOrderPreOrder ctf = new ConstructTreeFromInOrderPreOrder();\n        int inorder[] = {8, 11, 9, 10, 16, 15, 13, 7};\n        int preorder[] = {10, 11, 8, 9, 15, 16, 13, 7};\n        Node root = ctf.createTree(inorder, preorder);\n        DegenerateBinaryTreeToSortedLL dbt = new DegenerateBinaryTreeToSortedLL();\n        root = dbt.degenerate(root);\n        dbt.printList(root);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/tree/DiameterOfTree.java",
    "content": "package com.interview.tree;\n\nclass Height{\n    int height;\n}\n\n/**\n * http://www.geeksforgeeks.org/diameter-of-a-binary-tree/\n * Test cases\n * All left nodes\n * All right nodes\n */\npublic class DiameterOfTree {\n\n    public int diameter(Node root){\n        Height height = new Height();\n        return diameter(root,height);\n    }\n    \n    private int diameter(Node root, Height height){\n    \n        if(root == null){\n            return 0;\n        }\n        \n        Height leftHeight = new Height();\n        Height rightHeight = new Height();\n        int dial = diameter(root.left,leftHeight);\n        int diar = diameter(root.right,rightHeight);\n        height.height = Math.max(leftHeight.height, rightHeight.height) + 1;\n        return Math.max(Math.max(dial, diar),(1 + leftHeight.height + rightHeight.height));\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(-1, head);\n        head = bt.addNode(21, head);\n        head = bt.addNode(11, head);\n        head = bt.addNode(12, head);\n        head = bt.addNode(13, head);\n        head = bt.addNode(14, head);\n        DiameterOfTree dt = new DiameterOfTree();\n        System.out.println(dt.diameter(head));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/FenwickTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 04/27/2015\n * @author tusroy\n * \n * Write a program to implement fenwick or binary indexed tree\n * \n * A Fenwick tree or binary indexed tree is a data structure providing efficient methods\n * for calculation and manipulation of the prefix sums of a table of values.\n * \n * Space complexity for fenwick tree is O(n)\n * Time complexity to create fenwick tree is O(nlogn)\n * Time complexity to update value is O(logn)\n * Time complexity to get prefix sum is O(logn)\n * \n * References\n * http://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2/\n * https://www.topcoder.com/community/data-science/data-science-tutorials/binary-indexed-trees/\n * http://en.wikipedia.org/wiki/Fenwick_tree\n */\npublic class FenwickTree {\n\n    /**\n     * Start from index+1 if you updating index in original array. Keep adding this value \n     * for next node till you reach outside range of tree\n     */\n    public void updateBinaryIndexedTree(int binaryIndexedTree[], int val, int index){\n        while(index < binaryIndexedTree.length){\n            binaryIndexedTree[index] += val;\n            index = getNext(index);\n        }\n    }\n    \n    /**\n     * Start from index+1 if you want prefix sum 0 to index. Keep adding value\n     * till you reach 0\n     */\n    public int getSum(int binaryIndexedTree[], int index){\n        index = index + 1;\n        int sum = 0;\n        while(index > 0){\n            sum += binaryIndexedTree[index];\n            index = getParent(index);\n        }\n        return sum;\n    }\n    \n    /**\n     * Creating tree is like updating Fenwick tree for every value in array\n     */\n    public int[] createTree(int input[]){\n        int binaryIndexedTree[] = new int[input.length+1];\n        for(int i=1; i <= input.length; i++){\n            updateBinaryIndexedTree(binaryIndexedTree, input[i-1], i);\n        }\n        return binaryIndexedTree;\n    }\n    \n    /**\n     * To get parent\n     * 1) 2's complement to get minus of index\n     * 2) AND this with index\n     * 3) Subtract that from index\n     */\n    private int getParent(int index){\n        return index - (index & -index);\n    }\n    \n    /**\n     * To get next\n     * 1) 2's complement of get minus of index\n     * 2) AND this with index\n     * 3) Add it to index\n     */\n    private int getNext(int index){\n        return index + (index & -index);\n    }\n    \n    public static void main(String args[]){\n        int input[] = {1,2,3,4,5,6,7};\n        FenwickTree ft = new FenwickTree();\n        int binaryIndexedTree[] = ft.createTree(input);\n        assert 1 == ft.getSum(binaryIndexedTree, 0);\n        assert 3 == ft.getSum(binaryIndexedTree, 1);\n        assert 6 == ft.getSum(binaryIndexedTree, 2);\n        assert 10 == ft.getSum(binaryIndexedTree, 3);\n        assert 15 == ft.getSum(binaryIndexedTree, 4);\n        assert 21 == ft.getSum(binaryIndexedTree, 5);\n        assert 28 == ft.getSum(binaryIndexedTree, 6);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/FlattenLinkListToBinaryTreePreorder.java",
    "content": "package com.interview.tree;\n\nimport java.util.Stack;\n\n/**\n * Date 10/06/2016\n * @author Tushar Roy\n *\n * Given a binary tree, flatten it to a linked list in-place in preorder traversal.\n *\n * Time complexity O(n)\n *\n * https://leetcode.com/problems/flatten-binary-tree-to-linked-list/\n */\npublic class FlattenLinkListToBinaryTreePreorder {\n    public void flatten(Node root) {\n        if (root == null) {\n            return;\n        }\n        Stack<Node> stack = new Stack<>();\n        stack.push(root);\n        Node prev = null;\n        while (!stack.isEmpty()) {\n            Node node = stack.pop();\n            if (prev != null) {\n                prev.right = node;\n            }\n            prev = node;\n            if (node.right != null) {\n                stack.push(node.right);\n            }\n            if (node.left != null) {\n                stack.push(node.left);\n            }\n            node.left = null;\n            node.right = null;\n        }\n    }\n\n    public void flatten1(Node root) {\n        if(root==null)\n            return;\n        flatten(root.left);\n        flatten(root.right);\n        Node left  = root.left;\n        Node right = root.right;\n        root.left  = null;\n        root.right = left;\n        while(root.right!=null)\n            root = root.right;\n        root.right = right;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/HeightBalanced.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 10/06/2016\n * @author Tushar Roy\n *\n * Given a binary tree, determine if it is height-balanced.\n *\n * Time complexity O(logn)\n *\n * Reference\n * https://leetcode.com/problems/balanced-binary-tree/\n */\npublic class HeightBalanced {\n    public boolean isBalanced(Node root) {\n        return isBalancedUtil(root) >= 0;\n    }\n\n    private int isBalancedUtil(Node root) {\n        if (root == null) {\n            return 0;\n        }\n        int left = isBalancedUtil(root.left);\n        if (left < 0) {\n            return -1;\n        }\n        int right = isBalancedUtil(root.right);\n        if (right < 0) {\n            return -1;\n        }\n        int diff = Math.abs(left - right);\n        return diff <= 1 ? (Math.max(left, right) + 1) : -1;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/HuffmanEncoding.java",
    "content": "package com.interview.tree;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.PriorityQueue;\nimport java.util.Comparator;\n\n/**\n * http://www.geeksforgeeks.org/greedy-algorithms-set-3-huffman-coding/\n * http://www.geeksforgeeks.org/greedy-algorithms-set-3-huffman-coding-set-2/\n */\nclass HuffmanNode{\n    int freq;\n    char input;\n    HuffmanNode left;\n    HuffmanNode right;\n}\n\nclass HuffmanNodeComparator implements Comparator<HuffmanNode>{\n\n    @Override\n    public int compare(HuffmanNode o1, HuffmanNode o2) {\n        if(o1.freq < o2.freq){\n            return -1;\n        }else{\n            return 1;\n        }\n    }\n    \n}\n\npublic class HuffmanEncoding {\n\n    public Map<Character,String> huffman(char[] input, int freq[]){\n        HuffmanNodeComparator comparator = new HuffmanNodeComparator();\n        PriorityQueue<HuffmanNode> heap = new PriorityQueue<HuffmanNode>(input.length,comparator);\n        for(int i=0; i < input.length; i++){\n            HuffmanNode node = new HuffmanNode();\n            node.freq = freq[i];\n            node.input = input[i];\n            heap.offer(node);\n        }\n    \n        while(heap.size() > 1){\n            HuffmanNode node1 = heap.poll();\n            HuffmanNode node2 = heap.poll();\n            HuffmanNode node = new HuffmanNode();\n            node.left = node1;\n            node.right = node2;\n            node.freq = node1.freq + node2.freq;\n            heap.offer(node);\n        }\n        \n        Map<Character,String> map = new HashMap<Character,String>();\n        StringBuffer buff = new StringBuffer();\n        createCode(heap.poll(),map,buff);\n        return map;\n        \n    }\n    \n    public void createCode(HuffmanNode node,Map<Character,String> map,StringBuffer buff){\n        if(node == null){\n            return;\n        }\n        \n        if(node.left == null && node.right == null){\n            map.put(node.input,buff.toString());\n            return;\n        }\n        buff.append(\"0\");\n        createCode(node.left,map,buff);\n        buff.deleteCharAt(buff.length()-1);\n        buff.append(\"1\");\n        createCode(node.right,map,buff);\n        buff.deleteCharAt(buff.length()-1);\n    }\n    \n    \n    public static void main(String args[]){\n        HuffmanEncoding he = new HuffmanEncoding();\n        char input[] = {'a','b','c','d','e','f'};\n        int freq[] = {5,9,12,13,16,45};\n        Map<Character,String> code = he.huffman(input, freq);\n        System.out.println(code);\n    }\n    \n}\n"
  },
  {
    "path": "src/com/interview/tree/IdenticalTrees.java",
    "content": "package com.interview.tree;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * http://www.geeksforgeeks.org/check-for-identical-bsts-without-building-the-trees/\n * Test cases\n * Both array should be same size and have exact same elements and first element should be same\n */\npublic class IdenticalTrees {\n\n    private class BigSmall{\n        int big;\n        int small;\n    }\n    \n    public boolean sameBST(int tree1[], int tree2[]){\n        return sameBST(tree1,tree2,Integer.MIN_VALUE,Integer.MAX_VALUE,0);\n    }\n    \n    private boolean sameBST(int tree1[],int tree2[],int min,int max,int index){\n        if(index ==tree1.length){\n            return true;\n        }\n        \n        int i=0;\n        for(i=0; i < tree2.length; i++){\n            if(tree2[i] == tree1[index]){\n                break;\n            }\n        }\n        \n        BigSmall bs1 = nextBigSmall(tree1,index,min,max);\n        BigSmall bs2 = nextBigSmall(tree2,i,min,max);\n        \n        boolean r1=  tree1[bs1.big] == tree2[bs2.big] && tree1[bs1.small] == tree2[bs2.small] ;\n        if(r1 == false){\n            return false;\n        }\n        boolean r2 = true,r3 =true;\n        if(bs1.small !=  0){\n            r2 = sameBST(tree1,tree2,min,tree1[index],bs1.small);\n        }\n        if(bs1.big != 0){\n            r3 = sameBST(tree1,tree2,tree1[index],max,bs1.big);\n        }\n        return r2 && r3;\n    }\n    \n    private BigSmall nextBigSmall(int[] tree,int index,int min,int max){\n        BigSmall bs = new BigSmall();\n        boolean seenBig = false, seenSmall = false;\n        for(int i=index+1; i < tree.length && (!seenBig || !seenSmall); i++){\n            if(tree[i] > max || tree[i] < min){\n                continue;\n            }\n            if(!seenBig && tree[i] > tree[index]){\n                bs.big = i;\n                seenBig = true;\n            }\n            if(!seenSmall && tree[i] < tree[index]){\n                bs.small = i;\n                seenSmall = true;\n            }\n        }\n        return bs;\n    }\n    \n    /**\n     * Little simpler version of above implementation. Uses more space but atleast its easy to understand.\n     * All it does is makes 2 list one of larger and one of smaller element than root and then passes\n     * them into left and right sides\n     * @param arr1\n     * @param arr2\n     * @return\n     */\n    \n    public boolean sameBST1(int arr1[], int arr2[]){\n        List<Integer> list1 = new ArrayList<>();\n        for(int i : arr1){\n            list1.add(i);\n        }\n        List<Integer> list2 = new ArrayList<>();\n        for(int i : arr2){\n            list2.add(i);\n        }\n        \n        return sameBST1(list1, list2);\n    }\n    \n    /**\n     * It might not work for duplicate elements in array. For that you have to store\n     * both index and actual value to differentiate somehow.\n     */\n    private boolean sameBST1(List<Integer> arr1, List<Integer> arr2){\n        if(arr1.size() == 0 && arr2.size() == 0){\n            return true;\n        }\n        if(arr1.size() == 0 || arr2.size() == 0){\n            return false;\n        }\n        \n        if(arr1.get(0) != arr2.get(0)){\n            return false;\n        }\n        List<Integer> smaller1 = new ArrayList<Integer>();\n        List<Integer> larger1= new ArrayList<Integer>();\n        boolean first = true;\n        for(Integer i : arr1){\n            if(first){\n               first = false;\n               continue;\n            }\n            if(i <= arr1.get(0)){\n                smaller1.add(i);\n            }else{\n                larger1.add(i);\n            }\n        }\n        first = true;\n        List<Integer> smaller2 = new ArrayList<Integer>();\n        List<Integer> larger2= new ArrayList<Integer>();\n        for(Integer i : arr2){\n            if(first){\n               first = false;\n               continue;\n            }\n            if(i <= arr2.get(0)){\n                smaller2.add(i);\n            }else{\n                larger2.add(i);\n            }\n        }\n        boolean r = compare(smaller1, smaller2) && compare(larger1, larger2);\n        if(!r){\n            return false;\n        }\n        return sameBST1(smaller1, smaller2) && sameBST1(larger1, larger2);\n        \n    }\n    \n    private boolean compare(List<Integer> l1, List<Integer> l2){\n        Set<Integer> s = new HashSet<Integer>();\n        for(Integer i : l1){\n            s.add(i);\n        }\n        for(Integer i : l2){\n            if(!s.contains(i)){\n                return false;\n            }\n        }\n        return true;\n    }\n    \n    public static void main(String args[]){\n        int tree1[] = {3,-6,-2,11,9,-10,-1,15,10};\n        int tree2[] = {3,11,9,15,-6,10,-2,-1,-10};\n        IdenticalTrees it = new IdenticalTrees();\n        System.out.println(it.sameBST(tree1, tree2));\n        System.out.println(it.sameBST1(tree1, tree2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/InorderSuccessor.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 03/27/2016\n * @author Tushar Roy\n *\n * Given a binary search tree and a node in it, find the in-order successor of that node in the BST.\n *\n * Time complexity O(h)\n * Space complexity O(h)\n *\n * https://leetcode.com/problems/inorder-successor-in-bst/\n */\npublic class InorderSuccessor {\n    public Node inorderSuccessor(Node root, Node p) {\n        if (p.right != null) {\n            p = p.right;\n            while (p.left != null) {\n                p = p.left;\n            }\n            return p;\n        } else {\n            return succ(root, p.data);\n        }\n    }\n\n    private Node succ(Node root, int data) {\n        if (root.data == data) {\n            return null;\n        }\n        if (root.data < data) {\n            return succ(root.right, data);\n        } else {\n            Node s = succ(root.left, data);\n            return s == null ? root : s;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/IntervalTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 11/07/2015\n * @author Tushar Roy\n *\n * Write class for interval tree\n * Keep a max at every node which is max of that subtree.\n * This max is used to decide which direction to move when checking\n * for overlap. When an interval's high is less than max of left side go\n * in that direciton otherwise go in other direction.\n */\nclass InternalNode {\n    int low;\n    int high;\n    int max;\n    InternalNode left;\n    InternalNode right;\n\n    @Override\n    public String toString() {\n        return \"InternalNode{\" +\n                \"max=\" + max +\n                \", low=\" + low +\n                \", high=\" + high +\n                '}';\n    }\n}\n\npublic class IntervalTree {\n\n    public InternalNode insert(InternalNode root, int low, int high) {\n        if(root == null) {\n            InternalNode node = new InternalNode();\n            node.low = low;\n            node.high = high;\n            node.max = high;\n            return node;\n        }\n\n        if(low < root.low) {\n            root.left = insert(root.left, low, high);\n        } else {\n            root.right = insert(root.right, low, high);\n        }\n\n        root.max = Math.max(root.high, high);\n        return root;\n    }\n\n    public InternalNode isOverlap(InternalNode root, int low, int high) {\n        if(root == null) {\n            return null;\n        }\n\n        if(root.high >= low && root.low <= high) {\n            return root;\n        }\n\n        if(root.left != null && root.left.max > low) {\n            return isOverlap(root.left, low, high);\n        } else {\n            return isOverlap(root.right, low, high);\n        }\n    }\n\n    public static void main(String args[]) {\n        IntervalTree it = new IntervalTree();\n        InternalNode root = null;\n        root = it.insert(root, 10, 15);\n        root = it.insert(root, 11, 13);\n        root = it.insert(root, 18, 21);\n        root = it.insert(root, 20, 25);\n        root = it.insert(root, 0, 7);\n\n        System.out.println(it.isOverlap(root, 8, 9));\n        System.out.println(it.isOverlap(root, 17, 17));\n        System.out.println(it.isOverlap(root, 21, 22));\n        System.out.println(it.isOverlap(root, 21, 22));\n        System.out.println(it.isOverlap(root, 12, 18));\n        System.out.println(it.isOverlap(root, 24, 26));\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/tree/IsBST.java",
    "content": "package com.interview.tree;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * Date 04/11/2015\n * @author tusroy\n * \n * Youtube link - https://youtu.be/MILxfAbIhrE\n * \n * Given a binary tree, return true if it is binary search tree else return false.\n * \n * Solution\n * Keep min, max for every recursion. Initial min and max is very small and very larger\n * number. Check if root.data is in this range. When you go left pass min and root.data and \n * for right pass root.data and max.\n * \n * Time complexity is O(n) since we are looking at all nodes.\n * \n * Test cases:\n * Null tree\n * 1 or 2 nodes tree\n * Binary tree which is actually BST\n * Binary tree which is not a BST\n */\npublic class IsBST {\n\n    public boolean isBST(Node root){\n        return isBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE);\n    }\n    \n    private boolean isBST(Node root, int min, int max){\n        if(root == null){\n            return true;\n        }\n        if(root.data <= min || root.data > max){\n            return false;\n        }\n        return isBST(root.left, min, root.data) && isBST(root.right, root.data, max);\n    }\n\n\n    public boolean isBSTIterative(Node root) {\n        if (root == null) {\n            return true;\n        }\n\n        Deque<Node> stack = new LinkedList<>();\n        Node node = root;\n        int prev = Integer.MIN_VALUE;\n        int current;\n        while ( true ) {\n            if (node != null) {\n                stack.addFirst(node);\n                node = node.left;\n            } else {\n                if (stack.isEmpty()) {\n                    break;\n                }\n                node = stack.pollFirst();\n                current = node.data;\n                if (current < prev) {\n                    return false;\n                }\n                prev = current;\n                node = node.right;\n            }\n        }\n        return true;\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(15, root);\n        root = bt.addNode(-10, root);\n        root = bt.addNode(17, root);\n        root = bt.addNode(20, root);\n        root = bt.addNode(0, root);\n        \n        IsBST isBST = new IsBST();\n        assert isBST.isBST(root);\n        assert isBST.isBSTIterative(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/IsCompleteBinaryTree.java",
    "content": "package com.interview.tree;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\n\n/**\n * http://www.geeksforgeeks.org/check-if-a-given-binary-tree-is-complete-tree-or-not/\n * Test cases:\n * A node with only right child\n * A node with only left child\n * A node with both left and right child\n */\npublic class IsCompleteBinaryTree {\n\n    public boolean isComplete(Node root){\n        Queue<Node> queue = new LinkedList<Node>();\n        queue.offer(root);\n        boolean foundFirstNonFull = false;\n        while(!queue.isEmpty()){\n            root = queue.poll();\n            if(foundFirstNonFull){\n                if(root.left != null || root.right != null){\n                    return false;\n                }\n                continue;\n            }\n            if(root.left != null && root.right != null){\n                queue.offer(root.left);\n                queue.offer(root.right);\n            }else if(root.left != null){\n                queue.offer(root.left);\n                foundFirstNonFull = true;\n            }else if(root.right != null){\n                return false;\n            }else{\n                foundFirstNonFull = true;\n            }\n        }\n        return true;\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(3, head);\n        head = bt.addNode(-6, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(-10, head);\n        head = bt.addNode(-15, head);\n        head = bt.addNode(-4, head);\n        head = bt.addNode(4, head);\n        head = bt.addNode(11, head);\n        head = bt.addNode(-9, head);\n            \n        IsCompleteBinaryTree icbt = new IsCompleteBinaryTree();\n        System.out.println(icbt.isComplete(head));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/IsPreOrderArrayBST.java",
    "content": "package com.interview.tree;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * Check if given pre array sequence will create a binary search tree or not.\n *\n * Idea is to keep minimal acceptable value. Any element in pre array should never be less\n * than minimal acceptable value. Values are popped from stack till they are less than pre[i]\n * Last popped value becomes new minimally acceptable vaue.\n *\n * It does not work for duplicates\n *\n * Time complexity - O(n)\n * https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/\n * Reference - http://www.geeksforgeeks.org/check-if-a-given-array-can-represent-preorder-traversal-of-binary-search-tree/\n */\npublic class IsPreOrderArrayBST {\n\n    public boolean verifyPreorder(int pre[]) {\n        Deque<Integer> deque = new LinkedList<>();\n        int minAcceptable = Integer.MIN_VALUE;\n        deque.addFirst(pre[0]);\n        for(int i = 1; i < pre.length; i++) {\n            if(pre[i] < minAcceptable) {\n                return false;\n            }\n            while(!deque.isEmpty() && deque.peekFirst() < pre[i]) {\n                minAcceptable = deque.pollFirst();\n            }\n            deque.addFirst(pre[i]);\n        }\n        return true;\n    }\n\n    public boolean verifyPreorderConstantSpace(int[] preorder) {\n        int start = 0;\n        int min = Integer.MIN_VALUE;\n        for (int i = 1; i < preorder.length; i++) {\n            if (preorder[i] < min) {\n                return false;\n            }\n            if (preorder[i] > preorder[i - 1]) {\n                int index = binarySearch(preorder, start, i - 1, preorder[i]);\n                min = preorder[index];\n                start = i;\n            }\n        }\n        return true;\n    }\n\n    int binarySearch(int[] preorder, int start, int end, int val) {\n        int s = start;\n        int e = end;\n        while (s <= e) {\n            int middle = (s + e)/2;\n            if (preorder[middle] < val && (start == middle || preorder[middle - 1] > val)) {\n                return middle;\n            } else if (preorder[middle] < val) {\n                e = middle - 1;\n            } else {\n                s = middle + 1;\n            }\n        }\n        return -1;\n    }\n\n    public static void main(String args[]) {\n        IsPreOrderArrayBST isb = new IsPreOrderArrayBST();\n        int[] input = {10, 3, -1, 4, 13, 11, 12, 10};\n        System.out.println(isb.verifyPreorder(input));\n        System.out.println(isb.verifyPreorderConstantSpace(input));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/KClosestValueInBinaryTree.java",
    "content": "package com.interview.tree;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Stack;\n\n/**\n * Date 10/08/2016\n * @author Tushar Roy\n *\n * Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.\n *\n * Time complexity O(log(n) + k)\n *\n * https://leetcode.com/problems/closest-binary-search-tree-value-ii/\n */\npublic class KClosestValueInBinaryTree {\n\n    public List<Integer> closestKValues(Node root, double target, int k) {\n        if (root == null || k == 0) {\n            return new ArrayList<>();\n        }\n\n        Stack<Node> predecessor = new Stack();\n        Stack<Node> successor = new Stack();\n\n        double closestDiff = Double.MAX_VALUE;\n        Node closestDiffNode = null;\n        while (root != null) {\n            predecessor.push(root);\n            successor.push(root);\n            if (Math.abs(target - root.data) < closestDiff) {\n                closestDiff = Math.abs(target - root.data);\n                closestDiffNode = root;\n            }\n            if (root.data == target) {\n                break;\n            }\n\n            else if (target > root.data) {\n                root = root.right;\n            } else {\n                root = root.left;\n            }\n        }\n\n        while (predecessor.peek() != closestDiffNode) {\n            predecessor.pop();\n            successor.pop();\n        }\n        predecessor.pop();\n        successor.pop();\n        List<Integer> result = new ArrayList<>();\n        result.add(closestDiffNode.data);\n        Node prec = closestDiffNode;\n        Node succ = closestDiffNode;\n        k--;\n        prec = predecessor(predecessor, prec);\n        succ = successor(successor, succ);\n        while (k > 0) {\n            if (succ == null || (prec != null && Math.abs(target - prec.data) < Math.abs(target - succ.data))) {\n                result.add(prec.data);\n                prec = predecessor(predecessor, prec);\n            } else {\n                result.add(succ.data);\n                succ = successor(successor, succ);\n            }\n            k--;\n        }\n        return result;\n    }\n\n    private Node predecessor(Stack<Node> stack, Node current) {\n        if (current == null) {\n            return null;\n        }\n        if (current.left != null) {\n            stack.push(current);\n            current = current.left;\n            while (current.right != null) {\n                stack.push(current);\n                current = current.right;\n            }\n            return current;\n        } else {\n            while (!stack.isEmpty() && stack.peek().left == current) {\n                current = stack.pop();\n            }\n            if (stack.isEmpty()) {\n                return null;\n            } else {\n                return stack.pop();\n            }\n        }\n    }\n\n    private Node successor(Stack<Node> stack, Node current) {\n        if (current == null) {\n            return null;\n        }\n        if (current.right != null) {\n            stack.push(current);\n            current = current.right;\n            while (current.left != null) {\n                stack.push(current);\n                current = current.left;\n            }\n            return current;\n        } else {\n            while (!stack.isEmpty() && stack.peek().right == current) {\n                current = stack.pop();\n            }\n            if (stack.isEmpty()) {\n                return null;\n            } else {\n                return stack.pop();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/LargestBSTInBinaryTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 07/20/2014\n * @author tusroy\n * \n * Video link - https://youtu.be/4fiDs7CCxkc\n * \n * Given a binary tree, find size of largest binary search subtree in this\n * binary tree.\n * \n * Traverse tree in post order fashion. Left and right nodes return 4 piece\n * of information to root which isBST, size of max BST, min and max in those\n * subtree. \n * If both left and right subtree are BST and this node data is greater than max\n * of left and less than min of right then it returns to above level left size +\n * right size + 1 and new min will be min of left side and new max will be max of\n * right side.\n * \n * References:\n * http://www.geeksforgeeks.org/find-the-largest-subtree-in-a-tree-that-is-also-a-bst/\n * https://leetcode.com/problems/largest-bst-subtree/\n */\npublic class LargestBSTInBinaryTree {\n\n    public int largestBST(Node root){\n        MinMax m = largest(root);\n        return m.size;\n    }\n    \n    private MinMax largest(Node root){\n        //if root is null return min as Integer.MAX and max as Integer.MIN \n        if(root == null){\n            return new MinMax();\n        }\n        \n        //postorder traversal of tree. First visit left and right then\n        //use information of left and right to calculate largest BST.\n        MinMax leftMinMax = largest(root.left);\n        MinMax rightMinMax =largest(root.right);\n        \n        MinMax m = new MinMax();\n        \n        //if either of left or right subtree says its not BST or the data\n        //of this node is not greater/equal than max of left and less than min of right\n        //then subtree with this node as root will not be BST. \n        //Return false and max size of left and right subtree to parent\n        if(leftMinMax.isBST == false || rightMinMax.isBST == false || (leftMinMax.max > root.data || rightMinMax.min <= root.data)){\n            m.isBST = false;\n            m.size = Math.max(leftMinMax.size, rightMinMax.size);\n            return m;\n        }\n        \n        //if we reach this point means subtree with this node as root is BST.\n        //Set isBST as true. Then set size as size of left + size of right + 1.\n        //Set min and max to be returned to parent.\n        m.isBST = true;\n        m.size = leftMinMax.size + rightMinMax.size + 1;\n     \n        //if root.left is null then set root.data as min else\n        //take min of left side as min\n        m.min = root.left != null ? leftMinMax.min : root.data;\n  \n        //if root.right is null then set root.data as max else\n        //take max of right side as max.\n        m.max = root.right != null ? rightMinMax.max : root.data;\n   \n        return m;\n    }\n    \n    public static void main(String args[]){\n        LargestBSTInBinaryTree lbi = new LargestBSTInBinaryTree();\n        ConstructTreeFromInOrderPreOrder ctf = new ConstructTreeFromInOrderPreOrder();\n        //this is just to create a binary tree.\n        int inorder[]  = {-7,-6,-5,-4,-3,-2,1,2,3,16,6,10,11,12,14};\n        int preorder[] = {3,-2,-3,-4,-5,-6,-7,1,2,16,10,6,12,11,14};\n        Node root = ctf.createTree(inorder, preorder);\n        int largestBSTSize = lbi.largestBST(root);\n        System.out.println(\"Size of largest BST  is \" + largestBSTSize);\n        assert largestBSTSize == 8;\n    }\n}\n\n/**\n * Object of this class holds information which child passes back\n * to parent node.\n */\nclass MinMax{\n    int min;\n    int max;\n    boolean isBST;\n    int size ;\n    \n    MinMax(){\n        min = Integer.MAX_VALUE;\n        max = Integer.MIN_VALUE;\n        isBST = true;\n        size = 0;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/LargestIndependentSetInTree.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/largest-independent-set-problem/\n */\npublic class LargestIndependentSetInTree {\n\n    public int largestSet(Node root){\n        if(root == null){\n            return 0;\n        }\n        \n        if(root.lis != -1){\n            return root.lis;\n        }\n        int excl = 0;\n        int left_excl = 0;\n        if(root.left != null){\n            left_excl = largestSet(root.left.left) + largestSet(root.left.right);\n            excl += largestSet(root.left);\n        }\n        int right_excl = 0;\n        if(root.right != null){\n            right_excl = largestSet(root.right.left) + largestSet(root.right.right);\n            excl += largestSet(root.right);\n        }\n        \n        int incl = left_excl + right_excl + root.data;\n        root.lis = incl;\n    \n        return incl > excl ? incl : excl; \n    }\n    \n    public static void main(String args[]){\n        int inorder[] = {4,13,1,7,6,3,19};\n        int preorder[] = {13,4,6,7,1,3,19};\n        ConstructTreeFromInOrderPreOrder ctf = new ConstructTreeFromInOrderPreOrder();\n        Node root = ctf.createTree(inorder, preorder);\n        LargestIndependentSetInTree lis = new LargestIndependentSetInTree();\n        System.out.println(lis.largestSet(root));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/LeavesOfBinaryTree.java",
    "content": "package com.interview.tree;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Date 10/08/2016\n * @author Tushar Roy\n *\n * Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves, repeat until the tree is empty.\n *\n * Time complexity O(n^2) for unbalanced tree.\n *\n * https://leetcode.com/problems/find-leaves-of-binary-tree/\n */\npublic class LeavesOfBinaryTree {\n    public List<List<Integer>> findLeaves(Node root) {\n        if (root == null) {\n            return Collections.EMPTY_LIST;\n        }\n        List<List<Integer>> result = new ArrayList<>();\n        List<Integer> leaves = new ArrayList<>();\n        while (stripLeaves(root, leaves) != null) {\n            result.add(leaves);\n            leaves = new ArrayList<>();\n        }\n        result.add(leaves);\n        return result;\n    }\n\n    Node stripLeaves(Node root, List<Integer> leaves) {\n        if (root == null) {\n            return null;\n        }\n        if (root.left == null && root.right == null) {\n            leaves.add(root.data);\n            return null;\n        }\n        root.left = stripLeaves(root.left, leaves);\n        root.right = stripLeaves(root.right, leaves);\n        return root;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/LevelOrderTraversal.java",
    "content": "package com.interview.tree;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\n\n/**\n * Youtube link - https://youtu.be/9PHkM0Jri_4\n * \n * http://www.geeksforgeeks.org/level-order-tree-traversal/ \n * Test cases\n * Empty tree\n * Tree with only left side\n * Tree with only right side\n * Mixed size tree\n * Full tree\n * complete tree\n */\npublic class LevelOrderTraversal {\n\n    public void levelOrder(Node root){\n        if(root == null){\n            System.out.println(\"Please enter a valid tree!\");\n            return;\n        }\n        Queue<Node> queue = new LinkedList<Node>();\n        queue.offer(root);\n        System.out.println();\n        while(queue.size() > 0){\n            root = queue.poll();\n            System.out.print(root.data + \" \");\n            if(root.left != null){\n                queue.add(root.left);\n            }\n            if(root.right != null){\n                queue.add(root.right);\n            }\n        }\n    }\n\n    public static void main(String args[]){\n        LevelOrderTraversal loi = new LevelOrderTraversal();\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(-1, head);\n        loi.levelOrder(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/LevelOrderTraversalInReverse.java",
    "content": "package com.interview.tree;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Stack;\n\n/**\n * Date 04/20/2015\n * @author tusroy\n * \n * Video link - https://youtu.be/D2bIbWGgvzI\n *\n * Given a binary tree print its level order traversal in reverse\n * e.g           1\n *          2         3\n *        4    5    6   7\n * \n * Output should be 4 5 6 7 2 3 1\n * \n * Solution\n * Maintain a stack and queue. Do regular level order traversal but\n * put right first in the queue. Instead of printing put the result\n * in stack. Finally print contents of the stack.\n * \n * Time and space complexity is O(n)\n * \n * References : http://www.geeksforgeeks.org/reverse-level-order-traversal/\n */\npublic class LevelOrderTraversalInReverse {\n\n    public void reverseLevelOrderTraversal(Node root){\n        if(root == null){\n            return;\n        }\n        Queue<Node> q = new LinkedList<>();\n        Stack<Node> s = new Stack<>();\n        \n        q.offer(root);\n        while(!q.isEmpty()){\n            root = q.poll();\n            if(root.right != null){\n                q.offer(root.right);\n            }\n            if(root.left != null){\n                q.offer(root.left);\n            }\n            s.push(root);\n        }\n        while(!s.isEmpty()){\n            System.out.print(s.pop().data + \" \");\n        }\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(30, root);\n        root = bt.addNode(25, root);\n        root = bt.addNode(35, root);\n        root = bt.addNode(-10, root);\n        root = bt.addNode(0, root);\n        root = bt.addNode(-20, root);\n        root = bt.addNode(-15, root);\n        root = bt.addNode(45, root);\n        LevelOrderTraversalInReverse rlo = new LevelOrderTraversalInReverse();\n        rlo.reverseLevelOrderTraversal(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/LongestConsecutiveSequence.java",
    "content": "package com.interview.tree;\n\n/**\n * Created by tushar_v_roy on 4/1/16.\n */\npublic class LongestConsecutiveSequence {\n    int max = 0;\n    public int longestConsecutive(Node root) {\n        if (root == null) {\n            return 0;\n        }\n        max = 0;\n        longestConsecutiveUtil(root, root.data - 1, 0);\n        return max;\n    }\n\n    public void longestConsecutiveUtil(Node root, int prevData, int current) {\n        if (root == null) {\n            return;\n        }\n\n        if (root.data == prevData + 1) {\n            current = current + 1;\n        } else {\n            current = 1;\n        }\n        max = Math.max(current, max);\n        longestConsecutiveUtil(root.left, root.data, current);\n        longestConsecutiveUtil(root.right, root.data, current);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/LowestCommonAncestorInBinaryTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 04/27/2016\n * @author Tushar Roy\n *\n * Find lowest common ancestor in binary tree.\n *\n * Time complexity O(n)\n * Space complexity O(h)\n */\npublic class LowestCommonAncestorInBinaryTree {\n\n    public Node lca(Node root, Node n1, Node n2){\n        if(root == null){\n            return null;\n        }\n        if(root == n1 || root == n2){\n            return root;\n        }\n        \n        Node left = lca(root.left, n1, n2);\n        Node right = lca(root.right, n1, n2);\n\n        if(left != null && right != null){\n            return root;\n        }\n        return left != null ? left : right;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/LowestCommonAncestoryBinarySearchTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 05/04/2016\n * @author Tushar Roy\n *\n * Lowest common ancestor in binary search tree.\n *\n * Time complexity O(height of tree)\n * Space complexity O(height of tree)\n * \n * https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/\n */\npublic class LowestCommonAncestoryBinarySearchTree {\n\n    public Node lowestCommonAncestor(Node root, int p, int q) {\n        if (root.data > Math.max(p, q)) {\n            return lowestCommonAncestor(root.left, p, q);\n        } else if (root.data < Math.min(p, q)) {\n            return lowestCommonAncestor(root.right, p, q);\n        } else {\n            return root;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/MorrisTraversal.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 03/08/2016\n * @author Tushar Roy\n *\n * Morris inorder/preorder traversals\n *\n * Time complexity O(n)\n * Space complexity O(1)\n */\npublic class MorrisTraversal {\n\n    public void inorder(Node root) {\n        Node current = root;\n        while(current != null) {\n            //left is null then print the node and go to right\n            if (current.left == null) {\n                System.out.print(current.data + \" \");\n                current = current.right;\n            }\n            else {\n                //find the predecessor.\n                Node predecessor = current.left;\n                //To find predecessor keep going right till right node is not null or right node is not current.\n                while(predecessor.right != current && predecessor.right != null){\n                    predecessor = predecessor.right;\n                }\n                //if right node is null then go left after establishing link from predecessor to current.\n                if(predecessor.right == null){\n                    predecessor.right = current;\n                    current = current.left;\n                }else{ //left is already visit. Go rigth after visiting current.\n                    predecessor.right = null;\n                    System.out.print(current.data + \" \");\n                    current = current.right;\n                }\n            }\n        }\n    }\n\n    public void preorder(Node root) {\n        Node current = root;\n        while (current != null) {\n            if(current.left == null) {\n                System.out.print(current.data + \" \");\n                current = current.right;\n            }\n            else {\n                Node predecessor = current.left;\n                while(predecessor.right != current && predecessor.right != null) {\n                    predecessor = predecessor.right;\n                }\n                if(predecessor.right == null){\n                    predecessor.right = current;\n                    System.out.print(current.data + \" \");\n                    current = current.left;\n                }else{\n                    predecessor.right = null;\n                    current = current.right;\n                }\n            }\n        }\n    }\n\n    public static void main(String args[]) {\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(50, root);\n        root = bt.addNode(-10, root);\n        root = bt.addNode(7, root);\n        root = bt.addNode(9, root);\n        root = bt.addNode(-20, root);\n        root = bt.addNode(30, root);\n        MorrisTraversal mt = new MorrisTraversal();\n        mt.inorder(root);\n        System.out.println();\n        mt.preorder(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/NextInorderSuccessorIterator.java",
    "content": "package com.interview.tree;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.Stack;\n\n/**\n * http://www.glassdoor.com/Interview/Create-an-iterator-to-traverse-a-binary-tree-When-the-next-function-is-called-on-the-binary-tree-return-the-value-at-the-QTN_674695.htm\n * null tree.\n */\npublic class NextInorderSuccessorIterator {\n\n    private Node root = null;\n    Stack<Node> stack = new Stack<Node>();\n    Set<Node> visited = new HashSet<Node>();\n    NextInorderSuccessorIterator(Node root){\n        this.root = root;\n    }\n    \n    public int next(){\n        Node node = null;\n        while(root != null){\n            stack.push(root);\n            root = root.left;\n        }\n        root = stack.pop();\n        node = root;\n        root = root.right;\n        return node.data;\n    }\n    \n    public boolean hasNext(){\n        if(root != null || stack.size() > 0){\n            return true;\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node node = null;\n        node = bt.addNode(10, node);\n        node = bt.addNode(-5, node);\n        node = bt.addNode(7, node);\n        node = bt.addNode(20, node);\n        node = bt.addNode(3, node);\n        node = bt.addNode(14, node);\n        NextInorderSuccessorIterator nis = new NextInorderSuccessorIterator(node);\n        while(nis.hasNext()){\n            System.out.println(nis.next());\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/NextInorderSuccessorOfTwoTree.java",
    "content": "package com.interview.tree;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.Stack;\n\n/**\n * Next inorder iterator of two trees.\n * Merging tree to print one result\n */\npublic class NextInorderSuccessorOfTwoTree {\n\n    private Node root1 = null;\n    private Node root2 = null;\n    Stack<Node> stack1 = new Stack<Node>();\n    Stack<Node> stack2 = new Stack<Node>();\n    Set<Node> visited = new HashSet<Node>();\n\n    NextInorderSuccessorOfTwoTree(Node root1, Node root2) {\n        this.root1 = root1;\n        this.root2 = root2;\n    }\n\n    public boolean hasNext() {\n        if (root1 != null || stack1.size() > 0 || root2 != null\n                || stack2.size() > 0) {\n            return true;\n        }\n        return false;\n    }\n\n    public Node next() {\n        Node node = null;\n        while (root1 != null) {\n            stack1.push(root1);\n            root1 = root1.left;\n        }\n        while (root2 != null) {\n            stack2.push(root2);\n            root2 = root2.left;\n        }\n        if (!stack1.isEmpty() && !stack2.isEmpty()) {\n            if (stack1.peek().data <= stack2.peek().data) {\n                node = stack1.pop();\n                root1 = node.right;\n            } else {\n                node = stack2.pop();\n                root2 = node.right;\n            }\n        } else if (stack1.isEmpty()) {\n            node = stack2.pop();\n            root2 = node.right;\n        } else {\n            node = stack1.pop();\n            root1 = node.right;\n        }\n        return node;\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node node = null;\n        node = bt.addNode(10, node);\n        node = bt.addNode(-5, node);\n        node = bt.addNode(7, node);\n        node = bt.addNode(20, node);\n        node = bt.addNode(3, node);\n        node = bt.addNode(14, node);\n     \n        Node node1 = null;\n        node1 = bt.addNode(8, node1);\n        node1 = bt.addNode(-10, node1);\n        node1 = bt.addNode(18, node1);\n        node1 = bt.addNode(2, node1);\n        node1 = bt.addNode(11, node1);\n        \n        NextInorderSuccessorOfTwoTree nis = new NextInorderSuccessorOfTwoTree(node, node1);\n        while(nis.hasNext()){\n            System.out.println(nis.next().data);\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/tree/NodesAtDistanceK.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/print-nodes-distance-k-given-node-binary-tree/\n * Test case \n * k should not be negative\n * k could be very big number which means nothing was found\n * dest might/might not exists in the tree\n * root could be null\n */\npublic class NodesAtDistanceK {\n\n    private void findInChild(Node root, int k){\n        if(root == null){\n            return;\n        }\n        if(k == 0){\n            System.out.println(root.data);\n        }\n        findInChild(root.left, k-1);\n        findInChild(root.right, k-1);\n    }\n    \n    public int printNodes(Node root,int dest, int k){\n        if(root == null){\n            return -1;\n        }\n        \n        if(root.data == dest){\n            findInChild(root, k);\n            return k-1;\n        }\n        \n        int found = printNodes(root.left,dest,k);\n        if(found != -1){\n            if(found == 0){\n                System.out.println(root.data);\n            }else{\n                findInChild(root.right, found-1);\n            }\n            return found -1;\n        }\n        \n        found = printNodes(root.right,dest,k);\n        if(found != -1){\n            if(found == 0){\n                System.out.println(root.data);\n            }else{\n                findInChild(root.left, found-1);\n            }\n            return found-1;\n        }\n        return -1;\n    }\n    \n    public static void main(String args[]){\n        NodesAtDistanceK nad = new NodesAtDistanceK();\n        Node root = null;\n        BinaryTree bt = new BinaryTree();\n        root = bt.addNode(10, root);\n        root = bt.addNode(3, root);\n        root = bt.addNode(-1, root);\n        root = bt.addNode(8, root);\n        root = bt.addNode(-6, root);\n        root = bt.addNode(-11, root);\n        root = bt.addNode(18, root);\n        root = bt.addNode(11, root);\n        root = bt.addNode(13, root);\n        root = bt.addNode(26, root);\n        root = bt.addNode(27, root);\n        nad.printNodes(root, 11, 2);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/NodesWithNoSibling.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/print-nodes-dont-sibling-binary-tree/\n * This does not print root node even though it has no sibling\n * Test cases:\n * Null tree\n * Only one node tree\n * All left side tree\n * All right side tree\n * Regular mix tree\n */\npublic class NodesWithNoSibling {\n\n    public void printNodes(Node root){\n        if(root == null){\n            return;\n        }\n        if(root.left == null || root.right == null){\n            if(root.left != null){\n                System.out.print(root.left.data + \" \");\n            }\n            if(root.right  != null){\n                System.out.print(root.right.data + \" \");\n            }\n        }\n        printNodes(root.left);\n        printNodes(root.right);\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(5, root);\n        root = bt.addNode(-1, root);\n        root = bt.addNode(-5, root);\n        root = bt.addNode(20, root);\n        root = bt.addNode(25, root);\n        NodesWithNoSibling nws = new NodesWithNoSibling();\n        nws.printNodes(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/PathSum.java",
    "content": "package com.interview.tree;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 10/06/2016\n * @author Tushar Roy\n *\n * Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.\n *\n * Time complexity O(n)\n *\n * https://leetcode.com/problems/path-sum/\n * https://leetcode.com/problems/path-sum-ii/\n */\npublic class PathSum {\n    public List<List<Integer>> pathSum(Node root, int sum) {\n        List<List<Integer>> result = new ArrayList<>();\n        List<Integer> current = new ArrayList<>();\n        pathSumUtil(root, sum, result, current);\n        return result;\n    }\n\n    private void pathSumUtil(Node root, int sum, List<List<Integer>> result, List<Integer> currentPath) {\n        if (root == null) {\n            return;\n        }\n        if (root.left == null && root.right == null) {\n            if (root.data == sum) {\n                currentPath.add(root.data);\n                result.add(new ArrayList<>(currentPath));\n                currentPath.remove(currentPath.size() - 1);\n            }\n            return;\n        }\n        currentPath.add(root.data);\n        pathSumUtil(root.left, sum - root.data, result, currentPath);\n        pathSumUtil(root.right, sum - root.data, result, currentPath);\n        currentPath.remove(currentPath.size() - 1);\n    }\n\n    public boolean hasPathSum(Node root, int sum) {\n        if (root == null) {\n            return false;\n        }\n        if (root.left == null && root.right == null) {\n            return root.data == sum;\n        }\n        return hasPathSum(root.left, sum - root.data) || hasPathSum(root.right, sum - root.data);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/PopulateInOrderSuccessor.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/populate-inorder-successor-for-all-nodes/\n */\npublic class PopulateInOrderSuccessor {\n\n    private void populate(Node root, NodeRef nodeRef){\n        if(root == null){\n            return;\n        }\n        populate(root.right,nodeRef);\n        root.next = nodeRef.node;\n        nodeRef.node = root;\n        populate(root.left,nodeRef);\n    }\n    \n    public void populate(Node root){\n        NodeRef nodeRef = new NodeRef();\n        populate(root,nodeRef);\n    }\n    \n    public void print(Node root){\n        if(root == null){\n            return;\n        }\n        System.out.println(root.data);\n        print(root.next);\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(-1, head);\n        head = bt.addNode(21, head);\n        PopulateInOrderSuccessor pio = new PopulateInOrderSuccessor();\n        pio.populate(head);\n        while(head.left != null){\n            head = head.left;\n        }\n        pio.print(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/PrintPostOrderFromPreOrderInOrder.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 11/02/2015\n * @author Tushar Roy\n *\n * Given a preorder/inorder traversal of binary tree create postorder traversal of binary tree\n * without creating the tree\n *\n * Time complexity - O(n)\n *\n * References\n * http://www.geeksforgeeks.org/print-postorder-from-given-inorder-and-preorder-traversals/\n */\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\npublic class PrintPostOrderFromPreOrderInOrder {\n\n    public int[] postOrder(int[] preorder, int[] inorder) {\n        int[] post = new int[inorder.length];\n        AtomicInteger postIndex = new AtomicInteger(post.length - 1);\n        postOrder(preorder, inorder, post, 0, inorder.length -1, 0, postIndex);\n        return post;\n    }\n\n    private void postOrder(int[] preorder, int[] inorder, int post[], int low, int high, int preIndex, AtomicInteger postIndex) {\n        if(low > high) {\n            return;\n        }\n        post[postIndex.getAndDecrement()] = preorder[preIndex];\n        int i;\n        for(i=0; i < inorder.length; i++) {\n            if(preorder[preIndex] == inorder[i]) {\n                break;\n            }\n        }\n        postOrder(preorder, inorder, post, i+1, high, preIndex + (i - low) + 1, postIndex);\n        postOrder(preorder, inorder, post, low, i-1, preIndex + 1, postIndex);\n    }\n\n    public static void main(String args[]) {\n        int preorder[] = {10, 5, 3, 21, 20, 18, 9 , 16};\n        int inorder[] = {3, 5, 21, 10, 18, 9, 20, 16};\n        PrintPostOrderFromPreOrderInOrder ppp = new PrintPostOrderFromPreOrderInOrder();\n        int postorder[] = ppp.postOrder(preorder, inorder);\n        for(int i : postorder) {\n            System.out.print(i + \" \");\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/PrintTwoBSTInSortedForm.java",
    "content": "package com.interview.tree;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * http://www.geeksforgeeks.org/merge-two-bsts-with-limited-extra-space/\n * Test cases\n * Both tree are null\n * One of the tree is null\n * All elements of one tree occur before other tree\n * All elements of one tree occur after other tree\n * Elements are mixed\n * All same elements\n */\npublic class PrintTwoBSTInSortedForm {\n\n    public void print(Node root1, Node root2){\n        Deque<Node> s1 = new LinkedList<Node>();\n        Deque<Node> s2 = new LinkedList<Node>();\n        \n        while(true){\n            if(root1 != null){\n                s1.addFirst(root1);\n                root1 = root1.left;\n                continue;\n            }\n            if(root2 != null){\n                s2.addFirst(root2);\n                root2 = root2.left;\n                continue;\n            }\n            if(!s1.isEmpty()){\n                root1 = s1.peekFirst();\n            }\n            if(!s2.isEmpty()){\n                root2 = s2.peekFirst();\n            }\n            if(root1 != null && root2 != null){\n                if(root1.data <= root2.data){\n                    System.out.println(root1.data);\n                    root1 = s1.pollFirst();\n                    root1 = root1.right;\n                    root2 = null;\n                }else{\n                    System.out.println(root2.data);\n                    root2 = s2.pollFirst();\n                    root2 = root2.right;\n                    root1 = null;\n                }\n            }\n            else if(root1 != null){\n                System.out.println(root1.data);\n                root1 = s1.pollFirst();\n                root1 = root1.right;\n            \n            }else if(root2 != null){\n                System.out.println(root2.data);\n                root2 = s2.pollFirst();\n                root2 = root2.right;\n            }\n            if(root1 == null && root2 == null && s1.isEmpty() && s2.isEmpty()){\n                break;\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        PrintTwoBSTInSortedForm ptb = new PrintTwoBSTInSortedForm();\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(-1, head);\n    \n        Node head1 = null;\n        head1 = bt.addNode(-4, head1);\n        head1 = bt.addNode(-3, head1);\n        head1 = bt.addNode(6, head1);\n        head1 = bt.addNode(11, head1);\n        head1 = bt.addNode(22, head1);\n        head1 = bt.addNode(26, head1);\n        \n        ptb.print(head, head1);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/RedBlackTree.java",
    "content": "package com.interview.tree;\n\nimport java.util.Optional;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.concurrent.atomic.AtomicReference;\n\n/**\n * Date 10/29/2015\n * @author Tushar Roy\n *\n * Red Black Tree\n *\n * Time complexity\n * Insert - O(logn)\n * Delete - O(logn)\n * Search - O(logn)\n *\n * Does not work for duplicates.\n *\n * References\n * http://pages.cs.wisc.edu/~skrentny/cs367-common/readings/Red-Black-Trees/\n * https://en.wikipedia.org/wiki/Red%E2%80%93black_tree\n */\npublic class RedBlackTree {\n\n    public enum Color {\n        RED,\n        BLACK\n    }\n\n    public static class Node {\n        int data;\n        Color color;\n        Node left;\n        Node right;\n        Node parent;\n        boolean isNullLeaf;\n    }\n\n    private static Node createBlackNode(int data) {\n        Node node = new Node();\n        node.data = data;\n        node.color = Color.BLACK;\n        node.left = createNullLeafNode(node);\n        node.right = createNullLeafNode(node);\n        return node;\n    }\n\n    private static Node createNullLeafNode(Node parent) {\n        Node leaf = new Node();\n        leaf.color = Color.BLACK;\n        leaf.isNullLeaf = true;\n        leaf.parent = parent;\n        return leaf;\n    }\n\n    private static Node createRedNode(Node parent, int data) {\n        Node node = new Node();\n        node.data = data;\n        node.color = Color.RED;\n        node.parent = parent;\n        node.left = createNullLeafNode(node);\n        node.right = createNullLeafNode(node);\n        return node;\n    }\n\n    /**\n     * Main insert method of red black tree.\n     */\n    public Node insert(Node root, int data) {\n        return insert(null, root, data);\n    }\n\n    /**\n     * Main delete method of red black tree.\n     */\n    public Node delete(Node root, int data) {\n        AtomicReference<Node> rootReference = new AtomicReference<>();\n        delete(root, data, rootReference);\n        if(rootReference.get() == null) {\n            return root;\n        } else {\n            return rootReference.get();\n        }\n    }\n\n    /**\n     * Main print method of red black tree.\n     */\n    public void printRedBlackTree(Node root) {\n        printRedBlackTree(root, 0);\n    }\n\n    /**\n     * Main validate method of red black tree.\n     */\n    public boolean validateRedBlackTree(Node root) {\n\n        if(root == null) {\n            return true;\n        }\n        //check if root is black\n        if(root.color != Color.BLACK) {\n            System.out.print(\"Root is not black\");\n            return false;\n        }\n        //Use of AtomicInteger solely because java does not provide any other mutable int wrapper.\n        AtomicInteger blackCount = new AtomicInteger(0);\n        //make sure black count is same on all path and there is no red red relationship\n        return checkBlackNodesCount(root, blackCount, 0) && noRedRedParentChild(root, Color.BLACK);\n    }\n\n    private void rightRotate(Node root, boolean changeColor) {\n        Node parent = root.parent;\n        root.parent = parent.parent;\n        if(parent.parent != null) {\n            if(parent.parent.right == parent) {\n                parent.parent.right = root;\n            } else {\n                parent.parent.left = root;\n            }\n        }\n        Node right = root.right;\n        root.right = parent;\n        parent.parent = root;\n        parent.left = right;\n        if(right != null) {\n            right.parent = parent;\n        }\n        if(changeColor) {\n            root.color = Color.BLACK;\n            parent.color = Color.RED;\n        }\n    }\n\n    private void leftRotate(Node root, boolean changeColor) {\n        Node parent = root.parent;\n        root.parent = parent.parent;\n        if(parent.parent != null) {\n            if(parent.parent.right == parent) {\n                parent.parent.right = root;\n            } else {\n                parent.parent.left = root;\n            }\n        }\n        Node left = root.left;\n        root.left = parent;\n        parent.parent = root;\n        parent.right = left;\n        if(left != null) {\n            left.parent = parent;\n        }\n        if(changeColor) {\n            root.color = Color.BLACK;\n            parent.color = Color.RED;\n        }\n    }\n\n    private Optional<Node> findSiblingNode(Node root) {\n        Node parent = root.parent;\n        if(isLeftChild(root)) {\n            return Optional.ofNullable(parent.right.isNullLeaf ? null : parent.right);\n        } else {\n            return Optional.ofNullable(parent.left.isNullLeaf ? null : parent.left);\n        }\n    }\n\n    private boolean isLeftChild(Node root) {\n        Node parent = root.parent;\n        if(parent.left == root) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    private Node insert(Node parent, Node root, int data) {\n        if(root  == null || root.isNullLeaf) {\n            //if parent is not null means tree is not empty\n            //so create a red leaf node\n            if(parent != null) {\n                return createRedNode(parent, data);\n            } else { //otherwise create a black root node if tree is empty\n                return createBlackNode(data);\n            }\n        }\n\n        //duplicate insertion is not allowed for this tree.\n        if(root.data == data) {\n            throw new IllegalArgumentException(\"Duplicate date \" + data);\n        }\n        //if we go on left side then isLeft will be true\n        //if we go on right side then isLeft will be false.\n        boolean isLeft;\n        if(root.data > data) {\n            Node left = insert(root, root.left, data);\n            //if left becomes root parent means rotation\n            //happened at lower level. So just return left\n            //so that nodes at upper level can set their\n            //child correctly\n            if(left == root.parent) {\n                return left;\n            }\n            //set the left child returned to be left of root node\n            root.left = left;\n            //set isLeft to be true\n            isLeft = true;\n        } else {\n            Node right = insert(root, root.right, data);\n            //if right becomes root parent means rotation\n            //happened at lower level. So just return right\n            //so that nodes at upper level can set their\n            //child correctly\n            if(right == root.parent) {\n                return right;\n            }\n            //set the right child returned to be right of root node\n            root.right = right;\n            //set isRight to be true\n            isLeft = false;\n        }\n\n        if(isLeft) {\n            //if we went to left side check to see Red-Red conflict\n            //between root and its left child\n            if(root.color == Color.RED && root.left.color == Color.RED) {\n                //get the sibling of root. It is returning optional means\n                //sibling could be empty\n                Optional<Node> sibling = findSiblingNode(root);\n                //if sibling is empty or of BLACK color\n                if(!sibling.isPresent() || sibling.get().color == Color.BLACK) {\n                    //check if root is left child of its parent\n                    if(isLeftChild(root)) {\n                        //this creates left left situation. So do one right rotate\n                        rightRotate(root, true);\n                    } else {\n                        //this creates left-right situation so do one right rotate followed\n                        //by left rotate\n\n                        //do right rotation without change in color. So sending false.\n                        //when right rotation is done root becomes right child of its left\n                        //child. So make root = root.parent because its left child before rotation\n                        //is new root of this subtree.\n                        rightRotate(root.left, false);\n                        //after rotation root should be root's parent\n                        root = root.parent;\n                        //then do left rotate with change of color\n                        leftRotate(root, true);\n                    }\n\n                } else {\n                    //we have sibling color as RED. So change color of root\n                    //and its sibling to Black. And then change color of their\n                    //parent to red if their parent is not a root.\n                    root.color = Color.BLACK;\n                    sibling.get().color = Color.BLACK;\n                    //if parent's parent is not null means parent is not root.\n                    //so change its color to RED.\n                    if(root.parent.parent != null) {\n                        root.parent.color = Color.RED;\n                    }\n                }\n            }\n        } else {\n            //this is mirror case of above. So same comments as above.\n            if(root.color == Color.RED && root.right.color == Color.RED) {\n                Optional<Node> sibling = findSiblingNode(root);\n                if(!sibling.isPresent() || sibling.get().color == Color.BLACK) {\n                    if(!isLeftChild(root)) {\n                        leftRotate(root, true);\n                    } else {\n                        leftRotate(root.right, false);\n                        root = root.parent;\n                        rightRotate(root, true);\n                    }\n                } else {\n                    root.color = Color.BLACK;\n                    sibling.get().color = Color.BLACK;\n                    if(root.parent.parent != null) {\n                        root.parent.color = Color.RED;\n                    }\n                }\n            }\n        }\n        return root;\n    }\n\n    /**\n     * Using atomicreference because java does not provide mutable wrapper. Its like\n     * double pointer in C.\n     */\n    private void delete(Node root, int data, AtomicReference<Node> rootReference) {\n        if(root == null || root.isNullLeaf) {\n            return;\n        }\n        if(root.data == data) {\n            //if node to be deleted has 0 or 1 null children then we have\n            //deleteOneChild use case as discussed in video.\n            if(root.right.isNullLeaf || root.left.isNullLeaf) {\n                deleteOneChild(root, rootReference);\n            } else {\n                //otherwise look for the inorder successor in right subtree.\n                //replace inorder successor data at root data.\n                //then delete inorder successor which should have 0 or 1 not null child.\n                Node inorderSuccessor = findSmallest(root.right);\n                root.data = inorderSuccessor.data;\n                delete(root.right, inorderSuccessor.data, rootReference);\n            }\n        }\n        //search for the node to be deleted.\n        if(root.data < data) {\n            delete(root.right, data, rootReference);\n        } else {\n            delete(root.left, data, rootReference);\n        }\n    }\n\n    private Node findSmallest(Node root) {\n        Node prev = null;\n        while(root != null && !root.isNullLeaf) {\n            prev = root;\n            root = root.left;\n        }\n        return prev != null ? prev : root;\n    }\n\n    /**\n     * Assumption that node to be deleted has either 0 or 1 non leaf child\n     */\n    private void deleteOneChild(Node nodeToBeDelete, AtomicReference<Node> rootReference) {\n        Node child = nodeToBeDelete.right.isNullLeaf ? nodeToBeDelete.left : nodeToBeDelete.right;\n        //replace node with either one not null child if it exists or null child.\n        replaceNode(nodeToBeDelete, child, rootReference);\n        //if the node to be deleted is BLACK. See if it has one red child.\n        if(nodeToBeDelete.color == Color.BLACK) {\n            //if it has one red child then change color of that child to be Black.\n            if(child.color == Color.RED) {\n                child.color = Color.BLACK;\n            } else {\n                //otherwise we have double black situation.\n                deleteCase1(child, rootReference);\n            }\n        }\n    }\n\n\n    /**\n     * If double black node becomes root then we are done. Turning it into\n     * single black node just reduces one black in every path.\n     */\n    private void deleteCase1(Node doubleBlackNode, AtomicReference<Node> rootReference) {\n        if(doubleBlackNode.parent == null) {\n            rootReference.set(doubleBlackNode);\n            return;\n        }\n        deleteCase2(doubleBlackNode, rootReference);\n    }\n\n    /**\n     * If sibling is red and parent and sibling's children are black then rotate it\n     * so that sibling becomes black. Double black node is still double black so we need\n     * further processing.\n     */\n    private void deleteCase2(Node doubleBlackNode, AtomicReference<Node> rootReference) {\n        Node siblingNode = findSiblingNode(doubleBlackNode).get();\n        if(siblingNode.color == Color.RED) {\n            if(isLeftChild(siblingNode)) {\n                rightRotate(siblingNode, true);\n            } else {\n                leftRotate(siblingNode, true);\n            }\n            if(siblingNode.parent == null) {\n                rootReference.set(siblingNode);\n            }\n        }\n        deleteCase3(doubleBlackNode, rootReference);\n    }\n\n    /**\n     * If sibling, sibling's children and parent are all black then turn sibling into red.\n     * This reduces black node for both the paths from parent. Now parent is new double black\n     * node which needs further processing by going back to case1.\n     */\n    private void deleteCase3(Node doubleBlackNode, AtomicReference<Node> rootReference) {\n\n        Node siblingNode = findSiblingNode(doubleBlackNode).get();\n\n        if(doubleBlackNode.parent.color == Color.BLACK && siblingNode.color == Color.BLACK && siblingNode.left.color == Color.BLACK\n                && siblingNode.right.color == Color.BLACK) {\n            siblingNode.color = Color.RED;\n            deleteCase1(doubleBlackNode.parent, rootReference);\n        } else {\n            deleteCase4(doubleBlackNode, rootReference);\n        }\n    }\n\n    /**\n     * If sibling color is black, parent color is red and sibling's children color is black then swap color b/w sibling\n     * and parent. This increases one black node on double black node path but does not affect black node count on\n     * sibling path. We are done if we hit this situation.\n     */\n    private void deleteCase4(Node doubleBlackNode, AtomicReference<Node> rootReference) {\n        Node siblingNode = findSiblingNode(doubleBlackNode).get();\n        if(doubleBlackNode.parent.color == Color.RED && siblingNode.color == Color.BLACK && siblingNode.left.color == Color.BLACK\n        && siblingNode.right.color == Color.BLACK) {\n            siblingNode.color = Color.RED;\n            doubleBlackNode.parent.color = Color.BLACK;\n            return;\n        } else {\n            deleteCase5(doubleBlackNode, rootReference);\n        }\n    }\n\n    /**\n     * If sibling is black, double black node is left child of its parent, siblings right child is black\n     * and sibling's left child is red then do a right rotation at siblings left child and swap colors.\n     * This converts it to delete case6. It will also have a mirror case.\n     */\n    private void deleteCase5(Node doubleBlackNode, AtomicReference<Node> rootReference) {\n        Node siblingNode = findSiblingNode(doubleBlackNode).get();\n        if(siblingNode.color == Color.BLACK) {\n            if (isLeftChild(doubleBlackNode) && siblingNode.right.color == Color.BLACK && siblingNode.left.color == Color.RED) {\n                rightRotate(siblingNode.left, true);\n            } else if (!isLeftChild(doubleBlackNode) && siblingNode.left.color == Color.BLACK && siblingNode.right.color == Color.RED) {\n                leftRotate(siblingNode.right, true);\n            }\n        }\n        deleteCase6(doubleBlackNode, rootReference);\n    }\n\n    /**\n     * If sibling is black, double black node is left child of its parent, sibling left child is black and sibling's right child is\n     * red, sibling takes its parent color, parent color becomes black, sibling's right child becomes black and then do\n     * left rotation at sibling without any further change in color. This removes double black and we are done. This\n     * also has a mirror condition.\n     */\n    private void deleteCase6(Node doubleBlackNode, AtomicReference<Node> rootReference) {\n        Node siblingNode = findSiblingNode(doubleBlackNode).get();\n        siblingNode.color = siblingNode.parent.color;\n        siblingNode.parent.color = Color.BLACK;\n        if(isLeftChild(doubleBlackNode)) {\n            siblingNode.right.color = Color.BLACK;\n            leftRotate(siblingNode, false);\n        } else {\n            siblingNode.left.color = Color.BLACK;\n            rightRotate(siblingNode, false);\n        }\n        if(siblingNode.parent == null) {\n            rootReference.set(siblingNode);\n        }\n    }\n\n    private void replaceNode(Node root, Node child, AtomicReference<Node> rootReference) {\n        child.parent = root.parent;\n        if(root.parent == null) {\n            rootReference.set(child);\n        }\n        else {\n            if(isLeftChild(root)) {\n                root.parent.left = child;\n            } else {\n                root.parent.right = child;\n            }\n        }\n    }\n\n    private void printRedBlackTree(Node root, int space) {\n        if(root == null || root.isNullLeaf) {\n            return;\n        }\n        printRedBlackTree(root.right, space + 5);\n        for(int i=0; i < space; i++) {\n            System.out.print(\" \");\n        }\n        System.out.println(root.data + \" \" + (root.color == Color.BLACK ? \"B\" : \"R\"));\n        printRedBlackTree(root.left, space + 5);\n    }\n\n    private boolean noRedRedParentChild(Node root, Color parentColor) {\n        if(root == null) {\n            return true;\n        }\n        if(root.color == Color.RED && parentColor == Color.RED) {\n            return false;\n        }\n\n        return noRedRedParentChild(root.left, root.color) && noRedRedParentChild(root.right, root.color);\n    }\n\n    private boolean checkBlackNodesCount(Node root, AtomicInteger blackCount, int currentCount) {\n\n        if(root.color == Color.BLACK) {\n            currentCount++;\n        }\n\n        if(root.left == null && root.right == null) {\n            if(blackCount.get() == 0) {\n                blackCount.set(currentCount);\n                return true;\n            } else {\n                return currentCount == blackCount.get();\n            }\n        }\n        return checkBlackNodesCount(root.left, blackCount, currentCount) && checkBlackNodesCount(root.right, blackCount, currentCount);\n    }\n\n    public static void main(String args[]) {\n        Node root = null;\n        RedBlackTree redBlackTree = new RedBlackTree();\n\n        root = redBlackTree.insert(root, 10);\n        root = redBlackTree.insert(root, 15);\n        root = redBlackTree.insert(root, -10);\n        root = redBlackTree.insert(root, 20);\n        root = redBlackTree.insert(root, 30);\n        root = redBlackTree.insert(root, 40);\n        root = redBlackTree.insert(root, 50);\n        root = redBlackTree.insert(root, -15);\n        root = redBlackTree.insert(root, 25);\n        root = redBlackTree.insert(root, 17);\n        root = redBlackTree.insert(root, 21);\n        root = redBlackTree.insert(root, 24);\n        root = redBlackTree.insert(root, 28);\n        root = redBlackTree.insert(root, 34);\n        root = redBlackTree.insert(root, 32);\n        root = redBlackTree.insert(root, 26);\n        root = redBlackTree.insert(root, 35);\n        root = redBlackTree.insert(root, 19);\n        redBlackTree.printRedBlackTree(root);\n\n        root = redBlackTree.delete(root, 50);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 40);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, -10);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 15);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 17);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 24);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 21);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 32);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 26);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 19);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 25);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 17);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, -15);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 20);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 35);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 34);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 30);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 28);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n        root = redBlackTree.delete(root, 10);\n        System.out.println(redBlackTree.validateRedBlackTree(root));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/RootToLeafToSum.java",
    "content": "package com.interview.tree;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Date 04/11/2015\n * @author tusroy\n * \n * Youtube link - https://youtu.be/Jg4E4KZstFE\n * \n * Given a binary tree and a sum, find if there is a path from root to leaf\n * which sums to this sum.\n * \n * Solution\n * Keep going left and right and keep subtracting node value from sum.\n * If leaf node is reached check if whatever sum is remaining same as leaf node data.\n * \n * Time complexity is O(n) since all nodes are visited.\n * \n * Test cases:\n * Negative number, 0 and positive number\n * Tree with 0, 1 or more nodes\n * \n * Reference http://www.geeksforgeeks.org/root-to-leaf-path-sum-equal-to-a-given-number/\n */\npublic class RootToLeafToSum {\n\n    public boolean printPath(Node root, int sum, List<Node> path){\n        if(root == null){\n            return false;\n        }\n\n        if(root.left == null && root.right == null){\n            if(root.data == sum){\n                path.add(root);\n                return true;\n            }else{\n                return false;\n            }\n        }\n        if(printPath(root.left, sum-root.data, path) || printPath(root.right, sum - root.data, path)){\n            path.add(root);\n            return true;\n        }\n        return false;\n    }\n    \n    public static void main(String args[]){\n        RootToLeafToSum rtl = new RootToLeafToSum();\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(4, head);\n        head = bt.addNode(3, head);\n        List<Node> result = new ArrayList<>();\n        boolean r = rtl.printPath(head, 22, result);\n        if(r){\n            result.forEach(node -> System.out.print(node.data + \" \"));\n        }else{\n            System.out.println(\"No path for sum \" + 22); \n        }\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/SameTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 04/11/2015\n * @author tusroy\n * \n * Youtube link - https://youtu.be/ySDDslG8wws\n * \n * Given roots of two tree, return true if they have same data and same structure\n * or return false.\n * \n * Solution\n * Keep comparing root of both data and then recursively check left and right.\n * \n * Time complexity is O(n)\n */\npublic class SameTree {\n\n    public boolean sameTree(Node root1, Node root2){\n        if(root1 == null && root2 == null){\n            return true;\n        }\n        if(root1 == null || root2 == null){\n            return false;\n        }\n        \n        return root1.data == root2.data && \n                sameTree(root1.left, root2.left) &&\n                sameTree(root1.right, root2.right);\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node root1 = null;\n        root1 = bt.addNode(10, root1);\n        root1 = bt.addNode(20, root1);\n        root1 = bt.addNode(15, root1);\n        root1 = bt.addNode(2, root1);\n\n        Node root2 = null;\n        root2 = bt.addNode(10, root2);\n        root2 = bt.addNode(20, root2);\n        root2 = bt.addNode(15, root2);\n        root2 = bt.addNode(2, root2);\n        \n        SameTree st = new SameTree();\n        assert st.sameTree(root1, root2);\n   }\n}\n"
  },
  {
    "path": "src/com/interview/tree/SegmentTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 08/21/2014\n * @author tusroy\n * \n * Video link - https://youtu.be/ZBHKZF5w4YU\n *\n * A segment tree is a tree data structure for storing intervals, or segments. It allows \n * for faster querying (e.g sum or min) in these intervals.\n * Write a program to support these operations for sum\n * createSegmentTree(int arr[]) - create segment tree\n * query(int segment[], int startRange, int endRange) - query in this range\n * \n * Similar segment trees can be created for min or max.\n * \n * Time complexity to create segment tree is O(nlogn)\n * Space complexity to create segment tree is O(nlogn)\n * Time complexity to search in segment tree is O(logn)\n \n * References\n * http://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/\n * http://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/\n */\npublic class SegmentTree {\n\n    public int[] createTree(int input[], Operation operation){\n        int height = (int)Math.ceil(Math.log(input.length)/Math.log(2));\n        int segmentTree[] = new int[(int)(Math.pow(2, height+1)-1)];\n        constructTree(segmentTree,input,0,input.length-1,0, operation);\n        return segmentTree;\n    }\n    \n    private void constructTree(int segmentTree[], int input[], int low, int high,int pos, Operation operation){\n        if(low == high){\n            segmentTree[pos] = input[low];\n            return;\n        }\n        int mid = (low + high)/2;\n        constructTree(segmentTree,input,low,mid,2*pos+1, operation);\n        constructTree(segmentTree,input,mid+1,high,2*pos+2, operation);\n        segmentTree[pos] = operation.perform(segmentTree[2*pos+1], segmentTree[2*pos+2]);\n    }\n    \n    public int rangeQuery(int []segmentTree,int qlow,int qhigh,int len, Operation operation){\n        return rangeQuery(segmentTree,0,len-1,qlow,qhigh,0, operation);\n    }\n    \n    private int rangeQuery(int segmentTree[],int low,int high,int qlow,int qhigh,int pos, Operation operation){\n        if(qlow <= low && qhigh >= high){\n            return segmentTree[pos];\n        }\n        if(qlow > high || qhigh < low){\n            return 0;\n        }\n        int mid = (low+high)/2;\n        return operation.perform(rangeQuery(segmentTree,low,mid,qlow,qhigh,2*pos+1, operation),\n                rangeQuery(segmentTree,mid+1,high,qlow,qhigh,2*pos+2, operation));\n    }\n    \n    public void updateValueForSumOperation(int input[],int segmentTree[],int newVal,int index){\n        int diff = newVal - input[index];\n        input[index] = newVal;\n        updateVal(segmentTree,0,input.length-1,diff,index,0);\n    }\n    \n    private void updateVal(int segmentTree[],int low,int high,int diff,int index, int pos){\n        if(index < low || index > high){\n            return;\n        }\n        segmentTree[pos] += diff;\n        if(low >= high){\n            return;\n        }\n        int mid = (low + high)/2;\n        updateVal(segmentTree,low,mid,diff,index,2*pos+1);\n        updateVal(segmentTree,mid+1,high,diff,index,2*pos+2);\n    }\n    \n    public static void main(String args[]){\n        int input[] = {1,3,5,7,9,11};\n        SegmentTree st = new SegmentTree();\n        Operation sumOp = new SumOperation();\n        Operation minOp = new MinOperation();\n        int result [] = st.createTree(input, sumOp);\n        for(int i=0; i < result.length; i++){\n            System.out.print(result[i] + \" \");\n        }\n        int input1[] = {3,4,2,1,6,-1};\n        int result1[] = st.createTree(input1, minOp);\n        for(int i=0; i < result1.length; i++){\n            System.out.print(result1[i] + \" \");\n        }\n        \n        st.updateValueForSumOperation(input, result,0 , 0);\n        System.out.println();\n        for(int i=0; i < result.length; i++){\n            System.out.print(result[i] + \" \");\n        }\n        \n    }\n}\n\n/**\n * Provides interface to perform operations on range queue like sum or min \n */\ninterface Operation{\n    int perform(int a, int b);\n}\n\nclass SumOperation implements Operation{\n\n    @Override\n    public int perform(int a, int b) {\n        return a+b;\n    }\n}\n\nclass MinOperation implements Operation{\n    @Override\n    public int perform(int a, int b){\n        return Math.min(a,b);\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/tree/SegmentTreeMinimumRangeQuery.java",
    "content": "package com.interview.tree;\n\nimport com.interview.bits.NextPowerOf2;\n\n/**\n * Date 08/22/2015\n * @author Tushar Roy\n * \n * A segment tree is a tree data structure for storing intervals, or segments. It allows \n * for faster querying (e.g sum or min) in these intervals. Lazy propagation is useful\n * when there are high number of updates in the input array.\n\n * Write a program to support mininmum range query\n * createSegmentTree(int arr[]) - create segment tree\n * query(int segment[], int startRange, int endRange) - returns minimum between startRange and endRange\n * update(int input[], int segment[], int indexToBeUpdated, int newVal) - updates input and segmentTree with newVal at index indexToBeUpdated;\n * updateRange(int input[], int segment[], int lowRange, int highRange, int delta) - updates all the values in given range by\n * adding delta to them\n * queryLazy(int segment[], int startRange, int endRange) - query based off lazy propagation\n *\n * Time complexity to create segment tree is O(n) since new array will be at max 4n size\n * Space complexity to create segment tree is O(n) since new array will be at max 4n size\n * Time complexity to search in segment tree is O(logn) since you would at max travel 4 depths\n * Time complexity to update in segment tree is O(logn)\n * Time complexity to update range in segment tree is O(range)\n * \n * References\n * http://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/\n * http://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/\n * https://www.topcoder.com/community/data-science/data-science-tutorials/range-minimum-query-and-lowest-common-ancestor/\n */\npublic class SegmentTreeMinimumRangeQuery {\n\n    /**\n     * Creates a new segment tree based off input array.\n     */\n    public int[] createSegmentTree(int input[]){\n        NextPowerOf2 np2 = new NextPowerOf2();\n        //if input len is pow of 2 then size of \n        //segment tree is 2*len - 1, otherwise\n        //size of segment tree is next (pow of 2 for len)*2 - 1.\n        int nextPowOfTwo = np2.nextPowerOf2(input.length);\n        int segmentTree[] = new int[nextPowOfTwo*2 -1];\n        \n        for(int i=0; i < segmentTree.length; i++){\n            segmentTree[i] = Integer.MAX_VALUE;\n        }\n        constructMinSegmentTree(segmentTree, input, 0, input.length - 1, 0);\n        return segmentTree;\n        \n    }\n\n    /**\n     * Updates segment tree for certain index by given delta\n     */\n    public void updateSegmentTree(int input[], int segmentTree[], int index, int delta){\n        input[index] += delta;\n        updateSegmentTree(segmentTree, index, delta, 0, input.length - 1, 0);\n    }\n\n    /**\n     * Updates segment tree for given range by given delta\n     */\n    public void updateSegmentTreeRange(int input[], int segmentTree[], int startRange, int endRange, int delta) {\n        for(int i = startRange; i <= endRange; i++) {\n            input[i] += delta;\n        }\n        updateSegmentTreeRange(segmentTree, startRange, endRange, delta, 0, input.length - 1, 0);\n    }\n\n    /**\n     * Queries given range for minimum value.\n     */\n    public int rangeMinimumQuery(int []segmentTree,int qlow,int qhigh,int len){\n        return rangeMinimumQuery(segmentTree,0,len-1,qlow,qhigh,0);\n    }\n\n    /**\n     * Updates given range by given delta lazily\n     */\n    public void updateSegmentTreeRangeLazy(int input[], int segmentTree[], int lazy[], int startRange, int endRange, int delta) {\n        updateSegmentTreeRangeLazy(segmentTree, lazy, startRange, endRange, delta, 0, input.length - 1, 0);\n    }\n\n    /**\n     * Queries given range lazily\n     */\n    public int rangeMinimumQueryLazy(int segmentTree[], int lazy[], int qlow, int qhigh, int len) {\n        return rangeMinimumQueryLazy(segmentTree, lazy, qlow, qhigh, 0, len - 1, 0);\n    }\n\n    private void constructMinSegmentTree(int segmentTree[], int input[], int low, int high,int pos){\n        if(low == high){\n            segmentTree[pos] = input[low];\n            return;\n        }\n        int mid = (low + high)/2;\n        constructMinSegmentTree(segmentTree, input, low, mid, 2 * pos + 1);\n        constructMinSegmentTree(segmentTree, input, mid + 1, high, 2 * pos + 2);\n        segmentTree[pos] = Math.min(segmentTree[2*pos+1], segmentTree[2*pos+2]);\n    }\n    \n    private void updateSegmentTree(int segmentTree[], int index, int delta, int low, int high, int pos){\n       \n        //if index to be updated is less than low or higher than high just return.\n        if(index < low || index > high){\n            return;\n        }\n        \n        //if low and high become equal, then index will be also equal to them and update\n        //that value in segment tree at pos\n        if(low == high){\n            segmentTree[pos] += delta;\n            return;\n        }\n        //otherwise keep going left and right to find index to be updated \n        //and then update current tree position if min of left or right has\n        //changed.\n        int mid = (low + high)/2;\n        updateSegmentTree(segmentTree, index, delta, low, mid, 2 * pos + 1);\n        updateSegmentTree(segmentTree, index, delta, mid + 1, high, 2 * pos + 2);\n        segmentTree[pos] = Math.min(segmentTree[2*pos+1], segmentTree[2*pos + 2]);\n    }\n\n    private void updateSegmentTreeRange(int segmentTree[], int startRange, int endRange, int delta, int low, int high, int pos) {\n        if(low > high || startRange > high || endRange < low ) {\n            return;\n        }\n\n        if(low == high) {\n            segmentTree[pos] += delta;\n            return;\n        }\n\n        int middle = (low + high)/2;\n        updateSegmentTreeRange(segmentTree, startRange, endRange, delta, low, middle, 2 * pos + 1);\n        updateSegmentTreeRange(segmentTree, startRange, endRange, delta, middle + 1, high, 2 * pos + 2);\n        segmentTree[pos] = Math.min(segmentTree[2*pos+1], segmentTree[2*pos+2]);\n    }\n\n    private int rangeMinimumQuery(int segmentTree[],int low,int high,int qlow,int qhigh,int pos){\n        if(qlow <= low && qhigh >= high){\n            return segmentTree[pos];\n        }\n        if(qlow > high || qhigh < low){\n            return Integer.MAX_VALUE;\n        }\n        int mid = (low+high)/2;\n        return Math.min(rangeMinimumQuery(segmentTree, low, mid, qlow, qhigh, 2 * pos + 1),\n                rangeMinimumQuery(segmentTree, mid + 1, high, qlow, qhigh, 2 * pos + 2));\n    }\n\n    private void updateSegmentTreeRangeLazy(int segmentTree[],\n                                            int lazy[], int startRange, int endRange,\n                                            int delta, int low, int high, int pos) {\n        if(low > high) {\n            return;\n        }\n\n        //make sure all propagation is done at pos. If not update tree\n        //at pos and mark its children for lazy propagation.\n        if (lazy[pos] != 0) {\n            segmentTree[pos] += lazy[pos];\n            if (low != high) { //not a leaf node\n                lazy[2 * pos + 1] += lazy[pos];\n                lazy[2 * pos + 2] += lazy[pos];\n            }\n            lazy[pos] = 0;\n        }\n\n        //no overlap condition\n        if(startRange > high || endRange < low) {\n            return;\n        }\n\n        //total overlap condition\n        if(startRange <= low && endRange >= high) {\n            segmentTree[pos] += delta;\n            if(low != high) {\n                lazy[2*pos + 1] += delta;\n                lazy[2*pos + 2] += delta;\n            }\n            return;\n        }\n\n        //otherwise partial overlap so look both left and right.\n        int mid = (low + high)/2;\n        updateSegmentTreeRangeLazy(segmentTree, lazy, startRange, endRange,\n                delta, low, mid, 2*pos+1);\n        updateSegmentTreeRangeLazy(segmentTree, lazy, startRange, endRange,\n                delta, mid+1, high, 2*pos+2);\n        segmentTree[pos] = Math.min(segmentTree[2*pos + 1], segmentTree[2*pos + 2]);\n    }\n\n    private int rangeMinimumQueryLazy(int segmentTree[], int lazy[], int qlow, int qhigh,\n                                      int low, int high, int pos) {\n\n        if(low > high) {\n            return Integer.MAX_VALUE;\n        }\n\n        //make sure all propagation is done at pos. If not update tree\n        //at pos and mark its children for lazy propagation.\n        if (lazy[pos] != 0) {\n            segmentTree[pos] += lazy[pos];\n            if (low != high) { //not a leaf node\n                lazy[2 * pos + 1] += lazy[pos];\n                lazy[2 * pos + 2] += lazy[pos];\n            }\n            lazy[pos] = 0;\n        }\n\n        //no overlap\n        if(qlow > high || qhigh < low){\n            return Integer.MAX_VALUE;\n        }\n\n        //total overlap\n        if(qlow <= low && qhigh >= high){\n            return segmentTree[pos];\n        }\n\n        //partial overlap\n        int mid = (low+high)/2;\n        return Math.min(rangeMinimumQueryLazy(segmentTree, lazy, qlow, qhigh,\n                        low, mid, 2 * pos + 1),\n                rangeMinimumQueryLazy(segmentTree, lazy,  qlow, qhigh,\n                        mid + 1, high, 2 * pos + 2));\n\n    }\n\n    public static void main(String args[]){\n        SegmentTreeMinimumRangeQuery st = new SegmentTreeMinimumRangeQuery();\n\n        int input[] = {0,3,4,2,1,6,-1};\n        int segTree[] = st.createSegmentTree(input);\n\n        //non lazy propagation example\n        assert 0 == st.rangeMinimumQuery(segTree, 0, 3, input.length);\n        assert 1 == st.rangeMinimumQuery(segTree, 1, 5, input.length);\n        assert -1 == st.rangeMinimumQuery(segTree, 1, 6, input.length);\n        st.updateSegmentTree(input, segTree, 2, 1);\n        assert 2 == st.rangeMinimumQuery(segTree, 1, 3, input.length);\n        st.updateSegmentTreeRange(input, segTree, 3, 5, -2);\n        assert -1 == st.rangeMinimumQuery(segTree, 5, 6, input.length);\n        assert 0 == st.rangeMinimumQuery(segTree, 0, 3, input.length);\n\n        //lazy propagation example\n        int input1[] = {-1,2,4,1,7,1,3,2};\n        int segTree1[] = st.createSegmentTree(input1);\n        int lazy1[] =  new int[segTree.length];\n        st.updateSegmentTreeRangeLazy(input1, segTree1, lazy1, 0, 3, 1);\n        st.updateSegmentTreeRangeLazy(input1, segTree1, lazy1, 0, 0, 2);\n        assert 1 == st.rangeMinimumQueryLazy(segTree1, lazy1, 3, 5, input1.length);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/SerializeDeserializeBinaryTree.java",
    "content": "package com.interview.tree;\n\nimport javax.swing.tree.TreeNode;\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * Date 03/12/2016\n * @author Tushar Roy\n *\n * Serialize/Deserialize a binary tree whose data is a number.\n *\n *  Time complexity O(n)\n *  Space complexity O(n)\n *\n * Reference\n * https://leetcode.com/problems/serialize-and-deserialize-binary-tree/\n */\npublic class SerializeDeserializeBinaryTree {\n\n    /**\n     * Serialize Tree using preorder DFS\n     * @param root\n     * @return\n     */\n    public String serialize(Node root) {\n        StringBuffer buff = new StringBuffer();\n        serializeUtil(root, buff);\n        return buff.toString();\n    }\n\n    private void serializeUtil(Node root, StringBuffer buff) {\n        if (root == null) {\n            buff.append(\"%,\");\n            return;\n        }\n\n        buff.append(root.data).append(\",\");\n        if (root.left != null || root.right != null) {\n            buff.append(\"$,\");\n            serializeUtil(root.left, buff);\n            serializeUtil(root.right, buff);\n        } else {\n            return;\n        }\n\n    }\n    int index = 0;\n\n    /**\n     * Deserialize Tree using preorder DFS\n     * @param data\n     * @return\n     */\n    public Node deserialize(String data) {\n        String[] input = data.split(\",\");\n        index = 0;\n        return deserializeUtil(input);\n    }\n\n    private Node deserializeUtil(String input[]) {\n        if (index == input.length) {\n            return null;\n        }\n\n        if (input[index].equals(\"%\")) {\n            index++;\n            return null;\n        }\n        Node n = new Node();\n        n.data = Integer.parseInt(input[index]);\n        if (index < input.length - 1) {\n            if (input[index + 1].equals(\"$\")) {\n                index += 2;\n                n.left = deserializeUtil(input);\n                n.right = deserializeUtil(input);\n            } else {\n                index++;\n            }\n        }\n        return n;\n    }\n\n    /**\n     * Serialize tree using level order traversal.\n     */\n    public String serializeLevelOrder(Node root) {\n        if (root == null) {\n            return \"\";\n        }\n\n        Deque<Node> queue = new LinkedList<>();\n        queue.offerFirst(root);\n        StringBuffer buff = new StringBuffer();\n        while (!queue.isEmpty()) {\n            root = queue.pollFirst();\n            if (root == null) {\n                buff.append(\"%,\");\n            } else {\n                buff.append(root.data).append(\",\");\n                queue.offer(root.left);\n                queue.offer(root.right);\n            }\n        }\n        for (int i = buff.length() - 1; i >= 0; i--) {\n            if (buff.charAt(i) == '%' || buff.charAt(i) == ',') {\n                buff.deleteCharAt(i);\n            } else {\n                break;\n            }\n        }\n        return buff.toString();\n    }\n\n    /**\n     * Deserialize Tree using level order traversal.\n     */\n    public Node deserializeLevelOrder(String data) {\n        if (data == null || data.length() == 0) {\n            return null;\n        }\n        String[] input = data.split(\",\");\n        Deque<Node> queue = new LinkedList<>();\n        int index = 0;\n        queue.offerFirst(Node.newNode(Integer.parseInt(input[index])));\n        Node root = queue.peekFirst();\n        index++;\n        while (!queue.isEmpty()) {\n            Node current = queue.pollFirst();\n            if (index < input.length && !input[index].equals(\"%\")) {\n                current.left = Node.newNode(Integer.parseInt(input[index]));\n                queue.offerLast(current.left);\n            }\n            index++;\n            if (index < input.length && !input[index].equals(\"%\")) {\n                current.right = Node.newNode(Integer.parseInt(input[index]));\n                queue.offerLast(current.right);\n            }\n            index++;\n        }\n        return root;\n    }\n\n\n    public static void main(String args[]) {\n        SerializeDeserializeBinaryTree sd = new SerializeDeserializeBinaryTree();\n        Node node = sd.deserialize(\"10,$,30,15,$,%,20,$,21,16,$,%,18\");\n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(node);\n        String serializedTree= sd.serializeLevelOrder(node);\n        Node root = sd.deserializeLevelOrder(\"1,2\");\n        tt.inOrder(root);\n    }\n}\n\n"
  },
  {
    "path": "src/com/interview/tree/SinkNegativeToBottom.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.careercup.com/question?id=5344154741637120\n */\npublic class SinkNegativeToBottom {\n\n    public void sinkZero(Node root) {\n        if (root == null) {\n            return;\n        }\n\n        sinkZero(root.left);\n        sinkZero(root.right);\n\n        if (root.data < 0) {\n            pushDown(root);\n        }\n    }\n\n    private void pushDown(Node root) {\n        if(root == null){\n            return;\n        }\n        // find a child with non zero node value\n        if (root.left == null && root.right == null) {\n            // already leaf node. nothing to do. just return\n            return;\n        }\n\n        //if root left is not null and root left data is not 0 pick it to swap\n        if (root.left != null && root.left.data >= 0) {\n            int temp = root.data;\n            root.data = root.left.data;\n            root.left.data = temp;\n            pushDown(root.left);\n        }\n        else if(root.right != null && root.right.data >= 0){\n            int temp = root.data;\n            root.data = root.right.data;\n            root.right.data = temp;\n            pushDown(root.right);\n        }\n    }\n    \n    public static void main(String args[]){\n        int preorder[] = {-1,1,6,-2,11,3,2,-3,31,22,17};\n        int inorder[]  = {-2,6,11,1,3,-1,31,-3,22,2,17};\n        ConstructTreeFromInOrderPreOrder ctf = new ConstructTreeFromInOrderPreOrder();\n        Node root = ctf.createTree(inorder, preorder);\n        SinkNegativeToBottom szb = new SinkNegativeToBottom();\n        szb.sinkZero(root);\n        LevelOrderTraversal lot = new LevelOrderTraversal();\n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(root);\n        lot.levelOrder(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/SizeOfBinaryTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 03/05/2015\n * @author tusroy\n * \n * Given a root of binary tree, return size of binar tree\n * \n * Solution:\n * Recursively find size of left side, right side and add one to them and return that to calling function.\n * \n * Time complexity - O(n)\n * Space complexity(because of recursion stack) - height of binary tree. Worst case O(n)\n * \n * Test cases:\n * Null tree\n * 1 node tree\n * multi node tree\n */\npublic class SizeOfBinaryTree {\n\n    public int size(Node root){\n        if(root == null){\n            return 0;\n        }\n        return size(root.left) + size(root.right) + 1;\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(5, head);\n        head = bt.addNode(7, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(20, head);\n        head = bt.addNode(-1, head);\n        SizeOfBinaryTree sbt = new SizeOfBinaryTree();\n        System.out.println(sbt.size(head));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/SortedArrayToBST.java",
    "content": "package com.interview.tree;\n\n/**\n * Date 10/06/2016\n * @author Tushar Roy\n *\n * Given an array where elements are sorted in ascending order, convert it to a height balanced BST.\n *\n * Time complexity O(n)\n * \n * Reference\n * https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/\n */\npublic class SortedArrayToBST {\n    public Node sortedArrayToBST(int[] nums) {\n        return toBST(nums, 0, nums.length - 1);\n    }\n\n    private Node toBST(int[] nums, int low, int high) {\n        if (low > high) {\n            return null;\n        }\n        int mid = (low + high)/2;\n        Node n = Node.newNode(nums[mid]);\n        n.left = toBST(nums, low, mid - 1);\n        n.right = toBST(nums, mid + 1, high);\n        return n;\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/SortedOrderPrintCompleteTreeArray.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/sorted-order-printing-of-an-array-that-represents-a-bst/\n * Test case\n * empty array\n * 1 element array\n * multi element array\n */\npublic class SortedOrderPrintCompleteTreeArray {\n\n    private void print(int arr[],int current){\n        if(current >= arr.length){\n            return;\n        }\n        print(arr,2*current+1);\n        System.out.println(arr[current]);\n        print(arr,2*current+2);\n    }\n    \n    public void print(int arr[]){\n        print(arr,0);\n    }\n    \n    public static void main(String args[]){\n        int arr[] = {4, 2, 5, 1, 3};\n        SortedOrderPrintCompleteTreeArray sop = new SortedOrderPrintCompleteTreeArray();\n        sop.print(arr);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/SuccinctTree.java",
    "content": "package com.interview.tree;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n *  Date 11/01/2015\n *  @author Tushar\n *\n *  Encode and decode binary tree using succinct encoding technique\n *\n * References - http://www.geeksforgeeks.org/succinct-encoding-of-binary-tree/\n * https://en.wikipedia.org/wiki/Binary_tree#Succinct_encodings\n */\npublic class SuccinctTree {\n\n    public static class Result {\n        List<Integer> binaryRep = new ArrayList<>();\n        List<Integer> actualData = new ArrayList<>();\n    }\n\n    public Result encode(Node root) {\n        Result r = new Result();\n        encode(root, r);\n        return r;\n    }\n\n    private void encode(Node root, Result r) {\n        if(root == null) {\n            r.binaryRep.add(0);\n            return;\n        }\n        r.actualData.add(root.data);\n        r.binaryRep.add(1);\n\n        encode(root.left, r);\n        encode(root.right, r);\n    }\n\n    public Node decode(Result r) {\n        AtomicInteger x = new AtomicInteger(0);\n        AtomicInteger y = new AtomicInteger(0);\n        return decode(r, x, y);\n    }\n\n    private Node decode(Result r, AtomicInteger x, AtomicInteger y) {\n        if(r.binaryRep.get(x.get()) == 0) {\n            x.getAndIncrement();\n            return null;\n        }\n\n        Node root = new Node();\n        root.data = r.actualData.get(y.getAndIncrement());\n        x.getAndIncrement();\n        root.left = decode(r, x, y);\n        root.right = decode(r, x, y);\n        return root;\n    }\n\n    public static void main(String args[]) {\n        Node root = null;\n        BinaryTree bt = new BinaryTree();\n        root = bt.addNode(10, root);\n        root = bt.addNode(-10, root);\n        root = bt.addNode(20, root);\n        root = bt.addNode(15, root);\n        root = bt.addNode(-7, root);\n        root = bt.addNode(22, root);\n        root = bt.addNode(-4, root);\n        root = bt.addNode(12, root);\n        System.out.println(\"Before decoding\");\n        TreeTraversals tt = new TreeTraversals();\n        tt.inOrder(root);\n        System.out.println();\n        tt.preOrder(root);\n        System.out.println();\n        SuccinctTree st = new SuccinctTree();\n        Result r = st.encode(root);\n        root = st.decode(r);\n        System.out.println(\"After decoding\");\n        tt.inOrder(root);\n        System.out.println();\n        tt.preOrder(root);\n    }\n\n}\n"
  },
  {
    "path": "src/com/interview/tree/SumTree.java",
    "content": "package com.interview.tree;\n\n\nclass Count{\n    int size;\n}\n\n/**\n * http://www.geeksforgeeks.org/check-if-a-given-binary-tree-is-sumtree/\n * A SumTree is a Binary Tree where the value of a node is equal to sum of the nodes present \n * in its left subtree and right subtree\n */\npublic class SumTree {\n\n    public boolean isSumTree(Node root){\n        Count count = new Count();\n        return isSumTree(root,count);\n    }\n    \n    private boolean isSumTree(Node root,Count count){\n        if(root == null){\n            return true;\n        }\n        if(root.left == null && root.right == null){\n            count.size = root.data;\n            return true;\n        }\n        Count leftCount = new Count();\n        Count rightCount = new Count();\n        boolean isLeft = isSumTree(root.left,leftCount);\n        boolean isRight = isSumTree(root.right,rightCount);\n        count.size = root.data + leftCount.size + rightCount.size;\n        return isLeft && isRight && root.data == (leftCount.size + rightCount.size);\n    }\n    \n    public static void main(String args[]){\n        ConstructTreeFromInOrderPreOrder ctf = new ConstructTreeFromInOrderPreOrder();\n        int inorder[] = {4,10,6,46,11,13,2};\n        int preorder[] = {46,10,4,6,13,11,2};\n        Node root = ctf.createTree(inorder, preorder);\n        SumTree st = new SumTree();\n        System.out.println(st.isSumTree(root));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/TreeIsomorphism.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/tree-isomorphism-problem/\n * Test cases:\n * Same tree\n * Exact mirror\n * Some nodes flipped\n */\npublic class TreeIsomorphism {\n\n    public boolean areIsomorphicTrees(Node root1, Node root2) {\n        if (root1 == null && root2 == null) {\n            return true;\n        }\n        \n        if(root1 == null || root2 == null){\n            return false;\n        }\n\n        return root1.data == root2.data\n                && ((areIsomorphicTrees(root1.left, root2.left) && areIsomorphicTrees(\n                        root1.right, root2.right)) || (areIsomorphicTrees(\n                        root1.left, root2.right) && areIsomorphicTrees(\n                        root1.right, root2.left)));\n\n    }\n    \n    public static void main(String args[]){\n        int in1[] = {8,5,6,10,11,9,12};\n        int pre1[] = {10,5,8,6,9,11,12};\n        int in2[] = {11,9,12,10,6,5,15};\n        int pre2[] = {10,9,11,12,5,6,15};\n        ConstructTreeFromInOrderPreOrder ct = new ConstructTreeFromInOrderPreOrder();\n        Node root1 = ct.createTree(in1, pre1);\n        Node root2 = ct.createTree(in2, pre2);\n        TreeIsomorphism ti = new TreeIsomorphism();\n        System.out.println(ti.areIsomorphicTrees(root1, root2));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/TreeTraversalInSpiralOrder.java",
    "content": "package com.interview.tree;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\nimport java.util.Stack;\n\n/**\n * Date 04/16/2015\n * @author tusroy\n *\n * Video link - https://youtu.be/vjt5Y6-1KsQ\n *\n * Given a root of binary tree, print in spiral order. \n * e.g               1 \n *             2           3 \n *        4       5     6      7\n *      8   9  10    11 \n * should print 1 3 2 4 5 6 7 8 9 10 11\n *\n * Solution 1 : Use two stack. Put root in stack1. While stack1 is not\n * empty take items from stack1 and put its child left,right in stack2.\n * Then once stack1 is empty pop from stack2 and put its child right,\n * left into stack1.\n * \n * Solution 2 : Use one dequeue. Technique is like above but instead of\n * using two stack use dequeue. Also keep count till which point you read\n * in the dequeue.\n * \n * Solution 3: Use one dequeue. Use a delimiter to separate between one \n * stack growing from top and another one growing from bottom.\n *         \n * Time complexity is O(n) \n * Space complexity is O(n)\n *\n * Reference\n * https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/\n */\npublic class TreeTraversalInSpiralOrder {\n\n    /**\n     * Two stack to print in spiral way\n     */\n    public void spiralWithTwoStack(Node root) {\n        if (root == null) {\n            return;\n        }\n        Stack<Node> s1 = new Stack<>();\n        Stack<Node> s2 = new Stack<>();\n        s1.push(root);\n\n        while (!s1.isEmpty() || !s2.isEmpty()) {\n            while (!s1.isEmpty()) {\n                root = s1.pop();\n                System.out.print(root.data + \" \");\n                if (root.left != null) {\n                    s2.push(root.left);\n                }\n                if (root.right != null) {\n                    s2.push(root.right);\n                }\n            }\n            while (!s2.isEmpty()) {\n                root = s2.pop();\n                System.out.print(root.data + \" \");\n                if (root.right != null) {\n                    s1.push(root.right);\n                }\n                if (root.left != null) {\n                    s1.push(root.left);\n                }\n            }\n        }\n    }\n\n    /**\n     * One deque with count method to print tree in spiral order\n     */\n    public void spiralWithOneDeque(Node root) {\n        if (root == null) {\n            return;\n        }\n        Deque<Node> deque = new LinkedList<Node>();\n        deque.offerFirst(root);\n        int count = 1;\n        boolean flip = true;\n        while (!deque.isEmpty()) {\n            int currentCount = 0;\n            while (count > 0) {\n                if (flip) {\n                    root = deque.pollFirst();\n                    System.out.print(root.data + \" \");\n                    if (root.left != null) {\n                        deque.offerLast(root.left);\n                        currentCount++;\n                    }\n                    if (root.right != null) {\n                        deque.offerLast(root.right);\n                        currentCount++;\n                    }\n                } else {\n                    root = deque.pollLast();\n                    System.out.print(root.data + \" \");\n                    if (root.right != null) {\n                        deque.offerFirst(root.right);\n                        currentCount++;\n                    }\n                    if (root.left != null) {\n                        deque.offerFirst(root.left);\n                        currentCount++;\n                    }\n                }\n                count--;\n            }\n            flip = !flip;\n            count = currentCount;\n        }\n    }\n\n    /**\n     * One deque with delimiter to print tree in spiral order\n     */\n    public void spiralWithOneDequeDelimiter(Node root)\n    {\n        if(root == null){\n            return;\n        }\n        Deque<Node> q = new LinkedList<>();\n        q.offer(null);\n        q.offerFirst(root);\n        //if only delimiter(in this case null) is left in queue then break\n        while(q.size() > 1){\n            root = q.peekFirst();\n            while(root != null){\n                root = q.pollFirst();\n                System.out.print(root.data + \" \");\n                if(root.left != null){\n                    q.offerLast(root.left);\n                }\n                if(root.right != null){\n                    q.offerLast(root.right);\n                }\n                root = q.peekFirst();\n            }\n            root = q.peekLast();\n            while(root != null){\n                System.out.print(root.data + \" \");\n                root = q.pollLast();\n                if(root.right != null){\n                    q.offerFirst(root.right);\n                }\n                if(root.left != null){\n                    q.offerFirst(root.left);\n                }\n                root = q.peekLast();\n            }\n        }\n    }\n    public static void main(String args[]) {\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(30, root);\n        root = bt.addNode(25, root);\n        root = bt.addNode(35, root);\n        root = bt.addNode(-10, root);\n        root = bt.addNode(0, root);\n        root = bt.addNode(-20, root);\n        root = bt.addNode(-15, root);\n        root = bt.addNode(45, root);\n\n        TreeTraversalInSpiralOrder tt = new TreeTraversalInSpiralOrder();\n        System.out.println(\"Two stack method\");\n        tt.spiralWithTwoStack(root);\n        System.out.println(\"\\nOne deque with count\");\n        tt.spiralWithOneDeque(root);\n        System.out.println(\"\\nOne deque with delimiter\");\n        tt.spiralWithOneDequeDelimiter(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/TreeTraversalLevelByLevel.java",
    "content": "package com.interview.tree;\n\nimport java.util.LinkedList;\nimport java.util.Queue;\n\n/**\n * Date 04/18/2015\n * @author tusroy\n * \n * Video link - https://youtu.be/7uG0gLDbhsI\n * \n * Given a binary tree print each level on new line.\n * \n * e.g           10\n *           5         15\n *         0   -1    2    6\n * Output :   10\n *            5 15\n *            0 -1 2 6\n *            \n * Solution\n * Technique 1:\n * Use 2 queue. Keep polling from q1 and offer to q2 till q1 is empty. \n * After that print a new line. Keep polling from q2 and offer to q1 \n * till q2 is empty. Keep doing this still both q1 and q2 are empty.\n * \n * Technique 2\n * Use one queue with delimiter. Add a delimiter null after every level.\n * As soon as you encounter a null print a new line and add null at end of queue\n * \n * Technique 3\n * Use one queue with count. Keep count of nodes at every level. As soon as this \n * count is 0 print a new line.\n * \n * Time space complexity for all above algorithm is O(n).\n */\npublic class TreeTraversalLevelByLevel {\n\n    /**\n     * Use two queue to print level by level\n     */\n    public void levelByLevelTwoQueue(Node root) {\n        if (root == null) {\n            return;\n        }\n        Queue<Node> q1 = new LinkedList<>();\n        Queue<Node> q2 = new LinkedList<>();\n        q1.add(root);\n        while (!q1.isEmpty() || !q2.isEmpty()) {\n            while (!q1.isEmpty()) {\n                root = q1.poll();\n                System.out.print(root.data + \" \");\n                if (root.left != null) {\n                    q2.offer(root.left);\n                }\n                if (root.right != null) {\n                    q2.offer(root.right);\n                }\n            }\n            System.out.println();\n            while (!q2.isEmpty()) {\n                root = q2.poll();\n                System.out.print(root.data + \" \");\n                if (root.left != null) {\n                    q1.offer(root.left);\n                }\n                if (root.right != null) {\n                    q1.offer(root.right);\n                }\n            }\n            System.out.println();\n        }\n    }\n\n    /**\n     * Use one queue and delimiter to print level by level\n     */\n    public void levelByLevelOneQueueUsingDelimiter(Node root) {\n        if (root == null) {\n            return;\n        }\n        Queue<Node> q = new LinkedList<Node>();\n        q.offer(root);\n        q.offer(null);\n        while (!q.isEmpty()) {\n            root = q.poll();\n            if (root != null) {\n                System.out.print(root.data + \" \");\n                if (root.left != null) {\n                    q.offer(root.left);\n                }\n                if (root.right != null) {\n                    q.offer(root.right);\n                }\n            } else {\n                if (!q.isEmpty()) {\n                    System.out.println();\n                    q.offer(null);\n                }\n            }\n        }\n    }\n\n    /**\n     * Use one queue and count to print level by level\n     */\n    public void levelByLevelOneQueueUsingCount(Node root) {\n        if (root == null) {\n            return;\n        }\n        Queue<Node> q = new LinkedList<Node>();\n        int levelCount = 1;\n        int currentCount = 0;\n        q.offer(root);\n        while (!q.isEmpty()) {\n            while (levelCount > 0) {\n                root = q.poll();\n                System.out.print(root.data + \" \");\n                if (root.left != null) {\n                    currentCount++;\n                    q.offer(root.left);\n                }\n                if (root.right != null) {\n                    currentCount++;\n                    q.offer(root.right);\n                }\n                levelCount--;\n            }\n            System.out.println();\n            levelCount = currentCount;\n            currentCount = 0;\n        }\n    }\n\n    public static void main(String args[]) {\n        TreeTraversalLevelByLevel tt = new TreeTraversalLevelByLevel();\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(20, root);\n        root = bt.addNode(30, root);\n        root = bt.addNode(15, root);\n        root = bt.addNode(-10, root);\n        root = bt.addNode(0, root);\n        root = bt.addNode(5, root);\n        root = bt.addNode(-5, root);\n        root = bt.addNode(-15, root);\n        root = bt.addNode(27, root);\n        root = bt.addNode(35, root);\n        System.out.println(\"1. Two queue technique\");\n        tt.levelByLevelTwoQueue(root);\n        System.out.println(\"\\n2. One queue and delimiter\");\n        tt.levelByLevelOneQueueUsingDelimiter(root);\n        System.out.println(\"\\n\\n3. One queue and count\");\n        tt.levelByLevelOneQueueUsingCount(root);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/TreeTraversals.java",
    "content": "package com.interview.tree;\n\nimport java.util.Deque;\nimport java.util.LinkedList;\n\n/**\n * Youtube link - https://youtu.be/nzmtCFNae9k\n * Youtube link - https://youtu.be/elQcrJrfObg\n * Youtube link - https://youtu.be/qT65HltK2uE\n * Youtube link - https://youtu.be/ZM-sV9zQPEs\n * \n * http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/\n * http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/\n * http://www.geeksforgeeks.org/iterative-preorder-traversal/\n */\npublic class TreeTraversals {\n\n    public void inOrder(Node root){\n        if(root == null){\n            return;\n        }\n        inOrder(root.left);\n        System.out.print(root.data + \" \");\n        inOrder(root.right);\n    }\n    \n    public void preOrder(Node root){\n        if(root == null){\n            return;\n        }\n        System.out.print(root.data + \" \");\n        preOrder(root.left);\n        preOrder(root.right);\n    }\n    \n    public void postOrder(Node root){\n        if(root == null){\n            return;\n        }\n        postOrder(root.left);\n        postOrder(root.right);\n        System.out.print(root.data + \" \");\n    }\n\n    public void inorderItr(Node root){\n        Deque<Node> stack = new LinkedList<Node>();\n        Node node = root;\n        while(true){\n            if(node != null){\n                stack.addFirst(node);\n                node = node.left;\n            }\n            else{\n                if(stack.isEmpty()){\n                    break;\n                }\n                node = stack.pollFirst();\n                System.out.println(node.data);\n                node = node.right;\n            }\n        }\n    }\n    \n    public void preOrderItr(Node root){\n        Deque<Node> stack = new LinkedList<Node>();\n        stack.addFirst(root);\n        while(!stack.isEmpty()){\n            root = stack.pollFirst();\n            System.out.print(root.data + \" \");\n            if(root.right != null){\n                stack.addFirst(root.right);\n            }\n            if(root.left!= null){\n                stack.addFirst(root.left);\n            }\n        }\n    }\n    \n    public void postOrderItr(Node root){\n        Deque<Node> stack1 = new LinkedList<Node>();\n        Deque<Node> stack2 = new LinkedList<Node>();\n        stack1.addFirst(root);\n        while(!stack1.isEmpty()){\n            root = stack1.pollFirst();\n            if(root.left != null){\n                stack1.addFirst(root.left);\n            }\n            if(root.right != null){\n                stack1.addFirst(root.right);\n            }\n            stack2.addFirst(root);\n        }\n        while(!stack2.isEmpty()){\n            System.out.print(stack2.pollFirst().data + \" \");\n        }\n    }\n    \n    public void postOrderItrOneStack(Node root){\n        Node current = root;\n        Deque<Node> stack = new LinkedList<>();\n        while(current != null || !stack.isEmpty()){\n            if(current != null){\n                stack.addFirst(current);\n                current = current.left;\n            }else{\n                Node temp = stack.peek().right;\n                if (temp == null) {\n                    temp = stack.poll();\n                    System.out.print(temp.data + \" \");\n                    while (!stack.isEmpty() && temp == stack.peek().right) {\n                        temp = stack.poll();\n                        System.out.print(temp.data + \" \");\n                    }\n                } else {\n                    current = temp;\n                }\n            }\n        }\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(10, head);\n        head = bt.addNode(15, head);\n        head = bt.addNode(19, head);\n        head = bt.addNode(17, head);\n        head = bt.addNode(11, head);\n\n        head = bt.addNode(-11, head);\n\n\n        TreeTraversals tt = new TreeTraversals();\n        tt.postOrder(head);\n        System.out.println();\n        tt.postOrderItr(head);\n        System.out.println();\n        tt.postOrderItrOneStack(head);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/UpsidedownBinaryTree.java",
    "content": "package com.interview.tree;\n\n/**\n * Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that\n * shares the same parent node) or empty, flip it upside down and turn it into a tree where the original\n * right nodes turned into left leaf nodes. Return the new root.\n *\n * https://leetcode.com/problems/binary-tree-upside-down/\n */\npublic class UpsidedownBinaryTree {\n    public Node upsideDownBinaryTree(Node root) {\n        if (root == null) {\n            return null;\n        }\n        return upsideDownBinaryTree(root, null, null);\n    }\n\n    public Node upsideDownBinaryTree(Node root, Node parent, Node rightChild) {\n        if (root == null) {\n            return parent;\n        }\n        Node left = root.left;\n        Node right = root.right;\n\n        root.right = parent;\n        root.left = rightChild;\n\n        return upsideDownBinaryTree(left, root, right);\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/VertexCoverBinaryTreeDP.java",
    "content": "package com.interview.tree;\n\n/**\n * http://www.geeksforgeeks.org/vertex-cover-problem-set-2-dynamic-programming-solution-tree/\n * http://en.wikipedia.org/wiki/Vertex_cover\n * Using lis to store the cover data\n * Test cases:\n * null root\n * Only left child\n * Only right child\n * Tree with only one child at every node\n */\npublic class VertexCoverBinaryTreeDP {\n\n    public int cover(Node root){\n        if(root == null){\n            return 0;\n        }\n        //no need to include leaf node ever\n        if(root.left == null && root.right == null){\n            return 0;\n        }\n        //store result\n        if(root.lis != -1){\n            return root.lis;\n        }\n        //if root is included\n        int inclRoot = 1 + cover(root.left) + cover(root.right);\n        int exclRoot = 0;\n        //if root is not included\n        if(root.left!=null){\n            exclRoot += (1 + cover(root.left.left) + cover(root.left.right));\n        }\n        if(root.right!=null){\n            exclRoot += (1 + cover(root.right.left) + cover(root.right.right));\n        }\n        root.lis = Math.min(inclRoot, exclRoot);\n        return root.lis;\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node root = null;\n        root = bt.addNode(10, root);\n        root = bt.addNode(0, root);\n        root = bt.addNode(-5, root);\n        root = bt.addNode(5, root);\n        root = bt.addNode(7, root);\n        root = bt.addNode(3, root);\n        root = bt.addNode(30, root);\n        root = bt.addNode(40, root);\n        root = bt.addNode(25, root);\n        root = bt.addNode(46, root);\n        root = bt.addNode(-8, root);\n        root = bt.addNode(-2, root);\n        root = bt.addNode(-1, root);\n        root = bt.addNode(28, root);\n        VertexCoverBinaryTreeDP vc = new VertexCoverBinaryTreeDP();\n        System.out.println(vc.cover(root));\n    }\n}\n"
  },
  {
    "path": "src/com/interview/tree/VerticalOrder.java",
    "content": "package com.interview.tree;\n\nimport java.util.*;\n\n/**\n * Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bottom, column by column).\n * If two nodes are in the same row and column, the order should be from left to right.\n *\n * https://leetcode.com/problems/binary-tree-vertical-order-traversal/\n */\npublic class VerticalOrder {\n    public List<List<Integer>> verticalOrder(Node root) {\n        if (root == null) {\n            return new ArrayList<>();\n        }\n        int minVal = 0;\n        int maxVal = 0;\n        Map<Integer, List<Integer>> map = new HashMap<>();\n\n        Deque<Node> queue = new LinkedList<>();\n        Deque<Integer> verticalQueue = new LinkedList<>();\n\n        queue.offerFirst(root);\n        verticalQueue.offerFirst(0);\n        int vertical;\n        while (!queue.isEmpty()) {\n            root = queue.pollFirst();\n            vertical = verticalQueue.pollFirst();\n            minVal = Math.min(minVal, vertical);\n            maxVal = Math.max(maxVal, vertical);\n\n            List<Integer> r = map.get(vertical);\n            if (r == null) {\n                r = new ArrayList<>();\n                map.put(vertical, r);\n            }\n            r.add(root.data);\n\n            if (root.left != null) {\n                queue.offerLast(root.left);\n                verticalQueue.offerLast(vertical - 1);\n            }\n\n            if (root.right != null) {\n                queue.offerLast(root.right);\n                verticalQueue.offerLast(vertical + 1);\n            }\n        }\n\n        List<List<Integer>> result = new ArrayList<>();\n        for (int i = minVal; i <= maxVal; i++) {\n            List<Integer> r = map.get(i);\n            result.add(r);\n        }\n        return result;\n    }\n}"
  },
  {
    "path": "src/com/interview/tree/VerticalTreePrinting.java",
    "content": "package com.interview.tree;\n\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.util.List;\nimport java.util.TreeMap;\n\n/**\n * http://www.geeksforgeeks.org/print-binary-tree-vertical-order-set-2/\n */\npublic class VerticalTreePrinting {\n\n    public void printVertical(Node root){\n        Map<Integer,List<Node>> map = new TreeMap<Integer,List<Node>>();\n        populateMap(root,map,0);\n        printLevel(map);\n    }\n    \n    private void printLevel(Map<Integer,List<Node>> map){\n        for(Integer key : map.keySet()){\n            List<Node> listNodes = map.get(key);\n            for(Node n : listNodes){\n                System.out.print(n.data + \" \");\n            }\n            System.out.println();\n        }\n    }\n    \n    private void populateMap(Node root, Map<Integer,List<Node>> map,int level){\n        if(root == null){\n            return;\n        }\n        List<Node> listNodes = null;\n        if(map.containsKey(level)){\n            listNodes = map.get(level);\n        }else{\n            listNodes = new ArrayList<Node>();\n            map.put(level, listNodes);\n        }\n        listNodes.add(root);\n        populateMap(root.left,map,level-1);\n        populateMap(root.right,map,level+1);\n    }\n    \n    public static void main(String args[]){\n        BinaryTree bt = new BinaryTree();\n        Node head = null;\n        head = bt.addNode(3, head);\n        head = bt.addNode(-6, head);\n        head = bt.addNode(-7, head);\n        head = bt.addNode(2, head);\n        head = bt.addNode(9, head);\n        head = bt.addNode(6, head);\n        head = bt.addNode(11, head);\n        head = bt.addNode(13, head);\n        head = bt.addNode(12, head);\n        VerticalTreePrinting vtp = new VerticalTreePrinting();\n        vtp.printVertical(head);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/TestUtil.java",
    "content": "package com.interview;\n\nimport org.junit.Assert;\n\nimport java.util.List;\n\npublic class TestUtil<T> {\n    public void compareList(List<T> expected, List<T> actual) {\n        int i = 0;\n        for (T str : expected) {\n            Assert.assertEquals(\"Failed at index \" + i, str, actual.get(i++));\n        }\n    }\n\n    public void compareListOfList(List<List<T>> expected, List<List<T>> actual) {\n        Assert.assertEquals(expected.size(), actual.size());\n        for (int i = 0; i < expected.size(); i++) {\n            List<T> a1 = expected.get(i);\n            List<T> a2 = expected.get(i);\n            compareList(a1, a2);\n        }\n    }\n}\n"
  },
  {
    "path": "test/com/interview/array/AdditiveNumberTest.java",
    "content": "package com.interview.array;\n\nimport org.junit.Assert;\n\npublic class AdditiveNumberTest {\n    public static void main(String args[]) {\n        AdditiveNumber additiveNumber = new AdditiveNumber();\n        Assert.assertTrue(additiveNumber.isAdditiveNumber(\"12351174\"));\n        Assert.assertFalse(additiveNumber.isAdditiveNumber(\"1023\"));\n        Assert.assertTrue(additiveNumber.isAdditiveNumber(\"198019823962\"));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/array/ArrayAdditionTest.java",
    "content": "package com.interview.array;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class ArrayAdditionTest {\n\n    @Test\n    public void testAddSimple() {\n        ArrayAddition arrayAddition = new ArrayAddition();\n        int arr1[] = {9,9,9,9,9,9,9};\n        int arr2[] = {1,6,8,2,6,7};\n        int[] result = arrayAddition.add(arr1, arr2);\n        int[] expected = {1, 0, 1, 6, 8, 2, 6, 6};\n        Assert.assertArrayEquals(expected, result);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/array/MaximumMinimumArrangementTest.java",
    "content": "package com.interview.array;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class MaximumMinimumArrangementTest {\n    @Test\n    public void differentCases() {\n        MaximumMinimumArrangement maximumMinimumArrangement = new MaximumMinimumArrangement();\n        int[] input1 = {1, 2, 3, 4, 5, 6, 7};\n        maximumMinimumArrangement.rearrange(input1);\n        int[] expected1 = {7, 1, 6, 2, 5, 3, 4};\n        Assert.assertArrayEquals(expected1, input1);\n\n        int[] input2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n        maximumMinimumArrangement.rearrange(input2);\n        int[] expected2 = {10, 1, 9, 2, 8, 3, 7, 4, 6, 5};\n        Assert.assertArrayEquals(expected2, input2);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/array/MeetingRoomsTest.java",
    "content": "package com.interview.array;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport java.util.Arrays;\n\npublic class MeetingRoomsTest {\n\n    @Test\n    public void testDifferentCases() {\n        MeetingRooms meetingRooms = new MeetingRooms();\n        MeetingRooms.Interval[] interval = new MeetingRooms.Interval[4];\n        interval[0] = new MeetingRooms.Interval(0,3);\n        interval[1] = new MeetingRooms.Interval(2,5);\n        interval[2] = new MeetingRooms.Interval(6,8);\n        interval[3] = new MeetingRooms.Interval(8,10);\n        Assert.assertEquals(2, meetingRooms.minMeetingRooms(interval));\n        Assert.assertEquals(2, meetingRooms.minMeetingRooms1(interval));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/array/MultiplyAllFieldsExceptOwnPositionTest.java",
    "content": "package com.interview.array;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class MultiplyAllFieldsExceptOwnPositionTest {\n\n    @Test\n    public void testDifferentCases() {\n        MultiplyAllFieldsExceptOwnPosition mop = new MultiplyAllFieldsExceptOwnPosition();\n        int[] input1 = {0, 9, -2};\n        int[] output1 = {-18, 0, 0};\n        Assert.assertArrayEquals(output1, mop.multiply(input1));\n\n        int[] input2 = {1, 1};\n        int[] output2 = {1, 1};\n        Assert.assertArrayEquals(output2, mop.multiply(input2));\n\n        int[] input3 = {3, 1, -3, 6};\n        int[] output3 = {-18, -54, 18, -9};\n        Assert.assertArrayEquals(output3, mop.multiply(input3));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/array/NumberOfTriangledInUnsortedArrayTest.java",
    "content": "package com.interview.array;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class NumberOfTriangledInUnsortedArrayTest {\n\n    @Test\n    public void testSimpleCase() {\n        NumberOfTrianglesInUnsortedArray numberOfTrianglesInUnsortedArray = new NumberOfTrianglesInUnsortedArray();\n        int[] input = {3, 4, 5, 6, 8, 9, 15};\n        int result = numberOfTrianglesInUnsortedArray.numberOfTriangles(input);\n        Assert.assertEquals(15, result);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/array/ThreeSumSmallerThanTargetTest.java",
    "content": "package com.interview.array;\n\nimport junit.framework.Assert;\nimport org.junit.Test;\n\npublic class ThreeSumSmallerThanTargetTest {\n\n    @Test\n    public void testDifferentCases() {\n        ThreeSumSmallerThanTarget threeSumSmallerThanTarget = new ThreeSumSmallerThanTarget();\n        int[] input = {-2, 0, 1, 3};\n        Assert.assertEquals(2, threeSumSmallerThanTarget.threeSumSmaller(input, 2));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/bits/CountingBitsTillNumTest.java",
    "content": "package com.interview.bits;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * Created by tushar_v_roy on 4/3/16.\n */\npublic class CountingBitsTillNumTest {\n\n    @Test\n    public void testDifferentCases() {\n        CountingBitsTillNum countingBitsTillNum = new CountingBitsTillNum();\n        int[] expected1 = {0, 1, 1};\n        int[] expected2 = {0, 1, 1, 2, 1, 2};\n        int[] expected3 = {0, 1, 1, 2, 1, 2, 2, 3, 1};\n        int[] expected4 = {0, 1, 1, 2, 1, 2, 2, 3 ,1, 2, 2, 3};\n\n        Assert.assertArrayEquals(expected1, countingBitsTillNum.countBits(2));\n        Assert.assertArrayEquals(expected2, countingBitsTillNum.countBits(5));\n        Assert.assertArrayEquals(expected3, countingBitsTillNum.countBits(8));\n        Assert.assertArrayEquals(expected4, countingBitsTillNum.countBits(11));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/bits/MaxProductWordLengthTest.java",
    "content": "package com.interview.bits;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class MaxProductWordLengthTest {\n\n    @Test\n    public void testDifferentCases() {\n        MaxProductWordLength maxProductWordLength = new MaxProductWordLength();\n        String[] words1 = {\"abcw\", \"baz\", \"foo\", \"bar\", \"xtfn\", \"abcdef\"};\n        Assert.assertEquals(16, maxProductWordLength.maxProduct(words1));\n\n        String[] words2 = {\"a\", \"ab\", \"abc\", \"d\", \"cd\", \"bcd\", \"abcd\"};\n        Assert.assertEquals(4, maxProductWordLength.maxProduct(words2));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/dynamic/DecodeWaysTest.java",
    "content": "package com.interview.dynamic;\n\nimport org.junit.Test;\n\npublic class DecodeWaysTest {\n    @Test\n    public void testDifferentCases() {\n        DecodeWays decodeWays = new DecodeWays();\n        System.out.println(decodeWays.numDecodings(\"20320\"));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/dynamic/PalindromePartitionTest.java",
    "content": "package com.interview.dynamic;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class PalindromePartitionTest {\n\n    @Test\n    public void testAllPartitions() {\n        PalindromePartition palindromePartition = new PalindromePartition();\n        List<List<String>> result = palindromePartition.partition(\"aab\");\n\n        List<List<String>> expected = new ArrayList<>();\n        List<String> r1 = new ArrayList<>();\n        r1.add(\"a\");\n        r1.add(\"a\");\n        r1.add(\"b\");\n\n        expected.add(r1);\n        r1 = new ArrayList<>();\n        r1.add(\"aa\");\n        r1.add(\"b\");\n        expected.add(r1);\n        int index = 0;\n        for (List<String> r : result) {\n            Assert.assertEquals(expected.get(index++), r);\n        }\n    }\n\n    @Test\n    public void palindromePartitionMinCuts() {\n        PalindromePartition palindromePartition = new PalindromePartition();\n        Assert.assertEquals(3, palindromePartition.minCut(\"ABCCDCCLMLCCD\"));\n        Assert.assertEquals(0, palindromePartition.minCut(\"bb\"));\n        Assert.assertEquals(0, palindromePartition.minCut(\"b\"));\n\n    }\n}\n"
  },
  {
    "path": "test/com/interview/graph/CourseScheduleTest.java",
    "content": "package com.interview.graph;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class CourseScheduleTest {\n\n    @Test\n    public void testDifferentCases() {\n        CourseSchedule cs = new CourseSchedule();\n        int[][] courses = {{1,0},{2,0},{3,1},{3,2}};\n        int[] output = cs.findOrder(4, courses);\n        int[] expected = {0, 2, 1, 3};\n        Assert.assertArrayEquals(expected, output);\n\n\n        int[][] courses1 = {{1,0},{2,0},{3,1},{3,2}, {0, 3}};\n        int[] output1 = cs.findOrder(4, courses1);\n        int[] expected1 = {};\n        Assert.assertArrayEquals(expected1, output1);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/graph/TravelingSalesmanHeldKarpTest.java",
    "content": "package com.interview.graph;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class TravelingSalesmanHeldKarpTest {\n\n    @Test\n    public void testDifferentCases() {\n        TravelingSalesmanHeldKarp tsp = new TravelingSalesmanHeldKarp();\n        int[][] distance = {{0, 12, 3, 9, 6, 1, 2},\n                {12, 0, 6, 1, 8, 2, 10},\n                {3, 6, 0, 6, 7, 11, 7},\n                {9, 1, 6, 0, 9, 10, 3},\n                {6, 8, 7, 9, 0, 1, 11},\n                {1, 2, 11, 10, 1, 0, 12},\n                {2, 10, 7, 3, 11, 12, 0}};\n\n        int cost = tsp.minCost(distance);\n        Assert.assertEquals(19, cost);\n\n        int[][] distance1 = {{0, 1, 15, 6},\n                {2, 0, 7, 3},\n                {9, 6, 0, 12},\n                {10, 4, 8, 0},\n        };\n\n        cost = tsp.minCost(distance1);\n        Assert.assertEquals(21, cost);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/graph/WallsAndGatesTest.java",
    "content": "package com.interview.graph;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class WallsAndGatesTest {\n\n    @Test\n    public void testDifferentScenarios() {\n        WallsAndGates wallsAndGates = new WallsAndGates();\n        int INF = Integer.MAX_VALUE;\n        int[][] rooms = {{INF, -1, 0, INF},\n                         {INF, INF, INF, -1},\n                         {INF, -1, INF, -1},\n                         {0, -1, INF, INF}};\n\n        int[][] output = {{3, -1, 0, 1},\n                          {2, 2, 1, -1},\n                          {1, -1, 2, -1},\n                          {0, -1, 3, 4}};\n\n        wallsAndGates.wallsAndGates(rooms);\n        int i = 0;\n        for (int[] o : output) {\n            Assert.assertArrayEquals(o, rooms[i++]);\n        }\n    }\n}\n\n"
  },
  {
    "path": "test/com/interview/linklist/DeleteDuplicateNodesTest.java",
    "content": "package com.interview.linklist;\n\nimport org.junit.Test;\n\npublic class DeleteDuplicateNodesTest {\n\n    @Test\n    public void testDifferentCases() {\n        DeleteDuplicateNodes deleteDuplicateNodes = new DeleteDuplicateNodes();\n        LinkList linkList = new LinkList();\n        Node node = null;\n        node = linkList.addNode(1, node);\n        node = linkList.addNode(2, node);\n        node = linkList.addNode(2, node);\n        deleteDuplicateNodes.deleteDuplicates(node);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/misc/IntegerListParserTest.java",
    "content": "package com.interview.misc;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class IntegerListParserTest {\n\n    @Test\n    public void testDifferentCases() {\n        IntegerListParser integerListParser = new IntegerListParser();\n        IntegerListParser.NestedInteger nestedInteger = integerListParser.deserialize(\"123\");\n        String result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"123\", result);\n        nestedInteger = integerListParser.deserialize(\"[]\");\n        result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"[]\", result);\n        nestedInteger = integerListParser.deserialize(\"[123]\");\n        result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"[123]\", result);\n        nestedInteger = integerListParser.deserialize(\"[123,41]\");\n        result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"[123,41]\", result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[1]]\");\n        result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"[123,41,[1]]\", result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[[[]]]]\");\n        result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"[123,41,[[[]]]]\", result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[[[],[]]],[],[]]\");\n        result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"[123,41,[[[],[]]],[],[]]\", result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[[[121,41,[1]],[2]]],[2],[4]]\");\n        result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"[123,41,[[[121,41,[1]],[2]]],[2],[4]]\", result);\n        nestedInteger = integerListParser.deserialize(\"[123,41,[[1,2,[],[]]],[],[],[[1],[3]]]\");\n        result = integerListParser.serialize(nestedInteger);\n        Assert.assertEquals(\"[123,41,[[1,2,[],[]]],[],[],[[1],[3]]]\", result);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/multiarray/Mutable2DSumRangeQueryTest.java",
    "content": "package com.interview.multiarray;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class Mutable2DSumRangeQueryTest {\n\n    @Test\n    public void testDifferentCases() {\n        int[][] input = {{2, 3, 6}, {-1, 2, 4}, {-3, 2, 5}};\n        Mutable2DSumRangeQuery mutable2DSumRangeQuery = new Mutable2DSumRangeQuery(input);\n        int total = mutable2DSumRangeQuery.sumRegion(1, 1, 2, 2);\n        Assert.assertEquals(13, total);\n\n        total = mutable2DSumRangeQuery.sumRegion(0, 1, 2, 1);\n        Assert.assertEquals(7, total);\n\n        mutable2DSumRangeQuery.update(1, 1, 4);\n        total = mutable2DSumRangeQuery.sumRegion(1, 1, 2, 2);\n        Assert.assertEquals(15, total);\n\n        total = mutable2DSumRangeQuery.sumRegion(0, 1, 2, 1);\n        Assert.assertEquals(9, total);\n\n    }\n}\n"
  },
  {
    "path": "test/com/interview/number/AllStrobogrammaticNumberTest.java",
    "content": "package com.interview.number;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class AllStrobogrammaticNumberTest {\n\n    @Test\n    public void testDifferentCases() {\n        AllStrobogrammaticNumber allStrobogrammaticNumber = new AllStrobogrammaticNumber();\n        Assert.assertEquals(19, allStrobogrammaticNumber.strobogrammaticInRange(\"0\", \"1000\"));\n        Assert.assertEquals(34171, allStrobogrammaticNumber.strobogrammaticInRange(\"1011010\", \"2210101121121\"));\n\n    }\n}\n"
  },
  {
    "path": "test/com/interview/number/BasicCalculatorTest.java",
    "content": "package com.interview.number;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class BasicCalculatorTest {\n\n    @Test\n    public void testDifferentCases() {\n        BasicCalculator basicCalculator = new BasicCalculator();\n        Assert.assertEquals(0, basicCalculator.calculate(\"0\"));\n        Assert.assertEquals(9, basicCalculator.calculate(\"0 +  9\"));\n        Assert.assertEquals(19, basicCalculator.calculate(\"1 + 9 * 2\"));\n        Assert.assertEquals(15, basicCalculator.calculate(\"3 + 9/2 * 3\"));\n        Assert.assertEquals(6, basicCalculator.calculate(\"8 -2 + 3/ 5  \"));\n\n    }\n}\n"
  },
  {
    "path": "test/com/interview/recursion/RestoreIPAddressesTest.java",
    "content": "package com.interview.recursion;\n\nimport com.interview.TestUtil;\nimport org.junit.Test;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class RestoreIPAddressesTest {\n\n    @Test\n    public void testDifferenceCases() {\n        RestoreIPAddresses restoreIPAddresses = new RestoreIPAddresses();\n        List<String> result = restoreIPAddresses.restoreIpAddresses(\"25525511135\");\n        List<String> expected = new ArrayList<>();\n        expected.add(\"255.255.11.135\");\n        expected.add(\"255.255.111.35\");\n        TestUtil<String> t = new TestUtil<>();\n        t.compareList(expected, result);\n\n        List<String> result1 = restoreIPAddresses.restoreIpAddresses(\"0000\");\n        expected = new ArrayList<>();\n        expected.add(\"0.0.0.0\");\n        t.compareList(expected, result1);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/string/LongestSubstringWithKDistinctCharactersTest.java",
    "content": "package com.interview.string;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class LongestSubstringWithKDistinctCharactersTest {\n\n    @Test\n    public void testDifferenceCases() {\n        LongestSubstringWithKDistinctCharacters longestSubstringWithKDistinctCharacters = new LongestSubstringWithKDistinctCharacters();\n        Assert.assertEquals(3, longestSubstringWithKDistinctCharacters.lengthOfLongestSubstringKDistinct(\"eceba\", 2));\n        Assert.assertEquals(1, longestSubstringWithKDistinctCharacters.lengthOfLongestSubstringKDistinct(\"aba\", 1));\n        Assert.assertEquals(5, longestSubstringWithKDistinctCharacters.lengthOfLongestSubstringKDistinct(\"caebegcle\", 4));\n        Assert.assertEquals(0, longestSubstringWithKDistinctCharacters.lengthOfLongestSubstringKDistinct(\"eceba\", 0));\n        Assert.assertEquals(3, longestSubstringWithKDistinctCharacters.lengthOfLongestSubstringKDistinctUsingMap(\"eceba\", 2));\n        Assert.assertEquals(1, longestSubstringWithKDistinctCharacters.lengthOfLongestSubstringKDistinctUsingMap(\"aba\", 1));\n        Assert.assertEquals(5, longestSubstringWithKDistinctCharacters.lengthOfLongestSubstringKDistinctUsingMap(\"caebegcle\", 4));\n        Assert.assertEquals(0, longestSubstringWithKDistinctCharacters.lengthOfLongestSubstringKDistinctUsingMap(\"eceba\", 0));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/string/PalindromePairTest.java",
    "content": "package com.interview.string;\n\nimport com.interview.TestUtil;\nimport org.junit.Test;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class PalindromePairTest {\n\n    @Test\n    public void testDifferentCases() {\n        PalindromePair palindromePair = new PalindromePair();\n        TestUtil testUtil = new TestUtil();\n        String[] words = {\"bat\", \"tab\"};\n        List<List<Integer>> result = palindromePair.palindromePairs(words);\n        testUtil.compareListOfList(createList(0, 1, 1, 0), result);\n        String[] words1 = {\"abcd\", \"dcba\", \"lls\", \"s\", \"sssll\"};\n        result = palindromePair.palindromePairs(words1);\n        testUtil.compareListOfList(createList(0, 1, 1, 0, 3, 2, 2, 4), result);\n        String[] words2 = {\"\", \"abcd\", \"abba\"};\n        result = palindromePair.palindromePairs(words2);\n        testUtil.compareListOfList(createList(0, 2, 2, 0), result);\n        String[] words3 = {\"a\",\"abc\",\"aba\",\"\"};\n        result = palindromePair.palindromePairs(words3);\n        testUtil.compareListOfList(createList(3, 0, 0, 3, 3, 2, 2, 3), result);\n        String[] words4 = {\"abcd\",\"dcba\",\"lls\",\"s\",\"sssll\"};\n        result = palindromePair.palindromePairs(words4);\n        testUtil.compareListOfList(createList(0, 1, 1, 0, 3, 2, 2, 4), result);\n    }\n\n    private List<List<Integer>> createList(int... index) {\n        List<List<Integer>> result = new ArrayList<>();\n        for (int i = 0; i < index.length; i += 2) {\n            List<Integer> r = new ArrayList<>();\n            r.add(index[i]);\n            r.add((index[i + 1]));\n            result.add(r);\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "test/com/interview/string/StringEncoderDecoderTest.java",
    "content": "package com.interview.string;\n\nimport com.interview.TestUtil;\nimport org.junit.Test;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class StringEncoderDecoderTest {\n\n    @Test\n    public void testDifferentCases() {\n        StringEncoderDecoder stringEncoderDecoder = new StringEncoderDecoder();\n        List<String> input = new ArrayList<>();\n        input.add(\"Tushar\");\n        input.add(\"Roy\");\n        input.add(\"\");\n        String encoded = stringEncoderDecoder.encode(input);\n        List<String> result = stringEncoderDecoder.decode(encoded);\n        TestUtil<String> testUtil = new TestUtil();\n        testUtil.compareList(input, result);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/string/ValidPalindromeTest.java",
    "content": "package com.interview.string;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class ValidPalindromeTest {\n\n    @Test\n    public void testDifferentCases() {\n        ValidPalindrome validPalindrome = new ValidPalindrome();\n        Assert.assertTrue(validPalindrome.isPalindrome(\"A man, a plan, a canal: Panama\"));\n        Assert.assertFalse(validPalindrome.isPalindrome(\"race a car\"));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/string/ValidWordAbbreviationTest.java",
    "content": "package com.interview.string;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class ValidWordAbbreviationTest {\n\n    @Test\n    public void testDifferentCases() {\n        String[] dict =  {\"eersynoiyqkqubhdd\",\"ylz\",\"yldongowlrnsafafcgmz\",\"rxcjc\",\"dvgdtnknareecongydc\",\"ixiwz\",\"erjfyctsla\",\"xovvrnbbvivbsuhb\",\"bpslbpzbwphhwvhtcr\",\"wptflnqkvekpkt\",\"hwoiniqvfe\",\"dgidjd\",\"ecgsghxuesvqmhxe\",\"kfgppbbvwfyp\",\"qntzitqjuazrqwz\",\"yjbycoyngfrreiyibdsk\",\"nguqbtdistlgicmjfrs\",\"yjqrqibgp\",\"avulamdverhdpkpqjtae\",\"cbwvtowh\",\"yhgvjnvo\",\"rihywmuspvzvp\",\"rbkpetmovkwj\",\"jtsehilffmfkicusup\",\"ficdolmdtvk\",\"qwldknj\",\"hseogl\",\"pdyxrfdxekk\",\"xnrliooqnsqfzwgd\",\"utnumabyrkasiizsjx\",\"urygh\",\"odj\",\"nttcedxgpkjqzwfb\",\"gxs\",\"rkizfdlfmm\",\"pjlz\",\"fvjm\",\"edkozzeuhxp\",\"pbjcmakwqkdm\",\"ppuhqdpaokitaowrzkfh\",\"yimgbxllumgkbqadjjqf\",\"sqsytssfjbaldz\",\"llkw\",\"aliw\",\"hagvoxjnuuhsafkmxww\",\"hahndehh\",\"fqmrjyuogqpxyv\",\"gnzbcrikf\",\"auopjpwsepqwmend\",\"xfgsbfafytrrkyevtz\",\"acrtfozvjdvg\",\"hspkwabiheogyk\",\"uvlcpqien\",\"eaamufqeal\",\"wsvuyeysox\",\"oywhf\",\"kasdlmnj\",\"fjpryefc\",\"ftdqq\",\"ftfqzqqig\",\"dloh\",\"tleszaz\",\"yajyoyaxmmos\",\"zbobgedfdpacbkzmxt\",\"lmcj\",\"dtjonkbwsg\",\"xeiqjxvsfjdfddclnso\",\"gpeutivfqwzfyrtax\",\"wjoo\",\"pptzwdcynnfpnirfkfo\",\"wsudzgwuouof\",\"ykjmbtoafrjjsehckh\",\"oqhamskusmqofrsgkqfv\",\"yifmkodzvk\",\"vmufzdavpwjagmlcv\",\"dtamuegujvtzdxui\",\"nxdyotptdjdhst\",\"rsthatscf\",\"kdpwhmjtnkunabzaxv\",\"ggzytma\",\"sdypdz\",\"xncvkmcddpkhkoalh\",\"qnjndoizypqqqxewgla\",\"czc\",\"ojhzmxxceltwzg\",\"hmwvynbzpuebokl\",\"weuuontazzovia\",\"ohwqtugyirw\",\"lrtftghr\",\"fngstcishaseslmb\",\"athpsapnlyx\",\"tcdnqc\",\"fjfyvg\",\"fneurgd\",\"xddiwjfbshgfbbejmpe\",\"ynscraxwlwsqhsioe\",\"eaderhxrlwrjpp\",\"wpnlrfxgnbfpuuiggsvo\",\"ogqmzw\",\"xai\",\"fdtbvhaosybjczyfcsdx\",\"abbcbqhcuoiaggs\",\"qtdwhsqqjt\",\"dqdvabloavvjhunafwhw\",\"gcpqevfuos\",\"hipvttjbniv\",\"acheeyf\",\"seqrnvez\",\"hszzzvbvmhjg\",\"kkwpshwuvsrbjqm\",\"jqxo\",\"sukagbkkrvbquzkfsj\",\"axbrmcroycbyykkdhl\",\"zrtshq\",\"cgwssttvz\",\"nbwccbisxtkccgmkmped\",\"ivplojduvs\",\"wmblfkhtnj\",\"jeoodscttkmjrszzjgh\",\"qmadddn\",\"ssdauwepilwi\",\"wghuntzaltedkacttafj\",\"rxojnfrleq\",\"qzkuejnvhncjzc\",\"cromyllbcleqipqaitzd\",\"yjdzifptqtcmrfyjrfj\",\"svinvs\",\"uftn\"};\n        ValidWordAbbreviation validWordAbbreviation = new ValidWordAbbreviation(dict);\n\n        Assert.assertTrue(validWordAbbreviation.isUnique(\"hello\"));\n    }\n}\n"
  },
  {
    "path": "test/com/interview/suffixprefix/TrieTest.java",
    "content": "package com.interview.suffixprefix;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class TrieTest {\n\n    @Test\n    public void testDifferentCases() {\n        Trie trie = new Trie();\n\n        trie.insert(\"abcd\");\n        trie.insert(\"abgl\");\n        trie.insertRecursive(\"lmn\");\n        trie.insertRecursive(\"lmnpq\");\n        trie.insert(\"cdeg\");\n        trie.insert(\"ghijk\");\n\n        Assert.assertFalse(trie.search(\"ab\"));\n        Assert.assertFalse(trie.search(\"abc\"));\n        Assert.assertTrue(trie.search(\"abcd\"));\n        Assert.assertFalse(trie.search(\"abg\"));\n        Assert.assertTrue(trie.search(\"abgl\"));\n        Assert.assertFalse(trie.search(\"lm\"));\n        Assert.assertTrue(trie.search(\"lmn\"));\n        Assert.assertFalse(trie.search(\"lmnp\"));\n        Assert.assertTrue(trie.search(\"lmnpq\"));\n\n        trie.delete(\"abcd\");\n        Assert.assertTrue(trie.search(\"abgl\"));\n        Assert.assertFalse(trie.search(\"abcd\"));\n\n        trie.delete(\"lmn\");\n        Assert.assertFalse(trie.search(\"lmn\"));\n        Assert.assertTrue(trie.search(\"lmnpq\"));\n\n        trie.delete(\"lmnpq\");\n        Assert.assertFalse(trie.search(\"lmnpq\"));\n\n    }\n}\n"
  },
  {
    "path": "test/com/interview/tree/KClosestValueInBinaryTreeTest.java",
    "content": "package com.interview.tree;\n\nimport com.interview.TestUtil;\nimport org.junit.Test;\n\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class KClosestValueInBinaryTreeTest {\n\n    @Test\n    public void testDifferentCases() {\n        Node root = null;\n        BinaryTree bt = new BinaryTree();\n        root = bt.addNode(10, root);\n        root = bt.addNode(20, root);\n        root = bt.addNode(30, root);\n        root = bt.addNode(0, root);\n        root = bt.addNode(6, root);\n        root = bt.addNode(-6, root);\n        root = bt.addNode(16, root);\n        root = bt.addNode(19, root);\n\n        KClosestValueInBinaryTree kClosestValueInBinaryTree = new KClosestValueInBinaryTree();\n        List<Integer> result = kClosestValueInBinaryTree.closestKValues(root, 18, 2);\n        TestUtil testUtil = new TestUtil();\n        testUtil.compareList(Arrays.asList(19, 20), result);\n\n        result = kClosestValueInBinaryTree.closestKValues(root, 18, 4);\n        testUtil.compareList(Arrays.asList(19, 20, 16, 10), result);\n    }\n}\n"
  },
  {
    "path": "test/com/interview/tree/VerticalOrderTest.java",
    "content": "package com.interview.tree;\n\nimport com.interview.TestUtil;\nimport org.junit.Test;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class VerticalOrderTest {\n\n    @Test\n    public void testDifferentCases() {\n        SerializeDeserializeBinaryTree serializeDeserializeBinaryTree = new SerializeDeserializeBinaryTree();\n        Node root = serializeDeserializeBinaryTree.deserializeLevelOrder(\"5,1,6,%,3,%,%,2,4\");\n        VerticalOrder verticalOrder = new VerticalOrder();\n        List<List<Integer>> result = verticalOrder.verticalOrder(root);\n        List<List<Integer>> expected = new ArrayList<>();\n        expected.add(Arrays.asList(1, 2));\n        expected.add(Arrays.asList(5, 3));\n        expected.add(Arrays.asList(6, 4));\n\n        int index = 0;\n        TestUtil<Integer> t = new TestUtil<>();\n        for (List<Integer> r : result) {\n            t.compareList(expected.get(index++), r);\n        }\n\n        expected = new ArrayList<>();\n        expected.add(Arrays.asList(9));\n        expected.add(Arrays.asList(3, 15));\n        expected.add(Arrays.asList(20));\n        expected.add(Arrays.asList(7));\n\n        root = serializeDeserializeBinaryTree.deserializeLevelOrder(\"3,9,20,%,%,15,7\");\n        result = verticalOrder.verticalOrder(root);\n        index = 0;\n        for (List<Integer> r : result) {\n            t.compareList(expected.get(index++), r);\n        }\n    }\n\n}\n"
  }
]