Thursday, December 29, 2016

Leetcode/F家微软-- 285. Inorder Successor in BST

285. Inorder Successor in BST
  • Difficulty: Medium
Given a binary search tree and a node in it, find the in-order successor of that node in the BST.
https://leetcode.com/problems/inorder-successor-in-bst/  



*Inorder successor in bst: the 1st value great than current value 
That node is the smallest node in p' right branch, if not found can either be p's parent else null .
思路1: Find p in the tree, use a stack to store the path. 2 cases
1. if the right node is not empty,print the leftmost leaf of rightnode or itself.
2. if the right node is null, print the 1st value in stack that is greater than curr.val
else not found return null.
Complexity: time O(n) - store path. space O(n)

public class Solution {
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if(root == null)return root;
        Deque<TreeNode> st = new LinkedList<TreeNode>();
        TreeNode curr = root;
        // Find the target node while saving the path
        while(curr!=p){
            st.push(curr);
            if(curr.val > p.val){
                curr = curr.left;
            }else{
                curr = curr.right;
            }
        }
        // if curr has right node, find the leftmost of right node(or itself), is the successor
        if(curr.right != null){
            curr = curr.right;
            while(curr.left != null){
                curr = curr.left;
            }
            return curr;
        }else{
        // if curr has no right node, find the 1st node in stack that val > curr.val  
            while(!st.isEmpty()){
                if(st.peek().val>curr.val)return st.pop();
                st.pop();
            }    
            // 如果栈都pop空了还没有比目标节点大的,说没有更大的了
            return null;
        }
    }
}

思路2: use dfs
参考: https://discuss.leetcode.com/topic/25076/share-my-java-recursive-solution/13
 When the code runs into the else block, that means the current root is either p's parent or a node in p's right branch.
If it's p's parent node, there are two scenarios: 1. p doesn't have right child, in this case, the recursion will eventually return null, so p's parent is the successor; 2. p has right child, then the recursion will return the smallest node in the right sub tree, and that will be the answer.
If it's p's right child, there are two scenarios: 1. the right child has left sub tree, eventually the smallest node from the left sub tree will be the answer; 2. the right child has no left sub tree, the recursion will return null, then the right child (root) is our answer.
关键字: recursion
Complexity : time O(logn); space O(logn) for stack,           

public class Solution {
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if(root == null){ return root;}
        if(root.val<=p.val){//利用BST性质
            TreeNode right = inorderSuccessor(root.right,p);//successor in the right subtree
            return right;
        }else{
            TreeNode left = inorderSuccessor(root.left,p);//looking for p in the left subtree
            return left != null?left:root;//null case: when leftmost leaf
        }
    }
}


Predecessor

public class Solution {
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if(root == null){ return root;}
        if(root.val>=p.val){//利用BST性质
            TreeNode left = inorderSuccessor(root.left,p);
            return left;
        }else{
            TreeNode right = inorderSuccessor(root.right,p);//右叶,打印中叶或root
            return right != null?right:root;
        }
    }
}

Wednesday, December 28, 2016

Leetcode/G家--409.Longest Palindrome(HashMap)

 409. Longest Palindrome(HashMap)
  • Difficulty: Easy
https://leetcode.com/problems/longest-palindrome/ 
Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.

Input:
"abccccdd"

Output:
7
思路:将每个字母的数目存入map,偶数全加入结果,奇数加入num-1,最后奇数补1(如果存在)
关键字: HashMap

public class Solution {
    public int longestPalindrome(String s) {
        HashMap<Character,Integer> map = new HashMap<Character,Integer>();
        for(int i=0;i<s.length();i++){
            if(map.get(s.charAt(i))==null){
                map.put(s.charAt(i),1);
            }else{
                map.put(s.charAt(i),map.get(s.charAt(i))+1);
            }
        }
        int even = 0,odd= 0,single=0;
        for(Character key:map.keySet()){
            if(map.get(key)%2==0){ even += map.get(key);}
            else{ 
                single = 1;
                odd += map.get(key)-1;
            }
        }
        return even+odd+single;
    }
}

