LintCode - Infix to Postfix / Convert Expression to Reverse Polish Notation


LintCode - Infix to Postfix / Convert Expression to Reverse Polish Notation - 我的博客 - ITeye技术网站
Given an expression string array, return the Reverse Polish notation of this expression. (remove the parentheses)
Aka, convert infix notation to postfix notation.

Example
For the expression [3 - 4 + 5] (which denote by ["3", "-", "4", "+", "5"]), return[3 4 - 5 +] (which denote by ["3", "4", "-", "5", "+"])

Reverse Polish notation (RPN) is a mathematical notation in which every operator follows all of its operands, in contrast to Polish notation, which puts the operator in the prefix position. It is also known as postfix notation and is parenthesis-free as long as operator arities are fixed.

The infix expression "5 + ((1 + 2) × 4) − 3" can be written down like this in RPN:
5 1 2 + 4 × + 3 −
https://wxx5433.gitbooks.io/interview-preparation/content/part_ii_leetcode_lintcode/stack/convert_expression_to_reverse_polish_notation.html
  public ArrayList<String> convertToRPN(String[] expression) {
    ArrayList<String> result = new ArrayList<>();
    if (expression == null || expression.length == 0) {
      return result;
    }
    Stack<String> opStack = new Stack<>();
    for (String token : expression) {
      if (isNumber(token)) {
        result.add(token);
      } else if (token.equals("(")) {
        opStack.push(token);
      } else if (token.equals(")")) {
        while (!opStack.peek().equals("(")) {
          result.add(opStack.pop());
        }
        opStack.pop();
      } else {
        while (!opStack.isEmpty() && getPriority(opStack.peek()) >= getPriority(token)) {
          result.add(opStack.pop());
        }
        opStack.push(token);
      }
    }
    while (!opStack.isEmpty()) {
      result.add(opStack.pop());
    }
    return result;
  }

  private boolean isNumber(String token) {
    return Character.isDigit(token.charAt(0));
  }

  private int getPriority(String op) {
    if (op.equals("(")) {
      return 0;
    } else if (op.equals("+") || op.equals("-")) {
      return 1;
    } else {
      return 2;
    }
  }
https://xmruibi.gitbooks.io/interview-preparation-notes/content/Algorithm/Expression/ConvertExpressionToRPN.html
  • Always consider stack firstly, when meet a reverse polish notation problem.
  • The operator priority (*/) > (+-), when get the operator is less priority than stack top element, pop the stack util the element has the same priority as the current operator and output the pop element in result list.
  • Push the "(" always but pop the stack when get the ")" until stack has pop the corresponding "(".
  • When get the operand, just output in result list.
  public ArrayList<String> convertToRPN(String[] expression) {
    ArrayList<String> result = new ArrayList<>();
    if (expression == null || expression.length == 0) {
      return result;
    }
    Stack<String> opStack = new Stack<>();
    for (String token : expression) {
      if (isNumber(token)) {
        result.add(token);
      } else if (token.equals("(")) {
        opStack.push(token);
      } else if (token.equals(")")) {
        while (!opStack.peek().equals("(")) {
          result.add(opStack.pop());
        }
        opStack.pop();
      } else {
        while (!opStack.isEmpty() && getPriority(opStack.peek()) >= getPriority(token)) {
          result.add(opStack.pop());
        }
        opStack.push(token);
      }
    }
    while (!opStack.isEmpty()) {
      result.add(opStack.pop());
    }
    return result;
  }

  private boolean isNumber(String token) {
    return Character.isDigit(token.charAt(0));
  }

  private int getPriority(String op) {
    if (op.equals("(")) {
      return 0;
    } else if (op.equals("+") || op.equals("-")) {
      return 1;
    } else {
      return 2;
    }
  }
