Sunday, October 20, 2019

Vertical Order Traversal of a Binary Tree

Given a binary tree, return the vertical order traversal of its nodes values.
For each node at position (X, Y), its left and right children respectively will be at positions (X-1, Y-1) and (X+1, Y-1).
Running a vertical line from X = -infinity to X = +infinity, whenever the vertical line touches some nodes, we report the values of the nodes in order from top to bottom (decreasing Y coordinates).
If two nodes have the same position, then the value of the node that is reported first is the value that is smaller.
Return an list of non-empty reports in order of X coordinate.  Every report will have a list of values of nodes.

Example 1:
Input: [3,9,20,null,null,15,7]
Output: [[9],[3,15],[20],[7]]
Explanation: 
Without loss of generality, we can assume the root node is at position (0, 0):
Then, the node with value 9 occurs at position (-1, -1);
The nodes with values 3 and 15 occur at positions (0, 0) and (0, -2);
The node with value 20 occurs at position (1, -1);
The node with value 7 occurs at position (2, -2).
Example 2:
Input: [1,2,3,4,5,6,7]
Output: [[4],[2],[1,5,6],[3],[7]]
Explanation: 
The node with value 5 and the node with value 6 have the same position according to the given scheme.
However, in the report "[1,5,6]", the node value of 5 comes first since 5 is smaller than 6.

Note:
  1. The tree will have between 1 and 1000 nodes.
  2. Each node's value will be between 0 and 1000.
 ===================== Pre order traversal is not the right approach here =======


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> verticalTraversal(TreeNode* root) {
        if (root == NULL) {
            return vector<vector<int>>();
        }
        vector<vector<int>> ans;
        map<int, vector<int>> mp;
        helper(root, 0, mp);
        generate(mp, ans);
        return ans;
    }
 
    void helper(TreeNode* root, int location, map<int, vector<int>>& mp) {
        if (root == NULL) {
            return;
        }
        mp[location].push_back(root -> val);
        helper(root -> left, location - 1, mp);
        helper(root -> right, location + 1, mp);
        return;
    }
 
    void generate(map<int, vector<int>>& mp, vector<vector<int>>& ans) {
        map<int, vector<int>>::iterator it;
        for (it = mp.begin(); it != mp.end(); it++) {
            ans.push_back(it -> second);
        }
        return;
    }
};


========== . Queue is not working as well =====

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> verticalTraversal(TreeNode* root) {
        if (root == NULL) {
            return vector<vector<int>>();
        }
        vector<vector<int>> ans;
        map<int, vector<int>> mp;
        helper(root, 0, mp);
        generate(mp, ans);
        return ans;
    }
 
    void helper(TreeNode* root, int location, map<int, vector<int>>& mp) {
        if (root == NULL) {
            return;
        }
        queue<pair<int, TreeNode*>> q;
        q.push(make_pair(0, root));
     
        while (!q.empty()) {
            pair<int, TreeNode*> node = q.front(); q.pop();
            mp[node.first].push_back(node.second -> val);
            if (node.second -> left) {
                q.push(make_pair(node.first - 1, node.second -> left));
            }
            if (node.second -> right) {
                q.push(make_pair(node.first + 1, node.second -> right));
            }
        }
    }
 
    void generate(map<int, vector<int>>& mp, vector<vector<int>>& ans) {
        map<int, vector<int>>::iterator it;
        for (it = mp.begin(); it != mp.end(); it++) {
            ans.push_back(it -> second);
        }
        return;
    }
};

================== Right one ============
class Solution
{
    public:
    vector<vector<int>> verticalTraversal(TreeNode* root)
    {
        vector<vector<int>> result;
        map<int,map<int,vector<int>>> total;
        deque<TreeNode*> q;
        deque<int> p;
        deque<int> h;
        q.push_back(root);
        p.push_back(0);
        h.push_back(0);
        while(q.size()>0)
        {
            TreeNode* c=q.front();
            int x=p.front();
            int y=h.front();
            q.pop_front();
            p.pop_front();
            h.pop_front();
            total[x][y].push_back(c->val);
            if(c->left!=NULL)
            {
                q.push_back(c->left);
                p.push_back(x-1);
                h.push_back(y+1);
            }
            if(c->right!=NULL)
            {
                q.push_back(c->right);
                p.push_back(x+1);
                h.push_back(y+1);
            }
        }
        for(map<int,map<int,vector<int>>>::iterator it1=total.begin();it1!=total.end();it1++)
        {
            vector<int> temp;
            for(map<int,vector<int>>::iterator it2=it1->second.begin();it2!=it1->second.end();it2++)
            {
                sort(it2->second.begin(),it2->second.end());
                for(int i=0;i<it2->second.size();i++)
                {
                    temp.push_back(it2->second[i]);
                }
            }
            result.push_back(temp);
        }
        return result;
    }
};