Leetcode/F家,G家 -- 314. Binary Tree Vertical Order Traversal (BFS)


314. Binary Tree Vertical Order Traversal (BFS)
  • Difficulty: Medium
https://leetcode.com/problems/binary-tree-vertical-order-traversal/
Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bottom, column by column).
If two nodes are in the same row and column, the order should be from left to right.
Examples:
  1. Given binary tree [3,9,20,null,null,15,7],
       3
      /\
     /  \
     9  20
        /\
       /  \
      15   7
    
    return its vertical order traversal as:
    [
      [9],
      [3,15],
      [20],
      [7]
    ]
    
  2. Given binary tree [3,9,8,4,0,1,7],
         3
        /\
       /  \
       9   8
      /\  /\
     /  \/  \
     4  01   7
    
    return its vertical order traversal as:
    [
      [4],
      [9],
      [3,0,1],
      [8],
      [7]
    ]
    
  3. Given binary tree [3,9,8,4,0,1,7,null,null,null,2,5] (0's right child is 2 and 1's left child is 5),
         3
        /\
       /  \
       9   8
      /\  /\
     /  \/  \
     4  01   7
        /\
       /  \
       5   2
    
    return its vertical order traversal as:
    [
      [4],
      [9,5],
      [3,0,1],
      [8,2],
      [7]
    ]

Company: Google Snapchat Facebook

思路:用BFS来travese树,原因是要从上往下打印。 建2个Queue,第一个queue存node,第二个存对应的距离。往左就是dist-1,往右就是dist+1。用HashMap在相应的距离存下node。<dist,path>
最后将HashMap由key小到大加入list,即从左打到右-TreeMap(or HashMap记录key的min和max)
Complexity: O(N) time O(N) space

关键字:BFS, two queue

public class Solution {
    public List<List<Integer>> verticalOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(root == null)return res;
        Queue<TreeNode> nodes = new LinkedList<TreeNode>();
        Queue<Integer> dist = new LinkedList<Integer>();
        HashMap<Integer,List<Integer>> map = new HashMap <Integer,List<Integer>>();//<dist, path>
        nodes.add(root);
        dist.add(0);
        int min = 0, max = 0;
        while(!nodes.isEmpty()){
            TreeNode cur = nodes.poll();
            int curdis = dist.poll();
            if(!map.containsKey(curdis))map.put(curdis,new ArrayList<Integer>());
            map.get(curdis).add(cur.val);
            if(cur.left != null){
                nodes.add(cur.left);
                dist.add(curdis - 1);
                if(min > curdis - 1){ min = curdis-1;}
            }
            if(cur.right != null){
                nodes.add(cur.right);
                dist.add(curdis + 1);
                if(max < curdis + 1){ max = curdis+1;}
            }
        }
        for(int i = min; i <= max; i++){
            res.add(new ArrayList(map.get(i)));
        }
        return res;
    }
}

算法小结--编程常识

➤ Unit of memory size
1byte = 8 bit
1MB = 1024byte = 2^10 bit
1KB = 1024 MB = 2^10*2^10 = 2^20
1GB = 1024 KB = 2^10*2^10 = 2^30
4GB = 2^30*2^2 = 2^32
1TB = 2^40

➤ Unary & Binary operator
Unary: 没几个, &(地址),*(pointer ref), !,~(complement) ,+(positive),-(negation),++,--
Binary: logical,math operators: &(bitwise and),&&(logical and), +(add), - (minus)...

➤ Array
contiguous memory allocated for array so no growth

➤  HashTable - array with hash function
function take key to hash value for mapping index in hashtable
and store key
 *make use all info provided by key
 *uniformly distribute output across table
 *map similar keys to very different hash values