http://hehejun.blogspot.com/2014/12/algorithmconvert-expression-to-reverse.html
括号只是决定运算的优先顺序,所以不会出现在我们最后的逆波兰式当中。根据以上两个要点,先写出转换成逆波兰式的算法,之后再来分别解释,首先维护两个栈,第一个栈只存操作符,第二个栈是存逆波兰式的结果,第一个栈中我们先压入'#'并认为它的优先级最低(这一步可以让我们避免check栈空的情况)

  1. public List<String> convertToRPN(String[] expression) {  
  2.     List<String> rpn = new ArrayList<>();  
  3.     Stack<String> opstack = new Stack<>();  
  4.     for(String op:expression) {  
  5.         if("+-*/".contains(op)) {  
  6.             while(!opstack.isEmpty() && getPriority(opstack.peek()) >= getPriority(op)) {  
  7.                 rpn.add(opstack.pop());  
  8.             }  
  9.             opstack.push(op);  
  10.         } else if("(".equals(op)) {  
  11.             opstack.push(op);  
  12.         } else if(")".equals(op)) {  
  13.             while(!"(".equals(opstack.peek())) {  
  14.                 rpn.add(opstack.pop());  
  15.             }  
  16.             opstack.pop();  
  17.         }  
  18.         else {  
  19.             rpn.add(op);  
  20.         }  
  21.     }  
  22.     while(!opstack.isEmpty()) {  
  23.         rpn.add(opstack.pop());  
  24.     }  
  25.     return rpn;  
  26. }  
  27. private int getPriority(String s) {  
  28.     char c = s.charAt(0);  
  29.     if(c == '+' || c== '-') {  
  30.         return 1;  
  31.     } else if(c == '*' || c == '/') {  
  32.         return 2;  
  33.     }  
  34.     return 0;  

public String convertToReversePolish(String exp) {
  if (exp == null)
    return null;
  String res = "";
  int len = exp.length();
  Stack<Character> operator = new Stack<Character>();
  Stack<String> reversePolish = new Stack<String>();
  //avoid checking empty
  operator.push('#');
  for (int i = 0; i < len;) {
    //deal with space
    while (i < len && exp.charAt(i) == ' ')
      i++;
    if (i == len)
      break;
    //if is number
    if (isNum(exp.charAt(i))) {
      String num = "";
      while (i < len && isNum(exp.charAt(i)))
          num += exp.charAt(i++);
      reversePolish.push(num);
    //is operator
    } else if (isOperator(exp.charAt(i))) {
      char op = exp.charAt(i);
      switch (op) {
      case '(':
        operator.push(op);
        break;
      case ')':
        while (operator.peek() != '(')
          reversePolish.push(Character.toString(operator.pop()));
        operator.pop();
        break;
    case '+':
    case '-':
      if (operator.peek() == '(')
        operator.push(op);
      else {
        while (operator.peek() != '#' && operator.peek() != '(')
          reversePolish.push(Character.toString(operator.pop()));
        operator.push(op);
      }
      break;
    case '*':
    case '/':
      if (operator.peek() == '(')
        operator.push(op);
      else {
        while (operator.peek() != '#' && operator.peek() != '+' &&
            operator.peek() != '-' && operator.peek() != '(')
          reversePolish.push(Character.toString(operator.pop()));
        operator.push(op);
      }
      break;
    }
      i++;
    }
  }
  while (operator.peek() != '#')
    reversePolish.push(Character.toString(operator.pop()));
  while (!reversePolish.isEmpty())
    res = res.length() == 0? reversePolish.pop() + res: reversePolish.pop() + " " + res;
  return res;
}

public boolean isOperator(char c) {
  return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
}

public boolean isNum(char c) {
  return c - '0' >= 0 && c - '0' <= 9;
}
Converting infix to RPN (shunting-yard algorithm) « andreINC
Posted on If you’ve tried to write your own calculator (something in the style of gcalctool ) you’ve probably had to build a simple converter for your mathematical expressions from  infix notation to   RPN (Reverse Polish Notation). Inspired by this classical  SPOJ challenge I wanted to write my own simplified version of an expression converter. If this topic is new for you, or you need to refresh your memory please don’t skip the following paragraph.
http://andreinc.net/2010/10/05/converting-infix-to-rpn-shunting-yard-algorithm/
simplified version of the Shunting-yard algorithm (complete version)
  • For all the input tokens [S1]:
    • Read the next token [S2];
    • If token is an operator (x) [S3]:
      • While there is an operator (y) at the top of the operators stack and either (x) is
        left-associative and its precedence is less or equal to that of (y), or (x) is right-associative
        and its precedence is less (**No equal**) than (y) [S4]:
        • Pop (y) from the stack [S5];
        • Add (y) output buffer [S6];
      • Push (x) on the stack [S7];
    • Else If token is left parenthesis, then push it on the stack [S8];
    • Else If token is a right parenthesis [S9]:
      • Until the top token (from the stack) is left parenthesis, pop from the stack to the output buffer [S10];
      • Also pop the left parenthesis but don’t include it in the output buffer [S11];
    • Else add token to output buffer [S12].
  • While there are still operator tokens in the stack, pop them to output [S13]
Note: [SN] Relate with code.
        // Associativity constants for operators: encapsulate in an Operator class.
 private static final int LEFT_ASSOC = 0;
 private static final int RIGHT_ASSOC = 1;

 // Supported operators
 private static final Map<String, int[]> OPERATORS = new HashMap<String, int[]>();
 static {
  // Map<"token", []{precendence, associativity}>
  OPERATORS.put("+", new int[] { 0, LEFT_ASSOC });
  OPERATORS.put("-", new int[] { 0, LEFT_ASSOC });
  OPERATORS.put("*", new int[] { 5, LEFT_ASSOC });
  OPERATORS.put("/", new int[] { 5, LEFT_ASSOC });
  OPERATORS.put("%", new int[] { 5, LEFT_ASSOC });
  OPERATORS.put("^", new int[] { 10, RIGHT_ASSOC });
 }
 public static String[] infixToRPN(String[] inputTokens) { // simplify condition: use string array
  ArrayList<String> out = new ArrayList<String>();
  Stack<String> stack = new Stack<String>();
  // For all the input tokens [S1] read the next token [S2]
  for (String token : inputTokens) {
   if (isOperator(token)) {
    // If token is an operator (x) [S3]
    while (!stack.empty() &amp;&amp; isOperator(stack.peek())) {
     // [S4]
     if ((isAssociative(token, LEFT_ASSOC) &amp;&amp; cmpPrecedence(
       token, stack.peek()) <= 0)
       || (isAssociative(token, RIGHT_ASSOC) &amp;&amp; cmpPrecedence(
         token, stack.peek()) < 0)) {
      out.add(stack.pop());  // [S5] [S6]
      continue;
     }
     break;
    }
    // Push the new operator on the stack [S7]
    stack.push(token);
   } else if (token.equals("(")) {
    stack.push(token);  // [S8]
   } else if (token.equals(")")) {
    // [S9]
    while (!stack.empty() &amp;&amp; !stack.peek().equals("(")) {
     out.add(stack.pop()); // [S10]
    }
    stack.pop(); // [S11]
   } else {
    out.add(token); // [S12]
   }
  }
  while (!stack.empty()) {
   out.add(stack.pop()); // [S13]
  }
  String[] output = new String[out.size()];
  return out.toArray(output);
 }
When n is a negative integer and b is not zero, bn is naturally defined as 1/bn, preserving the property bn × bm = bn + m.
Right-associative operations include the following:
x^{y^z}=x^{(y^z)}.\,
The reason exponentiation is right-associative is that a repeated left-associative exponentiation operation would be less useful. Multiple appearances could (and would) be rewritten with multiplication:
(x^y)^z=x^{(yz)}.\,

    http://www.zrzahid.com/convert-to-reverse-polish-notation-and-evaluate-the-expression-shunting-yard-algorithm/
    Given an infix expression with binary operators convert it to reverse polish notation (RPN) and evaluate the expression.
    For example, the RPN form of the expression 3+2 is 32+. Similarly RPN for 3+4*2/(1-5)*2/3 is 342*15-/2*3/+ and the value of the expression is 1.66.
    We can convert an infix expression to a reverse polish notation expression by usingShunting-yard algorithm developed by Dijkstra. This is a O(n) time and O(n) space algorithm.
    • While there are tokens to be read:
    •   Read a token.
    • If the token is a number, then add it to the output queue.
    • If the token is a function token, then push it onto the stack.
    • If the token is a function argument separator (e.g., a comma):
    •         Until the token at the top of the stack is a left parenthesis, pop operators off the stack onto the output queue. If no left parentheses are encountered, either the separator was misplaced or parentheses were mismatched.
    • If the token is an operator, o1, then:
    •        while there is an operator token, o2, at the top of the operator stack, and either
    o1 is left-associative and its precedence is less than or equal to that of o2, or
    o1 is right associative, and has precedence less than that of o2,
    then pop o2 off the operator stack, onto the output queue;
    • push o1 onto the operator stack.
    • If the token is a left parenthesis (i.e. "("), then push it onto the stack.
    • If the token is a right parenthesis (i.e. ")"):
    •        Until the token at the top of the stack is a left parenthesis, pop operators off the stack onto the output queue.
    • Pop the left parenthesis from the stack, but not onto the output queue.
    • If the token at the top of the stack is a function token, pop it onto the output queue.
    • If the stack runs out without finding a left parenthesis, then there are mismatched parentheses.
    • When there are no more tokens to read:
    •         While there are still operator tokens in the stack:
    •               If the operator token on the top of the stack is a parenthesis, then there are mismatched parentheses.
    • Pop the operator onto the output queue.
    •Exit.
    
    public static ArrayList<String> convertInfix(String[] exprTokens){
     ArrayList<String> infix = new ArrayList<String>();
     Stack<String> operatorStack = new Stack<String>();
     
     for(String op : exprTokens){
      op = op.trim();
      //if its an operand , simply append to output
      if(!isOperator(op)){
       infix.add(op);
      }
      //if its an operator
      else{
       //if its a left parenthesis then push it to stack
       if(op.equals("(")){
        operatorStack.push("(");
       }
       //otherwise if it is a right parenthesis then pop the stack until we see a matching left parenthesis
       else if(op.equals(")")){
        while(!operatorStack.peek().equals("(") && !operatorStack.isEmpty()){
         infix.add(operatorStack.pop());
        }
        
        //if we do not have a matching left parethesis then it's a malformed expression
        if(operatorStack.isEmpty() || !operatorStack.peek().equals("(")){
         return null;
        }
        //otherwise we found a matching left. Just pop it out
        else{
         operatorStack.pop();
        }
       }
       //otherwise its an operator
       else{
        //keep poping out element from stack and append in output as long as we see a higher precedence operator 
        //in the top of stack
        while(
          !operatorStack.isEmpty() 
          && (
            (isLeftAssociative(op) && getPrecedence(op) <= getPrecedence(operatorStack.peek()))
            || (!isLeftAssociative(op) && getPrecedence(op) < getPrecedence(operatorStack.peek()))
             )
            ){
         infix.add(operatorStack.pop());
        }
        //ow add the operator
        operatorStack.push(op);
       }
      }
     }
     
     //if there are left over element sin stack then append them in the output
     while(!operatorStack.isEmpty()){
      infix.add(operatorStack.pop());
     }
     
     return infix;
    }
    
    private static int getPrecedence(String op){
     if(op.equals("+") || op.equals("-")){
      return 2;
     }
     if(op.equals("*") || op.equals("/")){
      return 3;
     }
     if(op.equals("^")){
      return 4;
     }
     
     return 0;
    }
    
    private static boolean isLeftAssociative(String op){
     if(op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/")){
      return true;
     }
     if(op.equals("^")){
      return false;
     }
     
     return false;
    }
    
    private static boolean isOperator(String op){
     return op.matches("[-+*/^()]");
    }
    Evaluate RPN expression

    Once we have generated reverse polish notation (RPN) of an expression then we can evaluate the expression using stack by the following simple procedure –
    • While there are tokens to be read:
    •   Read a token.
    •       If its an operand then simply push to stack
    •       If its an operator then replace the expression for this operator with the evaluated value. Pop second and first operand from stack and evaluate the expression for current operator. Then push the evaluated expression into stack.
    • At the end the stack top should be the evaluated value of the expression.
    
    For example, for 342*15-/2*3/+ we the states of stack are : [] -> [3] -> [3,4] -> [3,4,2] -> [3,8] -> .. ->[3,8,1,5] -> [3,8,-4] -> [3,-2] -> [3,-2,2] -> [3,-4] -> [3,-4,3] -> [3,-1.33] -> [1.66]

    Below is the O(n) implementation of the above algorithm which requires O(n) space.
    public static double evaluateInfix(ArrayList<String> infix){
     Stack<String> opStack = new Stack<String>();
     
     for(String op : infix){
      if(isOperator(op)){
       //pop second operand frst (because it's in stack)
       if(opStack.isEmpty()){
        return Double.NaN;
       }
       String op2 = opStack.pop();
       
       //pop first operand second (because it's in stack)
       if(opStack.isEmpty()){
        return Double.NaN;
       }
       String op1 = opStack.pop();
       
       //evaluate the expression
       double eval = evaluate(op1, op2, op);
       
       if(eval == Double.NaN){
        return Double.NaN;
       }
       
       //push the evaluated value to stack
       opStack.push(eval+"");
      }
      else{
       opStack.push(op);
      }
     }
     
     if(opStack.size() != 1){
      return Double.NaN;
     }
     
     return Double.parseDouble(opStack.pop());
    }
    
    private static double evaluate(String op1, String op2, String op){
     if(op.equals("+")){
      return Double.parseDouble(op1)+Double.parseDouble(op2);
     }
     else if(op.equals("-")){
      return Double.parseDouble(op1)-Double.parseDouble(op2);
     }
     else if(op.equals("*")){
      return Double.parseDouble(op1)*Double.parseDouble(op2);
     }
     else if(op.equals("/")){
      double denm = Double.parseDouble(op2);
      if(denm == 0){
       return Double.NaN;
      }
      else {
       return Double.parseDouble(op1)/Double.parseDouble(op2);
      }
     }
     else return Double.NaN;
    }

    http://en.wikipedia.org/wiki/Shunting-yard_algorithm#The_algorithm_in_detail
    Also read http://www.geeksforgeeks.org/expression-evaluation/
    Read full article from LintCode - Infix to Postfix / Convert Expression to Reverse Polish Notation - 我的博客 - ITeye技术网站

    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