2020_12_21 LeetCode刷题

本文总结了六道树类型题目的解题思路与代码实现,包括二叉搜索树中的众数、二叉搜索树的最小绝对差、二叉树的直径等。采用递归回溯的方法解决树的问题,分享了每道题目的具体实现过程。

今日刷题六道,六道题目都是树类型的题目,最后一到题目在15min内实现过程中出现了一些差错,其他的题目都是在15min内完成。要准备考试了,只能在复习间隙休息的时间刷题放松,争取在考试前能够补完简单难度的题目。

501. 二叉搜索树中的众数
递归回溯题。没有达成最优解,使用了额外的空间,递归统计各个数,同时记录得出最多的次数,之后直接遍历哈希表将出现次数最多的数存放即可。

/**
 * 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:
    int maxnum = -1;
    map<int,int> p;
    vector<int> findMode(TreeNode* root) {
        maxnum = -1;
        vector<int> ans;
        dfstree(root);
        for(map<int,int>::iterator it1 = p.begin();it1 != p.end();  it1++) {
            if(it1->second == maxnum) {
                int ans1 = it1->first;
                ans.push_back(ans1);
            }
        }
        return ans;
    }
    void dfstree(TreeNode* root) {
        if(root == nullptr) 
            return ;
        int num1 = root->val;
        p[num1] += 1;
        maxnum = max(maxnum,(int)p[num1]);
        dfstree(root->left);
        dfstree(root->right);
    }
};

530. 二叉搜索树的最小绝对差
递归回溯题。首先遍历树,记录所有节点的数值,之后排序,相邻两个数相减比较求取最小值。

/**
 * 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:
    int getMinimumDifference(TreeNode* root) {
        vector<int> number1;
        dfsTree(root,number1);
        sort(number1.begin(),number1.end());
        int len1 = number1.size();
        int ans = 0;
        for(int i = 1; i < len1; i++) {
            if(i == 1)
                ans = number1[i] - number1[i-1];
            else
                ans = min(ans, number1[i] - number1[i-1]);
        }
        return ans;
    }
    void dfsTree(TreeNode* root,vector<int>& nums) {
        if(root == nullptr)
            return;
        nums.push_back(root->val);
        dfsTree(root->left,nums);
        dfsTree(root->right,nums);
    }
};

543. 二叉树的直径
递归回溯题。根据给定的样例数据,认为应该是根节点的左子树最大深度+根节点的右子树最大深度,但是其直径可能不经过根节点,所以需要重新考虑,即在遍历的过程中,判定该节点的左子树最大深度+右子树的最大深度是否为最大值,如果为最大值,则更新进行记录,说明当前值为直径,否则继续进行遍历。最后返回最大的数值结果就是直径。

/**
 * 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:
    int ans = 0;
    int diameterOfBinaryTree(TreeNode* root) {
        if(root == nullptr)
            return 0;
        ans = 0;
        int sum1 = deepth(root->left);
        int sum2 = deepth(root->right);
        ans = max(ans,sum1 + sum2);
        return ans;
    }
    int deepth(TreeNode* root) {
        if(root == nullptr)
            return 0;
        int sum1 = deepth(root->left);
        int sum2 = deepth(root->right);
        ans = max(ans,sum1 + sum2);
        return max(sum1,sum2) + 1;
    }
};

559. N 叉树的最大深度
递归回溯题。从二叉树变成了N叉树,在递归过程中,每一个子树都要进行深度的求取然后比较大小求取最大值,最后返回输出即可求得答案。

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    int maxDepth(Node* root) {
        if(root == nullptr)
            return 0;
        int ans = deepth(root);
        return ans + 1;
    }
    int deepth(Node* root) {
        if(root == nullptr)
            return 0;
        int ans = 0, len1 = root->children.size();
        for(int i = 0; i < len1; i++)
            ans = max(ans, deepth(root->children[i]) + 1);
        return ans;
    }
};

563. 二叉树的坡度
递归回溯题。明确在回溯的过程中,返回当前子树的所有节点的和的数值,之后在回溯函数中,先分别计算左子树和右子树的各个节点的和,再计算坡度,最后返回以当前节点为根的所有节点的和,即得出答案。当前节点为nullptr则返回数值0。

/**
 * 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:
    int ans = 0;
    int findTilt(TreeNode* root) {
        ans = 0;
        int z = SumofTree(root);
        return ans;
    }
    int SumofTree(TreeNode* root) {
        if(root == nullptr)
            return 0;
        //计算左子树和
        int sum1 = SumofTree(root->left);
        //计算右子树和
        int sum2 = SumofTree(root->right);
        //计算坡度
        ans += abs(sum1 - sum2);
        //返回左右子树的和
        return root->val + sum1 + sum2;
    }
};

572. 另一个树的子树
递归回溯题。首先使用一个递归函数进行树的节点遍历,当树的当前节点的数值等于目标树根节点数值时,再调用另一个递归函数进行判定,对于每一个节点进行递归判定,判断是否相同,最后返回最终的结果即可。

/**
 * 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:
    bool ans = false;
    bool isSubtree(TreeNode* s, TreeNode* t) {
        ans = false;
        dfsTree(s,t);
        return ans;
    }
    void dfsTree(TreeNode* s,TreeNode* t) {
        if(ans)
            return;
        if(s == nullptr)
            return;
        if(s->val == t->val)
            ans = dfsSubTree(s,t);
        dfsTree(s->left,t);
        dfsTree(s->right,t);
    }
    bool dfsSubTree(TreeNode* s,TreeNode* t) {
        if(s == nullptr && t == nullptr)
            return true;
        if(s == nullptr && t != nullptr)
            return false;
        if(s != nullptr && t == nullptr)
            return false;
        bool ans = true;
        if(s != nullptr && t != nullptr)
            ans = (s->val == t->val);
        return dfsSubTree(s->left,t->left) && dfsSubTree(s->right,t->right) && ans;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值