[关闭]
@xmruibi 2015-02-13T04:12:43.000000Z 字数 5577 阅读 826

Stack and Queue Problems

Algorithm


Learn the Data Structure first:

  1. class Node:
  2. int val;
  3. Node next;
  4. Node(int val):
  5. this.val = val;
  6. - Stack
  7. Node top;
  8. stack():
  9. top = null;
  10. pop():
  11. Node node;
  12. if(isEmpty()):
  13. node = null;
  14. else:
  15. node = top;
  16. top = top.next;
  17. return node;
  18. push(int val):
  19. Node node = new Node(val);
  20. node.next = top;
  21. top = node;
  22. peek():
  23. Node node;
  24. if(isEmpty()):
  25. node = null;
  26. else:
  27. node = top;
  28. return node;
  29. isEmpty():
  30. return top == null? true:false;
  31. - Queue
  32. Node head;
  33. Node tail;
  34. Queue();
  35. head = null;
  36. tail = null;
  37. enqueue(int val):
  38. Node node = new Node(val);
  39. if(isEmpty()):
  40. first = node;
  41. last = node;
  42. else
  43. last.next = node;
  44. last = node;
  45. dequeue();
  46. if(isEmpty()):
  47. return null;
  48. else:
  49. Node node = first;
  50. first = first.next;
  51. return first;

Questions

1.1 Two Stacks for Queue

  1. Queue:
  2. Stack<Node> input = new Stack<Node>();
  3. Stack<Node> output = new Stack<Node>();
  4. void enqueue(int val):
  5. Node node = new Node(val);
  6. input.push(node);
  7. Node dequeue():
  8. if(size()==0)
  9. return null;
  10. if(output.isEmpty()):
  11. while(!input.isEmpty()):
  12. Node tmp = input.pop();
  13. output.push(tmp);
  14. return output.pop();
  15. int size():
  16. return input.size()+output.size();

1.2 Two Queues for Stack

  1. Stack:
  2. Queue<Node> q1 = new Queue<Node>();
  3. Queue<Node> q2 = new Queue<Node>();
  4. void push(val):
  5. Node node = new Node(val);
  6. q1.add(node);
  7. Node pop():
  8. if(size()==0)
  9. return null;
  10. if(q1.isEmpty()):
  11. while(q2.size()>1):
  12. q1.add(q2.remove());
  13. return q2.remove();
  14. else
  15. while(q1.size()>1):
  16. q2.add(q1.remove());
  17. return q1.remove();
  18. int size():
  19. return q1.size()+q2.size();

2. Min/Max Stack

- Approach 1: Multiple Stacks:
  1. Stack<E> stack = new Stack<E>();
  2. Stack<E> stackMin = new Stack<E>();//存放求最小值的栈
  3. Stack<E> stackMax = new Stack<E>();//存放求最大值的栈
  4. void push(E e):
  5. if(stackMin.isEmpty()||e.comparteTo(stackMin.peek())<0)
  6. stackMin.push(e);
  7. if(stackMax.isEmpty()||e.comparteTo(stackMax.peek())>0)
  8. stackMax.push(e);
  9. stack.push(e);
  10. E pop():
  11. if(stack.peek()==stackMin.peek())
  12. stackMin.pop();
  13. if(stack.peek()==stackMax.peek())
  14. stackMax.pop();
  15. return stack.pop();
  16. E max():
  17. return stackMax.peek();
  18. E min():
  19. return stackMin.peek();
- Approach 2: Customized Data Structure:
  1. class Node{
  2. E e;
  3. E eMin;
  4. E eMax;
  5. Node(E e,E eMin,E eMax):
  6. this.e = e;
  7. this.eMin = eMin;
  8. this.eMax = eMax;
  9. }
  10. Stack<Node> stack = new Stack<Node>()
  11. void push(E e):
  12. E newMin = e.compareTo(min())<0?e:min();
  13. E newMax = e.compareTo(max())>0?e:max();
  14. Node node = new Node(e,newMin,newMax);
  15. stack.push();
  16. E pop():
  17. return stack.pop();
  18. E min():
  19. return stack.peek().min;
  20. E max():
  21. return stack.peek().max;

3. Valid Parentheses

    boolean isValid(String s):
                Stack<Character> stack = new Stack<Character>();
                    for(int i=0;i<s.length();i++):
                        char c = s.charAt(i);
                        switch(c){
                            case '(': case '{': case '[':
                                stack.push(c);
                                break;
                            case ')':
                                if(stack.isEmpty() ||stack.pop()!='('){
                                    return false;
                                }else
                                    break;
                            case '}':
                                if(stack.isEmpty() ||stack.pop()!='{'){
                                    return false;
                                }else
                                    break;
                            case ']':
                                if(stack.isEmpty() ||stack.pop()!='['){
                                    return false;
                                }else
                                    break;
                        }
                return stack.isEmpty();

