LeetCode 962 - Maximum Width Ramp



Given an array A of integers, a ramp is a tuple (i, j) for which i < j and A[i] <= A[j].  The width of such a ramp is j - i.
Find the maximum width of a ramp in A.  If one doesn't exist, return 0.

Example 1:
Input: [6,0,8,2,1,5]
Output: 4
Explanation: 
The maximum width ramp is achieved at (i, j) = (1, 5): A[1] = 0 and A[5] = 5.
Example 2:
Input: [9,8,1,0,1,9,4,0,4,1]
Output: 7
Explanation: 
The maximum width ramp is achieved at (i, j) = (2, 9): A[2] = 1 and A[9] = 1. 
Note:
  1. 2 <= A.length <= 50000
  2. 0 <= A[i] <= 50000

X.
https://zxi.mytechroad.com/blog/stack/leetcode-962-maximum-width-ramp/
  1. Using a stack to store start candidates’ (decreasing order) index
  2. Scan from right to left, compare the current number with the one on the top of the stack, pop if greater.
e.g.
A = [6,0,8,2,1,5]
stack = [0, 1] => [6, 0]
cur: A[5] = 5, stack.top = A[1] = 0, ramp = 5, stack.pop()
cur: A[4] = 1, stack.top = A[0] = 6
cur: A[3] = 2, stack.top = A[0] = 6
cur: A[2] = 8, stack.top = A[0] = 6, ramp = 2, stack.pop()
stack.isEmpty() => END
https://leetcode.com/problems/maximum-width-ramp/discuss/210812/3-Java-Solutions-1)-Brute-Force-2)-Sort-3)-Stack-with-Detailed-Comments
    // Stack is often used for problems like
    // find nearest larger/smaller elem (like water container problem)
    // here it's to find furthest larger/smaller elem (a bit harder than water container problme)
    // Time=O(N) Space=O(N)
    public int maxWidthRamp(int[] A) {
        // scanning from left to right to get all possible indices of the min element seen so far
        // think a bit and you'll discover they are valid START INDICES candidates for the widest ramp
        // they are [i0, i1, i2, i3, i4] as in the pic attached, you could use the pic to think on the algorithm
        int N = A.length;
        Stack<Integer> s = new Stack();
        for (int i = 0; i < N; i++) {
            if (s.isEmpty() || A[i] < A[s.peek()]) {
                s.push(i);
            }
        }
        // now scanning backwards for all other non-min elements, let them pair with all the candidates
        // we've collected in the first step in stack. Meanwhile, if we've discover that the current index i could
        // form a ramp with a min idx j, we know j couldn't form a better solution since i is going backwards
        // so we pop j out of stack
        int res = 0;
        for (int i = N - 1; i >= 0; i--) {
            while (!s.isEmpty() && A[s.peek()] <= A[i]) {
                res = Math.max(res, i - s.pop());
            }      
        }
        return res;
    }

https://leetcode.com/problems/maximum-width-ramp/discuss/208331/C%2B%2B-5-lines-search-in-decreasing-stack-O(n-log-n)


You may wonder why are we checking elements left to right while the maximum is likely to be on the far right side? If we check elements right to left, we do not need to keep smaller elements in the stack. So, we first populate the stack left to right with elements in decreasing order, and then go right to left and pop all elements smaller than the current one. This gives us O(n) runtime. One additional optimization is to populate stack until the top <= A[A.size() - 1].
int maxWidthRamp(vector<int>& A, int res = 0) {
  vector<int> v = { 0 };
  for (int i = 1; A[v.back()] > A[A.size() - 1]; ++i)
    if (A[v.back()] > A[i]) v.push_back(i);

  for (int j = A.size() - 1; j > res; --j)
    while (!v.empty() && A[v.back()] <= A[j]) {
      res = max(res, j - v.back());
      v.pop_back();
    }
  return res;
}
https://leetcode.com/problems/maximum-width-ramp/discuss/208348/JavaC%2B%2BPython-O(N)-Using-Stack
Improve the idea above.
Still one pass and keep a decraesing stack.
based on my understanding, the problem is :
for each element A[i], we need to go back left to find the farthest element that is smaller than A[i].
I do spent a while to figure out why we need to pop() when we have while (!s.empty() && A[s.top()] <= A[i]), then I realize, if A[s.top()] <= A[i] A[s.top()], since we keep a descending order stack , so we also have A[s.top()] <= A[i - 1], and since A[i] - s.top() > A[i - 1] - s.top(), so we need to pop to avoid duplicated calculation.
Then people may ask why descending order stack? because for each element we need to look back for a smaller or equal value, and a descending order stack can guarantee that the top element is always smaller or equal to current element.