Random Pick with Weight

Given an array w of positive integers, where w[i] describes the weight of index i, write a function pickIndex which randomly picks an index in proportion to its weight.
Note:
  1. 1 <= w.length <= 10000
  2. 1 <= w[i] <= 10^5
  3. pickIndex will be called at most 10000 times.
Example 1:
Input: 
["Solution","pickIndex"]
[[[1]],[]]
Output: [null,0]
Example 2:
Input: 
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
Output: [null,0,1,1,1,0]

// Prefix Sum + Binary search

class Solution {
    private:
        vector<int> data;
public:
    Solution(vector<int>& w) {
        data = w;
        for (int i = 1; i < w.size(); i++) {
            data[i] = data[i -1] + w[i];
        }
    }
   
    int pickIndex() {
        int size = data.size();
        int random = rand() % data.back() + 1;
        int st = 0, end = size - 1;
        while (st < end) {
            int mid = st + (end - st) / 2;
            if (data[mid] == random) {
                return mid;
            } else if (data[mid] < random) {
                st = mid + 1;
            } else {
                end = mid;
            }
        }
        return st;
    }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* obj = new Solution(w);
 * int param_1 = obj->pickIndex();
 */

Divide Two Integers

Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividing dividend by divisor.
The integer division should truncate toward zero.
Example 1:
Input: dividend = 10, divisor = 3
Output: 3
Example 2:
Input: dividend = 7, divisor = -3
Output: -2
Note:
  • Both dividend and divisor will be 32-bit signed integers.
  • The divisor will never be 0.
  • Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.

class Solution {
public:
    int binary_helper(int dividend, int divisor) {
        long divd = abs((long)dividend);
        long div = abs((long)divisor);
        int ans = 0;
        while (true) {
            int partial_ans = 0;
            long new_div = div;
            if (divd == div) {
                return ans + 1;
            } else if (divd < div) {
                return ans;
            }
            while(true) {
                if ((new_div << 1) > divd) {
                    break;
                }
                new_div <<= 1;
                partial_ans++;
            }
            if (partial_ans == 0) {
                ans += 1;
                break;
            }
            divd -= new_div;
            ans += (1 << partial_ans);
        }
        return ans;
    }
 
    int divide(int dividend, int divisor) {
        if (divisor == 0) {
            return INT_MAX;
        }
             
        if (dividend == INT_MIN) {
            if (divisor == 1) {
                return INT_MIN;
            } else if (divisor == -1) {
                return INT_MAX;
            }
        }

        int sign_a = (dividend < 0 ? -1 : 1);
        int sign_b = (divisor < 0 ? -1 : 1);

        //int ans = linear_helper(dividend, divisor);
        int ans = binary_helper(dividend, divisor);
        return ans * sign_a * sign_b;
    }
 
