Leetcode_binary tree related_c++ version

(1) 236 Recent Common Ancestors of Binary Trees – Medium

Given a binary tree, find the nearest common ancestor of two specified nodes in the tree.

The definition of the nearest common ancestor in Baidu Encyclopedia is: "For two nodes p and q of a rooted tree T, the nearest common ancestor is represented as a node x, such that x is the ancestor of p and q and the depth of x is as large as possible (a A node can also be its own ancestor)."
Insert image description here

Method 1: Subscript method

The larger subscript is divided by 2 until the two subscripts are the same, which is the common precursor subscript.
There will be an overly long set in the test case, and the subscript will exceed the floating point representation range, causing an error. You can only find another method

/**
 * 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:

    float getIndex(TreeNode* root, float index, int value){
    
    
        if(root == NULL) return -1;
        if(value == root->val) {
    
    
            cout<< index << endl;
            return index;
        }
        float returnValue = getIndex(root->left, 2*index, value);
        if(returnValue > 0)return returnValue;
        returnValue = getIndex(root->right, 2*index+1, value);
        if(returnValue > 0)return returnValue;
        return -1;
    }

    TreeNode* getNode(TreeNode* root, float index, float targetIndex, int &statute){
    
    
        
        if(root == NULL) return NULL;
        //cout<<"value="<<root->val <<" index="<< index<<endl;
        if(index == targetIndex){
    
    
            statute = 1;
            return root;
        }
        TreeNode* tmpNode = getNode(root->left, 2*index, targetIndex, statute);
        if(statute == 1)return tmpNode;
        tmpNode = getNode(root->right, 2*index+1, targetIndex, statute);
        if(statute == 1)return tmpNode;
        return NULL;
            
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
        float index1 = getIndex(root, 1, p->val);
        float index2 = getIndex(root, 1, q->val);
        while(index1>1 && index2>1){
    
    
            if(index1 == index2) break;
            if(index1 > index2) index1 = floor(index1/2);
            else index2 = floor(index2/2);
        }
        cout<<"index1="<< index1 << " index2="<<index2<<endl;
        if(index1 == 1 || index2 == 1) return root;
        
        else{
    
    
            int statute = 0;
            return getNode(root, 1, index1, statute);
        }
        
    }
};

Insert image description here

Method 2: Use the stack

/**
 * 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:
    //将根节点到该点的路径push到栈中
    void getPath(vector<TreeNode*>& path, int& statute,TreeNode* p, int targetValue){
    
    
        if(statute == 1 || p == NULL) return;
        
        if(p->val == targetValue) {
    
    
            //cout<<" push "<<p->val;
            path.push_back(p);
            statute = 1;
            return;
        }
        path.push_back(p);
        getPath(path, statute, p->left,  targetValue);
        if(statute == 1) return;
        getPath(path, statute, p->right,  targetValue);
        if(statute == 1) return;
        //未找到目标节点,回溯
        path.pop_back();
        return;

        
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
        vector<TreeNode*> path_p;
        vector<TreeNode*> path_q;
        //标志是否找到该元素
        int statute = -1;
        getPath(path_p, statute, root, p->val);
        statute = -1;
        getPath(path_q, statute, root, q->val);
        
        while(path_p.size()>1 && path_q.size()>1){
    
    
            int pPathLength = path_p.size();
            int qPathLength = path_q.size();
            //cout<<endl<<" plength="<<pPathLength<<" qlength="<<qPathLength<<endl;
            if(path_p[pPathLength-1]->val == path_q[qPathLength - 1]->val) {
    
    
                //cout<<"ptop="<<path_p[pPathLength-1]->val<<" qtop="<<path_q[qPathLength - 1]->val;
                break;
            }
            //如果找到公共路径,两栈的长度一定是一样长的
            //将长度较长的栈pop栈顶元素
            if (pPathLength >= qPathLength) {
    
    
                path_p.pop_back();
                pPathLength--;
            }
            else if (pPathLength < qPathLength) {
    
    
                path_q.pop_back();
                qPathLength--;
            }
        }
        if(path_p.size() == 1 || path_q.size() == 1) return root;
        else return path_p[path_p.size() - 1];
        
    }
};

Insert image description here

(2) The expansion of 114 binary trees into linked lists – medium

Given the root node root of a binary tree, please expand it into a singly linked list:

The expanded singly linked list should also use TreeNode, where the right child pointer points to the next node in the linked list, and the left child pointer is always null.
The expanded singly linked list should be in the same order as the binary tree pre-order traversal.
Insert image description here

/**
 * 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:
    void preOrder(TreeNode*& node, TreeNode*& last){
    
    
        if(node == NULL) return;
        if(node->left == NULL && node->right == NULL){
    
    
            last = node;
            return;
        }
        //节点备份
        TreeNode* left = node->left;
        TreeNode* right = node->right;
        //左子树放到根节点的右子树上,左指针置为空
        if(left){
    
    
            node->right = left;
            node->left = NULL;
            last = left;
            preOrder(left, last);
        }
        //右子树放到最后一个操作的节点的右子树上
        if(right){
    
    
            last->right = right;
            last = right;
            preOrder(right, last);
        }
        return;
    }    
    
    void flatten(TreeNode* root) {
    
    
        if(root == NULL || (root->left == NULL && root->right == NULL)) return;
        //last记录最后一个操作的节点
        TreeNode* last = root;
        preOrder(root, last);
        return;
    }


};

Insert image description here

(3) Right view of 199 binary tree – medium

Given the root node root of a binary tree, imagine yourself standing on the right side of it, and return the node values ​​that can be seen from the right side in order from top to bottom.
Insert image description here

/**
 * 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:
    //不管何种遍历,在同一层的情况下,总是先遍历左边的,再遍历右边的,因此只需要记录同一层最后遍历的节点
    void preOrder(vector<int>& result, TreeNode* root, int depth){
    
    
        if(root == NULL) return;
        //深度只会线性增长,不会跳跃式,新的深度的值只需放在数组最后即可
        if(depth > result.size()){
    
    
            result.push_back(root->val);
        }
        //同层,用新的值替换老的值
        else{
    
    
            result[depth - 1] = root->val;
        }
        preOrder(result, root->left, depth+1);
        preOrder(result, root->right, depth+1);
    }

    vector<int> rightSideView(TreeNode* root) {
    
    
        vector<int> result;
        //result.push_back(root->val);
        preOrder(result, root, 1);
        return result;
    }
};

Insert image description here

(4) 449 Serializing and Deserializing Binary Search Trees – Medium

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted over a network connection link for later reconstruction in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary search tree. There are no restrictions on how the serialization/deserialization algorithm works. You just need to make sure that the binary search tree can be serialized to a string, and that the string can be deserialized into the original binary search tree.

The encoded string should be as compact as possible.
Insert image description 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 Codec {
    
    
public:
    //先根序遍历二叉树,插入字符串,若数字为54,插入后变为“45#”
    void preOrder(TreeNode* root, string& result){
    
    
        if(root) {
    
    
            int num = root->val;
            while(num != 0){
    
    
                //从低位到高位逆序插入字符串
                result.push_back(num%10 +'0');
                num = num/10;
            }
            result += '#';
            preOrder(root->left, result);
            preOrder(root->right, result);
        }
        
    }
    // Encodes a tree to a single string.

    string serialize(TreeNode* root) {
    
    
        string result = "";
        preOrder(root, result);
        return result;
        
    }


    void insertNode(TreeNode* &root, int num){
    
    
        //根为空,则创建新节点插入
        if(root == NULL) {
    
    
            //cout<< "insert";
            root = new TreeNode(num);
            return;
        }
        //大于根,则插入根的右子树
        else if(num >= root->val){
    
    
            //cout<< "num = "<< num<< " root="<<root->val<< " right"<<endl;
            insertNode(root->right, num);
        }
        //小于根,则插入根的左子树
        else {
    
    
            //cout<< "num = "<< num<< " root="<<root->val<< " left"<<endl;
            insertNode(root->left, num);
        }
    }
    // Decodes your encoded data to tree.

    TreeNode* deserialize(string data) {
    
    
        TreeNode* root = NULL;
        //cout << data <<"  length="<<data.length()<< endl;
        if(data.length() == 0) return root;
        //count标记位数
        int count = 0;
        for(int i = 0; i< data.length(); i++ ){
    
    
            int sum = 0;
            //没遇到“#”则认为还是同一个数
            while(data[i] != '#'){
    
    
                int num = data[i]-'0';
                //cout<< "data="<<data[i]<<" num="<< num<<" count="<<count<<endl;
                for(int j = 0; j < count;j++){
    
    
                    //cout<< num<< endl;
                    //高位需乘10
                    num = num * 10;
                }
                
                count += 1;
                sum +=  num;
                i++;
            }
            //cout<<"push "<< sum<< endl;
            count = 0;
            insertNode(root, sum);
        }return root;
        
    }
};

// Your Codec object will be instantiated and called as such:
// Codec* ser = new Codec();
// Codec* deser = new Codec();
// string tree = ser->serialize(root);
// TreeNode* ans = deser->deserialize(tree);
// return ans;

Insert image description here

Guess you like

Origin blog.csdn.net/weixin_44343355/article/details/132892627