The stack is used to store all candidate start points.
And by comparing elements (starting from the end of the array) with those candidates, we can eliminate points that are not bigger than the candidate.
Time Complexity:
O(N)


    public int maxWidthRamp(int[] A) {
        Stack<Integer> s = new Stack<>();
        int res = 0, n = A.length;
        for (int i = 0; i < n; ++i)
            if (s.empty() || A[s.peek()] > A[i])
                s.add(i);
        for (int i = n - 1; i > res; --i)
            while (!s.empty() && A[s.peek()] <= A[i])
                res = Math.max(res, i - s.pop());
        return res;
    }


Keep a decraesing stack.
For each number,
binary search the first smaller number in the stack.
When the number is smaller the the last,
push it into the stack.


Time Complexity:
O(NlogN)


    public int maxWidthRamp(int[] A) {
        List<Integer> s = new ArrayList<>();
        int res = 0, n = A.length;
        for (int i = 0; i < n; ++i) {
            if (s.size() == 0 || A[i] < A[s.get(s.size() - 1)]) {
                s.add(i);
            } else {
                int left = 0, right = s.size() - 1, mid = 0;
                while (left < right) {
                    mid = (left + right) / 2;
                    if (A[s.get(mid)] > A[i]) {
                        left = mid + 1;
                    } else {
                        right = mid;
                    }
                }
                res = Math.max(res, i - s.get(left));
            }
        }
        return res;
    }
X. https://blog.csdn.net/fuxuemingzhu/article/details/85223568
这里用到的是单调递减栈,如果遇到一个数字,比栈顶元素更小,那么就入栈;否则就在栈里边向后找到第一个刚好小于等于它的元素,此时的距离就是最远距离。
Not efficent
    def maxWidthRamp(self, A):
        """
        :type A: List[int]
        :rtype: int
        """
        N = len(A)
        stack = []
        res = 0
        for i, a in enumerate(A):
            if not stack or stack[-1][1] > a:
                stack.append((i, a))
            else:
                x = len(stack) - 1
                while x >= 0 and stack[x][1] <= a:
                    res = max(res, i - stack[x][0])
                    x -= 1
        return res
X. Left + right array
https://www.acwing.com/solution/LeetCode/content/672/
1. 维护一个前缀最小值数组 minlminl,和一个后缀最大值数组 maxrmaxr。例如,[6,0,8,2,1,5] 的两个数组分别为 [6,0,0,0,0,0], [8,8,8,5,5,5]。
2. 定义两个指针,初始时分别指向两个数组的开头,如果 minl[i] <= maxr[j],则更新答案后 j;否则 i;
3. 解释:如果 minl[i] <= maxr[j],则说明在 i 之前(包括 i)必定有一个数字小于等于 j之后(包括 j)的某个数字。且左端的数字就是 A[i],因为 i 是从最小的开始往后走的,故此时只需要向后移动 j,去尝试 j之后的数字某个是否也可行。
4. 如果 minl[i] > maxr[j],则说明 i 之前(包括 i)的所有数字都比 j 之后(包括 j)的所有数字要大,所以 i 需要向后移动寻找一个小一些的数字。

https://leetcode.com/problems/maximum-width-ramp/discuss/209582/O(n)-time-O(n)-space-using-two-array
Use two array to solve this problem. min_arr[i] is the minimum of the first i + 1 elements of A, max_arr[j] is the maximum of the last len(A) - j elements of A.
The idea of this solution is: Suppose (ij) is the answer, then A[i] must be the smallest element among the first i + 1 elements of A and A[j] must be the largeset element among the last len(A) - j elements of A. Otherwise, we can always find an element smaller than A[i] or larger than A[j], so that (ij) is not the maximum width ramp.
For example, the input is [6, 0, 8, 2, 1, 5]. Then min_arr=[6, 0, 0, 0, 0, 0] and max_arr=[8, 8, 8, 5, 5, 5].
We can find the ramp use two points, left and rightleft starts from the beginning of min_arr[i] and right starts from the beginning of max_arr[i]. Increase right by 1 when min_arr[left] <= max_arr[right], else increase left by 1
https://leetcode.com/problems/maximum-width-ramp/discuss/208341/O(N)-JAVA
    public int maxWidthRamp(int[] A) {
        int n = A.length;
        int i, j , max = 0;
        int[] maxR = new int[n], minL = new int[n];
        minL[0] = A[0];
        for (i = 1; i < n; i++){
            minL[i] = Math.min(A[i], minL[i - 1]);
        }
        maxR[n - 1] = A[n - 1];
        for (j = n - 2; j >= 0; j--){
            maxR[j] = Math.max(A[j], maxR[j + 1]);
        }
        i = 0; j = 0;
        while (i < n && j < n){
            if (minL[i] <= maxR[j]){
                max = Math.max(max, j - i);
                j++;
            }else{
                i++;
            }
        }
        return max;
    }