    long linear_helper(int dividend, int divisor) {
        long divd = abs((long)dividend);
        long div = abs((long)divisor);
        long count = 0;
        while (divd >= div) {
            count++;
            divd -= div;
        }
        return count;
    }
};




============== Cleaner one ===========
public int divide(int dividend, int divisor) {
    //handle special cases
    if(divisor==0) return Integer.MAX_VALUE;
    if(divisor==-1 && dividend == Integer.MIN_VALUE)
        return Integer.MAX_VALUE;
 
    //get positive values
    long pDividend = Math.abs((long)dividend);
    long pDivisor = Math.abs((long)divisor);
 
    int result = 0;
    while(pDividend>=pDivisor){
        //calculate number of left shifts
        int numShift = 0;    
        while(pDividend>=(pDivisor<<numShift)){
            numShift++;
        }
 
        //dividend minus the largest shifted divisor
        result += 1<<(numShift-1);
        pDividend -= (pDivisor<<(numShift-1));
    }
 
    if((dividend>0 && divisor>0) || (dividend<0 && divisor<0)){
        return result;
    }else{
        return -result;
    }
}

============= Another ======
class Solution {
public:
    int divide(int dividend, int divisor) {
        if (dividend == INT_MIN && divisor == -1) {
            return INT_MAX;
        }
        int sign = 1;
        if (dividend < 0) {
            sign *= -1;
        }
        if (divisor < 0) {
            sign *= -1;
        }
        // return sign;
        if (dividend == 0 || divisor == 0) {
            return 0;
        }
        
        long temp = labs(dividend);
        long tempDiv = labs(divisor);
        if (temp == tempDiv) {
            return sign;
        }
        
        long ans = 0;
        while (temp != 0) {
            int k = 0;
            while ((tempDiv << k) <= temp) {
                k++;
            }
            if (k == 0) {
                return sign * ans;
            }
            ans += (1 << (k - 1));
            temp -= (tempDiv << (k - 1));
        }
        return  sign == 1 ? ans : -ans;
    }
};

Wednesday, October 16, 2019

Expression Add Operators

Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators (not unary) +-, or * between the digits so they evaluate to the target value.
Example 1:
Input: num = "123", target = 6
Output: ["1+2+3", "1*2*3"] 
Example 2:
Input: num = "232", target = 8
Output: ["2*3+2", "2+3*2"]
Example 3:
Input: num = "105", target = 5
Output: ["1*0+5","10-5"]
Example 4:
Input: num = "00", target = 0
Output: ["0+0", "0-0", "0*0"]
Example 5:
Input: num = "3456237490", target = 9191
Output: []
Accepted
79,133
Submissions
233,892

class Solution {
public:
 
    void helper(string& num, int st, int target,
                long diff, long total, string s, vector<string>& ans) {
     
        if (st == num.size()) {
            if (total == target) {
               ans.push_back(s);
            }
            return;
        }
     
        for (int i = 1; i < num.size() - st + 1; i++) {
            string curStr = num.substr(st, i);
            if (curStr.size() > 1 && curStr[0] == '0') {continue;}
            long curNum = stoll(curStr);
            if (!s.empty()) {
                helper(num, st + i, target, curNum,
                       total + curNum, s + "+" + curStr, ans);
                helper(num, st + i, target, -curNum,
                       total - curNum, s + "-" + curStr, ans);
                helper(num, st + i, target, diff * curNum,
                       (total - diff) + diff * curNum, s + "*" + curStr, ans);
            } else {
                helper(num, st + i, target, curNum, curNum, curStr, ans);
            }
        }
        return;
    }
 
    vector<string> addOperators(string num, int target) {
        vector<string> ans;
        if (num.empty()) {
            return ans;
        }

        helper(num, 0, target, 0, 0, "", ans);
        return ans;
    }
};


============
class Solution {
public:
    vector<string> addOperators(string num, int target) {
        vector<string> sol;
        helper(num, 0, 0, 0, target, "", sol);
        return sol;
    }
   
    void helper(string num, int idx, long sum, long prevNum, int target,
                string ans, vector<string>& sol) {
        if (idx == num.size()) {
            if (sum == target) {
                sol.push_back(ans);
            }
            return;
        }
       
        for (int i = idx; i < num.size(); i++) {
            string str = num.substr(idx, i - idx + 1);
            if (str.size() > 1 && str[0] == '0') {
                continue;
            }
            long tmp = stoll(str);
            if (ans.empty()) {
                helper(num, i + 1, tmp, tmp, target, str, sol);
            } else {
                helper(num, i + 1, sum + tmp, tmp, target, ans + "+" + str, sol);
                helper(num, i + 1, sum - tmp, -tmp, target, ans + "-" + str, sol);
                helper(num, i + 1, (sum - prevNum) + prevNum * tmp, prevNum * tmp, target, ans + "*" + str, sol);
            }
           
        }
    }
};

Monday, October 14, 2019

Number of Longest Increasing Subsequence

Given an unsorted array of integers, find the number of longest increasing subsequence.
Example 1:
Input: [1,3,5,4,7]
Output: 2
Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7].
Example 2:
Input: [2,2,2,2,2]
Output: 5
Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is 1, so output 5.
Note: Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int.


