0
点赞
收藏
分享

微信扫一扫

【超详细图文讲解】如何利用VMware创建CentOS虚拟机(包括如何更改网络设置 + 远程访问虚拟机方法)

王栩的文字 03-19 08:30 阅读 3

Leetcode hot100

二叉树

1.路径总和 III

路径总和 III
思路:我们访问每一个节点 node,检测以 node 为起始节点且向下延深的路径有多少种。递归遍历每一个节点的所有可能的路径,然后将这些路径数目加起来即为返回结果。
综上:递归是比较合适的方法。

当前层需要干什么:求出以当前 root 为节点向下遍历的和 == targetsum 的个数
rootSum(TreeNode* root, int targetSum)
以当前节点 p 为目标路径的起点递归向下进行搜索。假设当前的节点 p 的值为 val,我们对左子树和右子树进行递归搜索,对节点 p 的左孩子节点 pl 求出 rootSum(pl, targetSum−val)
以及对右孩子节点 pr 求出 rootSum(pr, targetSum−val)。节点 p 的 rootSum(p, targetSum)即等于 rootSum(pl,targetSum−val) + rootSum(pr,targetSum−val),同时我们还需要判断一下当前节点 p 的值是否刚好等于 targetSum。

/**
 * 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:
	//以各个节点为根节点
	//root,root->left,root->right,root->left->left,root->left->right......
	int pathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) return 0;
        return rootSum(root, targetSum) + pathSum(root->left, targetSum) 
                + pathSum(root->right, targetSum);
    }
	
	//以当前节点为根节点,找到从当前节点向下遍历,节点相加和为target的次数
    int rootSum(TreeNode* root, long targetSum) {
        if (root == nullptr) return 0;
        int ret = 0;
        if (root->val == targetSum) ret++;
        ret += rootSum(root->left, targetSum - root->val);
        ret += rootSum(root->right, targetSum - root->val);
        return ret;
    }
};

2.路径总和 II

路径总和 II
虽然这道题不在hot100里,但是和上一道题很类似,该题是求所有 从根节点到叶子节点 路径总和等于给定目标和的路径。显然还是用递归的方法更合适。
我们可以递归遍历记录所有的路径,同时计算路径和,如果等于那么添加到最终的vector<vector< int >>中。

函数 dfs(TreeNode* root, int targetSum)

递推参数: 当前节点 root ,当前目标值 targetSum。
终止条件: 若节点 root 为空,则直接返回。
递推工作
路径更新: 将当前节点值 root->val 加入路径 vector<int>tmp
目标值更新: targetSum = targetSum - root->val (即目标值 targetSum 从 targetSum 减至 0 )。
路径记录: 当 (1) root 为叶节点(左右子树均为空) 且 (2) 路径和等于目标值(targetSum == 0),则将此路径 tmp 加入 ans 。
先序遍历: 递归左 / 右子节点。
路径恢复: 向上回溯前,需要将当前节点从路径 tmp 中删除,即执行 tmp.pop_back()

/**
 * 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:
    vector<vector<int>> ans;
    vector<int> tmp;
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) return ans;
        dfs(root, targetSum);
        return ans;
    }

    void dfs(TreeNode* root, int targetSum) {
        if (root == nullptr) return;
        tmp.push_back(root->val);
        targetSum -= root->val;
        if (root->left == nullptr && root->right == nullptr && targetSum == 0) {
            ans.push_back(tmp);
        }
        dfs(root->left, targetSum);
        dfs(root->right, targetSum);
        tmp.pop_back();
    }
};

在这里插入图片描述

在这里插入图片描述

3.二叉树的所有路径

二叉树的所有路径
再来看一道相似的题目,只需要记录从根节点到叶子节点的路径即可

/**
 * 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:
    vector<string> ans;
    vector<string> binaryTreePaths(TreeNode* root) {
        if (root == nullptr) return ans;
        string tmp;
        dfs(root, tmp);
        return ans;
    }
    void dfs(TreeNode* root, string tmp) {
        if (root == nullptr) return;
        tmp += to_string(root->val);
        if (root->left == nullptr && root->right == nullptr) {
            ans.push_back(tmp);
        } else {
            tmp += "->";
            dfs(root->left, tmp);
            dfs(root->right, tmp);
        }
    }
};

4.二叉树的最近公共祖先

二叉树的最近公共祖先
终止条件:

  • 当 root 等于 p,q,则直接返回 root;

递推工作:

  • 开启递归左子节点,返回值记为 left;
  • 开启递归右子节点,返回值记为 right;

返回值:
根据 left 和 right,可展开为四种情况;

  • 当 left 和 right 同时为空 :说明 root 的左 / 右子树中都不包含 p,q,返回 null;
  • 当 left 和 right 同时不为空 :说明 p,q 分列在 root 的 异侧 (分别在 左 / 右子树),因此 root
    为最近公共祖先,返回 root ;
  • 当 left 为空 ,right 不为空 :p,q 都不在 root 的左子树中,直接返回 right。
    具体可分为两种情况:
    • p,q 其中 p 在 root 的 右子树 中,此时 right 指向 p(假设为 p );
    • p,q 两节点都在 root 的 右子树 中,此时的 right 指向 最近公共祖先节点 ;
  • 当 left 不为空 , right 为空 :与情况 3. 同理;
    参考
    在这里插入图片描述
/**
 * 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:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    	//找到p,找到q,或者已经到叶子节点还没找到
        if (root == nullptr || root == p || root == q) return root;
        //遍历左子树
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        //遍历右子树
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        //左右子树点都没找到
        if (left == nullptr && right == nullptr) return nullptr;
        //右边没有p或者q,left要么是p/q,或者是p/q的公共祖先
        if (left != nullptr && right == nullptr) return left;
        if (right != nullptr && left == nullptr) return right;
        return root;
    }
};

回溯

1.电话号码的字母组合

电话号码的字母组合
电话号码的组合就是输入字符对应字符串的全排列,全排列的问题应该用回溯解决。
遍历输入的字符串;
找出对应字符映射的字母;
遍历映射字母;
添加到tmp string中,进行递归;
tmp string 剪枝。
在这里插入图片描述

class Solution {
public:
    unordered_map<char, string> mp = {
        {'2', {"abc"}},
        {'3', {"def"}},
        {'4', {"ghi"}},
        {'5', {"jkl"}},
        {'6', {"mno"}},
        {'7', {"pqrs"}},
        {'8', {"tuv"}},
        {'9', {"wxyz"}}
    };
    vector<string> ans;
    vector<string> letterCombinations(string digits) {
        if (digits.empty()) return ans;
        string tmp;
        dfs(digits, 0, tmp);
        return ans;
    }
    void dfs(string digits, int index, string& tmp) {
        if (index == digits.length()) {
            ans.push_back(tmp);
        } else {
            //遍历输入的数字
            char digit = digits[index];
            //找到数字对应的string
            string letters = mp[digit];
            //遍历数字对应的char
            for (char c: letters) {
                //添加到string
                tmp.push_back(c);
                //递归
                dfs(digits, index + 1, tmp);
                tmp.pop_back();
            }
        }   
    }
};
举报

相关推荐

0 条评论