You don't need to calculate minL, only maxR should work!
    public int maxWidthRamp(int[] A) {
        if(A.length == 0){
            return 0;
        }
        int[] maxR = new int[A.length];
        maxR[A.length-1] = A[A.length-1];
        for(int i=A.length-2;i>=0;i--){
            maxR[i] = Math.max(A[i], maxR[i+1]);
        }
        
        int i=0;
        int j=0;
        int res = 0;
        while(i<A.length && j<A.length){
            if(A[i]<=maxR[j]){
                 res = Math.max(res, j-i);
                 j++;
            }else{
                i++;
            }
        }
        
        return res;
    }
X. Two Pointers
https://leetcode.com/problems/maximum-width-ramp/discuss/208328/Two-pointer-O(nlogn)-C%2B%2B-O(n)-space
After i had stored the useful information from problem using vector of pair. I sorted the array.
After I used two pointer consecutive to each other ( pointer at begining and end is not feasible)

int maxWidthRamp(vector<int>& A) 
    {
        vector<pair<int, int>> vec;
        int n = A.size();
        
        for (int i = 0; i < n; ++i) vec.push_back({A[i], i});
        sort(vec.begin(), vec.end());
        
        int i = 0, j = 1, res = 0;
        while (j < n)
        {
            if (vec[i].second <= vec[j].second)
            {
                res = max(res, vec[j].second - vec[i].second);
                ++j;
            }
            else ++i;
        }
        
        return res;
    }
    public int maxWidthRamp(int[] A) {
        int modA[][] = new int[A.length][2];
        for (int i = 0 ; i < A.length ; i++)    {
            modA[i] = new int[] { A[i], i};
        }
        
        Arrays.sort(modA, (m1, m2) -> m1[0] - m2[0]);
        
        int i = 0;
        int j = 1;
        int maxWidth = 0;
        while (j < A.length)    {
            if (modA[j][1] > modA[i][1])    {
                maxWidth = Integer.max(maxWidth, modA[j][1] - modA[i][1]);
                j++;
            }
            else
                i++;
            
            if (i == j)
                j++;
        }
        
        return maxWidth;
    }

X. https://leetcode.com/articles/maximum-width-ramp/
Approach 1: Sort
For all elements like A[i] = v, let's write the indices i in sorted order of their values v. For example with A[0] = 7, A[1] = 2, A[2] = 5, A[3] = 4, we can write the order of indices i=1, i=3, i=2, i=0.
Then, whenever we write an index i, we know there was a ramp of width i - min(indexes_previously_written) (if this quantity is positive). We can keep track of the minimum of all indexes previously written as m.

  public int maxWidthRamp(int[] A) {
    int N = A.length;
    Integer[] B = new Integer[N];
    for (int i = 0; i < N; ++i)
      B[i] = i;

    Arrays.sort(B, (i, j) -> ((Integer) A[i]).compareTo(A[j]));

    int ans = 0;
    int m = N;
    for (int i : B) {
      ans = Math.max(ans, i - m);
      m = Math.min(m, i);
    }

    return ans;
  }

    // 1. sort on value
    // 2. sort on index <-- used in this problem Time=O(NlgN), Space=O(N)
    public int maxWidthRamp2(int[] A) {
        // sort index according to values and then do a dp
        int N = A.length;
        Integer[] indices = new Integer[N]; // need to use Integer for Arrays.sort with lambda to work
        Arrays.setAll(indices, i -> i);
        Arrays.sort(indices, (i, j) -> A[i] != A[j] ? A[i] - A[j] : i - j);
        // use dp to find min idx so far
        int minIdx = indices[0];
        int res = 0;
        for (int idx : indices) {
            res = Math.max(res, idx - minIdx);
            minIdx = Math.min(minIdx, idx);
        }
        return res;
    }
Approach 2: Binary Search Candidates
https://www.jianshu.com/p/cb458cc61e31
Keep a decresing stack.
For each number,
binary search the first smaller number in the stack.
When the number is smaller the the last,
push it into the stack.
    def maxWidthRamp(self, A):
        stack = []
        res = 0
        for i in range(len(A))[::-1]:
            if not stack or A[i] > stack[-1][0]:
                stack.append([A[i], i])
            else:
                j = stack[bisect.bisect(stack, [A[i], i])][1]
                res = max(res, j - i)
        return res