4. Evaluate Reverse Polish Notation

  1. enum OperatorEnum { // 注意 enumeration type 写法
  2. add("+"), sub("-"), mul("*"), div("/"), leftkh("("), rightkh(")");
  3. // 最后一个必须是分号。
  4. private String value;
  5. public String getValue() {
  6. eturn value;
  7. }
  8. OperatorEnum(String s) {
  9. value = s;
  10. }
  11. }
  12. int evalRPN(String[] tokens):
  13. int result=Integer.MIN_VALUE;
  14. Stack<Integer> stack = new Stack<Integer>();
  15. for(int i=0;i<tokens.length;i++):
  16. if(tokens[i].equals(OperatorEnum.add.getValue())):
  17. result = stack.pop()+stack.pop();
  18. else if(tokens[i].equals(OperatorEnum.sub.getValue())):
  19. result = stack.pop()-stack.pop();
  20. else if(tokens[i].equals(OperatorEnum.mul.getValue())):
  21. result = stack.pop()*stack.pop();
  22. else if(tokens[i].equals(OperatorEnum.div.getValue())):
  23. int div = stack.pop();
  24. int dived = stack.pop();
  25. if(dived == 0):
  26. result = Integer.MIN_VALUE;
  27. else:
  28. result = div / dived;
  29. else:
  30. result = Integer.parseInt(tokens[i]);
  31. stack.push(result);
  32. if (!stack.isEmpty()):
  33. result = stack.pop();
  34. return stack.isEmpty() ? result : Integer.MIN_VALUE;

6. Single Array implement multiple stacks(e.g. 3 stacks?)

            static array approach:
  1. int stackSize = 300;
  2. int[] array = new int[stackSize];
  3. int[] spointer = {0,0,0};
  4. void push(int sNum, int val):
  5. int index = sNum*stackSize +spointer[sNum]+1;
  6. spointer[sNum]++;
  7. array[index] = val;
  8. int pop(int sNum):
  9. int index = sNum*stackSize +spointer[sNum];
  10. int pop = array[index];
  11. array[index] = 0;
  12. spointer[sNum]--;
  13. return pop;
  14. int peek(int sNum):
  15. return array[sNum*stackSize +spointer[sNum]];
  16. boolean isEmpty(int sNum):
  17. return sPointer[sNum]==0;
            dynamic linked list approach:
  1. class StackNode:
  2. int prev;
  3. int val;
  4. StackNode(int prev,int val):
  5. this.val = val;
  6. this.prev = prev;
  7. int stackSize = 300;
  8. int indexUsed = 0;
  9. int[] spointer = {-1,-1,-1};
  10. StackNode[] buf = new StackNode[stackSize*3];
  11. void push(int sNum, int val):
  12. int lastIndex = spointer[sNum];
  13. spointer[sNum] = indexUsed;
  14. indexUsed++;
  15. buf[spointer[sNum]] = new StackNode(lastIndex, val);
  16. int pop(int sNum):
  17. int val = buf[spointer[sNum]].val;
  18. int lastIndex = spointer[sNum];
  19. spointer[sNum] = buf[spointer[sNum]].prev;
  20. buf[lastIndex] = null;
  21. indexUsed --;
  22. return val;
  23. int peek(int sNum):
  24. return buf[spointer[sNum]].val;

7. Hanoi Towers

  1. Stack<Integer> disks;
  2. int index;
  3. Tower():
  4. disks = new Stack<Integer>();
  5. index= i;
将n个圆盘从柱子src移动到柱子dst,其中可以借助柱子bri(bridge)。
注:n个圆盘从上到下依次的标号依次为1到n,表示圆盘从小到大。
移动的过程中,不允许大圆盘放在小圆盘的上面。
我们定义一组元组来表示三根柱子的状态:(src上的圆盘,bri上的圆盘,dst上的圆盘) 初始状态是:(1~n, 0, 0)
 表示src上有1到n共n个圆盘,另外两个柱子上没有圆盘。 目标状态是:(0, 0, 1~n)表示dst上有1到n共n个圆盘,另外两个柱子上没有圆盘。
 由于最大的圆盘n最后是放在dst的最下面,且大圆盘是不能放在小圆盘上面的, 所以,一定存在这样一个中间状态:(n, 1~n-1, 0),这样才能把最大的圆盘n 移动到dst的最下面。现在手头上的工具(可用的函数)只有hanoi,自然要想办法创造可以使用这个函数的情景,而不是其它情景。
  1. void hanoi(int n, char src, char bri, char dst):
  2. if(n>0):
  3. hanoi(n-1,dst,bri);
  4. moveTopTo(dst);
  5. bri.hanoi(n-1,this,dst);
  6. void moveTopTo():
  7. int top = disks.pop();
  8. t.add(top);
  9. void add(int d):
  10. if(!disks.isEmpty()&&disks.peek()<=0):
  11. "Error placing"
  12. else
  13. disks.push(d)

8. Simplify Path(For UNIX file path)

  1. String simplifyPath(String path):
  2. Stack<String> stack = new Stack<String>();
  3. String[] paths = path.split("/+");
  4. for(String elem:paths):
  5. if(elem.equals("."))
  6. continue;
  7. else if(elem.equals(".."))
  8. if(stack.isEmpty()):
  9. continue;
  10. stack.pop();
  11. else
  12. stack.push(elem);
  13. String result = "";
  14. while(!stack.isEmpty()):
  15. result = "/" + stack.pop()+result;
  16. if(result.length()==0):
  17. result = "/";
  18. return result;
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注