class Solution {
public:
    int findNumberOfLIS(vector<int>& nums) {
        if (nums.size() == 0) {
            return 0;
        }
        vector<int> dp(nums.size(), 1);
        vector<int> count(nums.size(), 1);
        int max_count = 1;
        for (int i = 1; i < nums.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    if (dp[i] < dp[j] + 1) {
                        dp[i] = dp[j] + 1;
                        count[i] = count[j];
                    } else if (dp[i] == dp[j] + 1) {
                        count[i] += count[j];
                    }
                }
                max_count = max(max_count, dp[i]);
            }
        }
       
        int ans = 0;
        for (int i = 0; i < dp.size(); i++) {
            if (dp[i] == max_count) {
                ans += count[i];
            }
        }
        return ans;
    }
};

Sunday, October 13, 2019

Average of Levels in Binary Tree

Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array.
Example 1:
Input:
    3
   / \
  9  20
    /  \
   15   7
Output: [3, 14.5, 11]
Explanation:
The average value of nodes on level 0 is 3,  on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11].
Note:
  1. The range of node's value is in the range of 32-bit signed integer.

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        vector<double> ans;
        vector<TreeNode*> q;
        vector<TreeNode*> next;
        if (root == NULL) {
            return ans;
        }
        q.push_back(root);
        ans.push_back(root -> val);
        long sum = 0;
        for (int i = 0; i < q.size(); i++) {
            TreeNode *tmp = q[i];
            if (tmp -> left) {
                next.push_back(tmp -> left);
                sum += tmp -> left -> val;
            }
            if (tmp -> right) {
                next.push_back(tmp -> right);
                sum += tmp -> right -> val;
            }
            if (i == q.size() - 1) {
                if (next.size() != 0) {
                    ans.push_back((double)sum / next.size());
                }
                q = next;
                next.clear();
                i = -1;
                sum = 0;
            }
        }
        return ans;
    }
};

============== USing queue and figure out the size in the beginning =====
class Solution { public: vector<double> averageOfLevels(TreeNode* root) { vector<double> values_to_return; if(root == nullptr) return values_to_return; queue<TreeNode*> levels; levels.push(root); values_to_return.push_back(root->val); int which_level = 0; while(!levels.empty()){ which_level = levels.size(); vector<double> tmp; while(which_level>0){ TreeNode * node = levels.front(); levels.pop(); if(node->left){ levels.push(node->left); tmp.push_back(node->left->val); } if(node->right){ levels.push(node->right); tmp.push_back(node->right->val); } which_level--; } double sum = 0; if(tmp.size()>0){ for(int i =0; i<tmp.size(); ++i){ sum = tmp[i]+sum; } values_to_return.push_back(sum/tmp.size()); } } return values_to_return; } };

Subtree of Another Tree

Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself.
Example 1:
Given tree s:
     3
    / \
   4   5
  / \
 1   2
Given tree t:
   4 
  / \
 1   2
Return true, because t has the same structure and node values with a subtree of s.
Example 2:
Given tree s:
     3
    / \
   4   5
  / \
 1   2
    /
   0
Given tree t:
   4
  / \
 1   2
Return false.
Accepted
127,861
Submissions
300,452

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSubtree(TreeNode* s, TreeNode* t) {
        if (s == NULL) {
            return t == NULL;
        }
        
        if (s -> val == t -> val) {
            bool ans = check(s, t);
            if (ans) {
                return true;
            }
        }
        return isSubtree(s -> left, t) || isSubtree(s -> right, t);
    }
    
    bool check(TreeNode* s, TreeNode* t) {
        if (s == NULL) {
            return t == NULL;
        }
        if (t == NULL) {
            return s == NULL;
        }
        if (s -> left == NULL && s -> right == NULL && t -> left == NULL && t -> right == NULL) {
            return s -> val == t -> val;
        } else {
            return (s -> val == t -> val) && check(s -> left, t -> left) && check(s -> right, t -> right);
        }
        return false;
    }
};


========= Cleaner one =======

bool isSubtree(TreeNode* s, TreeNode* t) { if(!s) return false; if (isSame(s,t)) return true; return isSubtree(s->left,t) || isSubtree(s->right,t); } bool isSame(TreeNode *s, TreeNode *t) { if (!s && !t) return true; if (!s || !t) return false; if (s->val != t->val) return false; return isSame(s->left, t->left) && isSame(s->right, t->right); }