Consider i in decreasing order. We want to find the largest j with A[j] >= A[i] if it exists.
Thus, the candidates for j are decreasing: if there is j1 < j2 and A[j1] <= A[j2] then we strictly prefer j2.
Algorithm
Let's keep a list of these candidates j. For example, with A = [0,8,2,7,5], the candidates for i = 0 would be candidates = [(v=5, i=4), (v=7, i=3), (v=8, i=1)]. We keep the list of candidates in decreasing order of i and increasing order of v.
Now we can binary search to find the largest j with A[j] >= A[i]: it's the first one in this list of candidates with v >= A[i].

  public int maxWidthRamp(int[] A) {
    int N = A.length;

    int ans = 0;
    List<Point> candidates = new ArrayList();
    candidates.add(new Point(A[N - 1], N - 1));

    // candidates: i's decreasing, by increasing value of A[i]
    for (int i = N - 2; i >= 0; --i) {
      // Find largest j in candidates with A[j] >= A[i]
      int lo = 0, hi = candidates.size();
      while (lo < hi) {
        int mi = lo + (hi - lo) / 2;
        if (candidates.get(mi).x < A[i])
          lo = mi + 1;
        else
          hi = mi;
      }

      if (lo < candidates.size()) {
        int j = candidates.get(lo).y;
        ans = Math.max(ans, j - i);
      } else {
        candidates.add(new Point(A[i], i));
      }
    }
    return ans;
  }
X. TreeMap
https://jinx19.github.io/2018/12/23/LeetCode-Solution-2018-12-23-LeetCode-Solution-962-Maximum-Width-Ramp/
https://leetcode.com/problems/maximum-width-ramp/discuss/208659/Simple-java-solution-with-TreeMap
This solution is similar to decending stack solution, but with TreeMap, we can further simplify the logic as treemap maintains the natural ordering, to search a particular value is more straight forward with method of: TreeMap.floorEntry().
The map stores the value to postion mapping. The values is sorted in ascending order.
  public int maxWidthRamp(int[] A) {
    int max = 0;
    NavigableMap<Integer, Integer> valPosMap = new TreeMap<>();
    for (int i = 0; i < A.length; i++) {
      if (i == 0 || A[i] < valPosMap.firstKey())
        valPosMap.put(A[i], i);
      else {
        int cur = i - valPosMap.floorEntry(A[i]).getValue();
        if (cur > max)
          max = cur;
      }
    }
    return max;
  }
https://leetcode.com/problems/maximum-width-ramp/discuss/209060/TreeMap-O(nlogn)-8-lines-of-Java
    public int maxWidthRamp(int[] A) {  
        TreeMap<Integer, Integer> tm = new TreeMap<>();
        int res = 0; 
        for (int i=A.length-1; i>=0; i--) {
            Integer k = tm.ceilingKey(A[i]);
            if (k == null) 
                tm.put(A[i], i);
            else 
                res = Integer.max(res, tm.get(k)-i);
        }
        return res;
    }
X. https://leetcode.com/problems/maximum-width-ramp/discuss/210812/3-Java-Solutions-1)-Brute-Force-2)-Sort-3)-Stack-with-Detailed-Comments
    //------ Solution 1 Brute force -------------//
    // brute force with fast break
    // Time=O(N^2) (a bit better) Space=O(1)
    public int maxWidthRamp1(int[] A) {
        int N = A.length;
        int res = 0;
        rightIdx: for(int i = 0; i < A.length; ++i) {
            leftIdx: for(int j = 0; j < i; ++j) {
                if (A[i] >= A[j]) {
                    res = Math.max(res, i - j);
                    continue rightIdx; // stop inner loop at the first valid index j
                }
            }
        }
        return res;
    }
https://kingsfish.github.io/2018/12/23/Leetcode-962-Maximum-Width-Ramp/
这种思路的最差时间复杂度是O(n^2),最优时间复杂度是O(1),空间复杂度是O(1)。

public int maxWidthRamp(int[] A) {
int n = A.length;
int max = 0;
for (int i = 0; i < n; i ++) {
if(max >= n - 1 - i){
break;
}
for (int j = n - 1; j > i; j --) {
if (A[j] >= A[i]) {
max = Math.max(max, j - i);
}
}
}
return max;
}
https://leetcode.com/problems/maximum-width-ramp/discuss/211756/Normal-DP-%2B-pruning-solution-in-Java
    public int maxWidthRamp(int[] A) {
        int[] dp = new int[A.length+1];
        int res = 0;
        for(int i = 2; i < A.length + 1; ++i){
            int maxval = 0;
            for(int j = 1; j < i; ++j) {
                if(A[i-1] >= A[j-1]) {
                    maxval = Math.max(maxval, dp[j-1] + (i-j));   
                    break;
                }
            }
            res = Math.max(res, maxval);
        }
        return res;
    }

Labels

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

Popular Posts