Wednesday, April 28, 2021

863. All Nodes Distance K in Binary Tree

 We are given a binary tree (with root node root), a target node, and an integer value K.

Return a list of the values of all nodes that have a distance K from the targetnode.  The answer can be returned in any order.

 

    Example 1:

    Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2
    
    Output: [7,4,1]
    
    Explanation: 
    The nodes that are a distance 2 from the target node (with value 5)
    have values 7, 4, and 1.
    
    
    
    Note that the inputs "root" and "target" are actually TreeNodes.
    The descriptions of the inputs above are just serializations of these objects.
    

     

    Note:

    1. The given tree is non-empty.
    2. Each node in the tree has unique values 0 <= node.val <= 500.
    3. The target node is a node in the tree.
    4. 0 <= K <= 1000.

    /**
     * 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<int> distanceK(TreeNode* root, TreeNode* target, int K) {
            vector<int> ans;
            if (root == NULL || target == NULL) {
                return ans;
            }
            if (K == 0) {
                return {target->val};
            }
            // Prepare parentMap
            unordered_map<TreeNode*, TreeNode*> mp;
            PrepareParent(root, NULL, mp);
            
            // BFS
            return BFS(target, mp, K);
        }
        
        void PrepareParent(TreeNode* root, TreeNode *parent, unordered_map<TreeNode*, TreeNode*>& mp) {
            if (root == NULL) {
                return;
            }
            mp[root] = parent;
            PrepareParent(root -> left, root, mp);
            PrepareParent(root -> right, root, mp);
        }
        
        void checkNode(TreeNode *node, queue<TreeNode *>& q, unordered_set<TreeNode *>& visited, vector<int>& ans, int level, int k) {
            if (node != NULL && visited.count(node) == 0) {
                visited.insert(node);
                if (level == k - 1) {
                    ans.push_back(node -> val);
                } else {
                    q.push(node);
                }
            }
        }
        
        vector<int> BFS(TreeNode* node, unordered_map<TreeNode*, TreeNode*>& mp, int k) {
            vector<int> ans;
            unordered_set<TreeNode *> visited;
            queue<TreeNode *> q;
            q.push(node);
            visited.insert(node);
            int level = 0;
            while (!q.empty()) {
                int size = q.size();
                for (int i = 0; i < size; i++) {
                    TreeNode *node = q.front(); q.pop();
                    // All neighbors (both child + parent)
                    TreeNode * left = node -> left;
                    checkNode(left, q, visited, ans, level, k);
                    TreeNode * right = node -> right;
                    checkNode(right, q, visited, ans, level, k);
                    TreeNode * parent = mp[node];
                    checkNode(parent, q, visited, ans, level, k);
                }
                level++;
            }
            return ans;
        }

        // DFS one is shorter too
        /*
        
        class Solution {
    public:
        vector<int> ans;   
        map<TreeNode*, TreeNode*> parent;  // son=>parent  
        set<TreeNode*> visit;    //record visied node
        
        void findParent(TreeNode* node){
            if(!node ) return;
            if( node->left ){
                parent[node->left] = node;
                findParent(node->left);
            }
            if( node->right){
                parent[node->right] = node;
                findParent(node->right);
            }
        }
        
        vector<int> distanceK(TreeNode* root, TreeNode* target, int K) {
            if( !root ) return {};
            
            findParent(root);
            dfs(target, K );
            return ans;
        }
        void dfs( TreeNode* node, int K){
            if( visit.find(node) != visit.end() )
                return;
            visit.insert(node);
            if( K == 0 ){
                ans.push_back(node->val);
                return;
            }
            if( node->left ){
                dfs(node->left, K-1);
            }
            if( node->right){
                dfs(node->right, K-1);
            }
            TreeNode* p = parent[node];
            if( p )
                dfs(p, K-1);
        }
    };
        
        */

    };

    Sunday, April 25, 2021

    669. Trim a Binary Search Tree

     Given the root of a binary search tree and the lowest and highest boundaries as low and high, trim the tree so that all its elements lies in [low, high]. Trimming the tree should not change the relative structure of the elements that will remain in the tree (i.e., any node's descendant should remain a descendant). It can be proven that there is a unique answer.

    Return the root of the trimmed binary search tree. Note that the root may change depending on the given bounds.

     

    Example 1:

    Input: root = [1,0,2], low = 1, high = 2
    Output: [1,null,2]
    

    Example 2:

    Input: root = [3,0,4,null,2,null,null,1], low = 1, high = 3
    Output: [3,2,null,1]
    

    Example 3:

    Input: root = [1], low = 1, high = 2
    Output: [1]
    

    Example 4:

    Input: root = [1,null,2], low = 1, high = 3
    Output: [1,null,2]
    

    Example 5:

    Input: root = [1,null,2], low = 2, high = 4
    Output: [2]
    

     

    Constraints:

    • The number of nodes in the tree in the range [1, 104].
    • 0 <= Node.val <= 104
    • The value of each node in the tree is unique.
    • root is guaranteed to be a valid binary search tree.
    • 0 <= low <= high <= 104

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        TreeNode* trimBST(TreeNode* root, int low, int high) {
            if (root == NULL) {
                return NULL;
            }
            if (root -> val > high) {
                return trimBST(root -> left, low, high);
            } else if (root -> val < low) {
                return trimBST(root -> right, low, high);
            }
            root -> left = trimBST(root -> left, low, high);
            root -> right = trimBST(root -> right, low, high);
            return root;
        }
    };

    405. Convert a Number to Hexadecimal

     Given an integer num, return a string representing its hexadecimal representation. For negative integers, two’s complement method is used.

    All the letters in the answer string should be lowercase characters, and there should not be any leading zeros in the answer except for the zero itself.

     

    Example 1:

    Input: num = 26
    Output: "1a"
    

    Example 2:

    Input: num = -1
    Output: "ffffffff"
    

     

    Constraints:

    • -231 <= num <= 231 - 1

    class Solution {
    public:
        string helper(int num) {
            string ans;
            string mp = "0123456789abcdef";
            while (num != 0) {
                int temp = num & 15;
                ans = mp[temp] + ans;
                num >>= 4;
                // Negative number would end up in num being zero.
                // Hence check the length.
                if(ans.size()==8) {
                    break;
                }
            }
            return ans;
        }
        string toHex(int num) {
            if (num == 0) {
                return "0";
            } else {
                return helper(num);
            }
            
        }
    };

    525. Contiguous Array

     Given a binary array nums, return the maximum length of a contiguous subarray with an equal number of 0 and 1.

     

    Example 1:

    Input: nums = [0,1]
    Output: 2
    Explanation: [0, 1] is the longest contiguous subarray with an equal number of 0 and 1.
    

    Example 2:

    Input: nums = [0,1,0]
    Output: 2
    Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.
    

     

    Constraints:

    • 1 <= nums.length <= 105
    • nums[i] is either 0 or 1.

    class Solution {
    public:
        
        int findMaxLength(vector<int>& nums) {
            unordered_map<int, int> mp;
            mp[0] = -1;
            int ans = 0;
            int counter = 0;
            for (int i = 0; i < nums.size(); i++) {
                if (nums[i] == 1) {
                    counter++;
                } else {
                    counter--;
                }
                if (mp.count(counter) != 0) {
                    ans = max(ans, i - mp[counter]);
                } else {
                    mp[counter] = i;
                }
            }
            return ans;
        }
    };

    536. Construct Binary Tree from String

     You need to construct a binary tree from a string consisting of parenthesis and integers.

    The whole input represents a binary tree. It contains an integer followed by zero, one or two pairs of parenthesis. The integer represents the root's value and a pair of parenthesis contains a child binary tree with the same structure.

    You always start to construct the left child node of the parent first if it exists.

     

    Example 1:

    Input: s = "4(2(3)(1))(6(5))"
    Output: [4,2,6,3,1,5]
    

    Example 2:

    Input: s = "4(2(3)(1))(6(5)(7))"
    Output: [4,2,6,3,1,5,7]
    

    Example 3:

    Input: s = "-4(2(3)(1))(6(5)(7))"
    Output: [-4,2,6,3,1,5,7]
    

     

    Constraints:

    • 0 <= s.length <= 3 * 104
    • s consists of digits, '('')', and '-' only.

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        TreeNode* str2tree(string s) {
            int i = 0;
            return helper(s, i);
        }
        
        TreeNode* helper(string s, int& idx) {
            if (idx == s.size()) {
                return NULL;
            }
            int st = idx;
            if (s[idx] == '-') {
                idx++;
            }
            while (idx < s.size() && (isdigit(s[idx]))) {
                idx++;
            }
            TreeNode *node = new TreeNode(stoi(s.substr(st, idx - st)));
            if (idx == s.size()) {
                return node;
            }
            if (s[idx] == '(') {
                idx++;
                node -> left = helper(s, idx);
                idx++;
            }
            if (s[idx] == '(') {
                idx++;
                node -> right = helper(s, idx);
                idx++;
            }
            return node;
        }
    };


    ===============
        TreeNode* str2tree(string s) 
        {
            if(s.empty()) return NULL;
            
            stack<TreeNode*> st;
            
            int j=0;
            for(int i=0; i<s.size(); i++)
            {
                j = i;
                
                if(s[i]==')') st.pop();
                
                if( (i<s.size() && s[i]>='0' && s[i]<='9') || s[i]=='-' )
                {
                    while(s[i+1]>='0' && s[i+1]<='9') i++;
                    TreeNode* cur = new TreeNode(stoi(s.substr(j, i-j+1)));
                    
                    if(!st.empty())
                    {
                        auto t = st.top();
                        if(!t->left) t->left = cur;
                        else t->right = cur;
                    }
                    
                    st.push(cur);
                }
            }
            
            return st.top();
        }