deal with collections(avoid by good hash function)
-linear probing
 assign to next available slot
 * increase loop up time to O(N)
 * increase chance of collision - clustering
-sepearate chaining
 array points to linked list
 * search O(n/k) - k lists n keys, distribute evenly

➤ Graph
BFS:Time O(V+E), Space O(V) - tree or known, O(V+E) - adjacency list, O(V^2) - adjacency matrix
DFS:  Time O(V+E), Space O(V) - worst case all vertices in path to store in the stack

Applications:
1.social network (union find)
2.city road
3.precedence constraint(topological sort)

Adjacency Matrix: v*v
--diagnal 0 means no itself loop
--symetric only in undriected graph
Pros:
*easy implement
*remove is O(1)
*O(1) to check for specific edge

Cons:
!O(v^2)more space
!adding vertex cause O(v^2), rewrite all list.

Adjacency list --java ArrayList<List<Integer>> eg: [0][1,2,3]
-- use linkedlist
Pros
*O(v+E)spaces, worst case O(v^2)
*Adding vertex is easirer

Cons
!Query of specified edge takes O(v)

➤Other
"The idea behind bidirectional search is to run two simultaneous searches—one forward from
the initial state and the other backward from the goal—hoping that the two searches meet in
the middle. The motivation is that b^(d/2) + b^(d/2) is much less than b^d. b is branch factor, d is depth. "
----- section 3.4.6 in Artificial Intelligence - A modern approach by Stuart Russel and Peter Norvig


Leetcode/F家,Linkedin -- 311. Sparse Matrix Multiplication

 311. Sparse Matrix Multiplication
  • Difficulty: Medium
https://leetcode.com/problems/sparse-matrix-multiplication/
Given two sparse matrices A and B, return the result of AB.
You may assume that A's column number is equal to B's row number.
Example:
A = [
  [ 1, 0, 0],
  [-1, 0, 3]
]

B = [
  [ 7, 0, 0 ],
  [ 0, 0, 0 ],
  [ 0, 0, 1 ]
]


     |  1 0 0 |   | 7 0 0 |   |  7 0 0 |
AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 |
                  | 0 0 1 |

思路:
解法1:正常for loop,最外面 i: A_row,第二层 j : A_col = B_row,第三层 k: B_col
            *new martix form by A'row * B'col
            *lock A, fill C by row(match pos in B row using j: A'col = B'row)比如说A[0,1]会和所有在B row 1的元素相乘。
             *sparse to aviol multiply 0, skip A[] = 0



public class Solution {
    public int[][] multiply(int[][] A, int[][] B) {
        int A_row = A.length;
        int A_col = A[0].length;//B'row
        int B_col = B[0].length;
        int[][] C = new int[A_row][B_col];
        //3 loop, i - Arow, j - Bcol, k - Acol = Brow
        for(int i = 0; i < A_row; i++){
            for(int j = 0; j < A_col; j++){
                if(A[i][j] == 0)continue;//sparse matrix    
                for(int k = 0; k < B_col; k++){
                    C[i][k] += A[i][j] * B[j][k];//A'col = B'row
                }
            }
        }
        return C;
    }
}

Leetcode/各大家 -- 1. Two Sum(HashMap)


1. Two Sum(HashMap)
  • Difficulty: Easy
https://leetcode.com/problems/two-sum/
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution.
Example:
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

思路:loop用Hashmap存入数组<val,index>,每次查是否当前target - element值存在于Hashmap中。
关键字:HashMap

public class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
        int[] res = new int[2];
        for(int i=0;i<nums.length;i++){
            int val = target - nums[i];
            if(map.containsKey(val)){
                res[0]=map.get(val);
                res[1]=i;
                return res;
            }else{
                map.put(nums[i],i);
            }
        }
        
        return res;
    }
}

算法小结--class & 数据结构

考点是写class或者define一个data structure

Ex:
https://leetcode.com/problems/two-sum-iii-data-structure-design/