cpp刷题打卡记录24——路径总和 & 路径总和II

路径总和

法一:迭代

cpp 复制代码
/**
 * 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 hasPathSum(TreeNode* root, int targetSum) {
        if(root == NULL){
            return false;
        }
        stack<pair<TreeNode*, int>> st;
        st.push(pair<TreeNode*, int>(root, root->val));
        while(!st.empty()){
            pair<TreeNode*, int> node = st.top();
            st.pop();
            if(!node.first->left && !node.first->right && node.second == targetSum){
                return true;
            }
            if(node.first->right){
                st.push(pair<TreeNode*, int>(node.first->right, node.second+node.first->right->val));
            }
            if(node.first->left){
                st.push(pair<TreeNode*, int>(node.first->left, node.second+node.first->left->val));
            }
        }
        return false;
    }
};

思路是:整体采用前序遍历,因为既要遍历树的节点又需要记录从头节点到当前节点的路径的值,所以用pair结构 pair<TreeNode*, int> pair<节点指针, 路径数值> 来存放在这个栈里的元素。还需注意的是路径是根节点到叶子节点的,叶子节点是没有左孩子节点和右孩子节点的。

法二·:递归

cpp 复制代码
class Solution {
public:
    bool traversal(TreeNode* current, int sum){
        if(!current->left && !current->right && sum == 0){
            return true;
        }
        if(!current->left && !current->right){
            return false;
        }

        if(current->left){
            sum -= current->left->val;
            if(traversal(current->left, sum)){
                return true;
            }
            sum += current->left->val;
        }

        if(current->right){
            sum -= current->right->val;
            if(traversal(current->right, sum)){
                return true;
            }
            sum += current->right->val;
        }
        return false;
    }
    
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root == NULL){
            return false;
        }
        return traversal(root, targetSum - root->val);
    }
};

及其不擅长写递归。

路径总和II

cpp 复制代码
class Solution {
public:
    vector<int> path;
    vector<vector<int>> result;
    void traversal(TreeNode* current, int count){
        if(!current->left && !current->right && count == 0){
            result.push_back(path);
            return;
        }

        if(!current->left && !current->right){
            return;
        }

        if(current->left){
            path.push_back(current->left->val);
            count -= current->left->val;
            traversal(current->left, count);
            count += current->left->val;
            path.pop_back();
        }

        if(current->right){
            path.push_back(current->right->val);
            count -= current->right->val;
            traversal(current->right, count);
            count += current->right->val;
            path.pop_back();
        }
        return;
    }

    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if(root == NULL){
            return result;
        }        
        path.push_back(root->val); //别忘记把根节点放进路径
        traversal(root, targetSum - root->val);
        return result;
    }
};

与上一题不同的是,这道题目需要遍历整个树

!!一定要注意traversal中if里面的return,这个return只是返回了当前的递归,没有结束整个递归。也就是说在找到一条路径后,只结束当前节点的递归,返回到父节点,然后继续探索该父节点的其他子节点。

本集心得:

讨厌递归,老是想不到。

相关推荐
伊玛目的门徒7 小时前
试用leetcode之典中典 二数之和问题
java·算法·leetcode
Jerry7 小时前
LeetCode 226. 翻转二叉树
算法
想做小南娘,发现自己是女生喵8 小时前
【无标题】
数据结构·算法
Kx_Triumphs10 小时前
HDU4348 To the moon(主席树区间修改模板)
算法·题解
旖-旎10 小时前
《LeetCode647 回文子串 || LeetCode 5 最长回文子串》
c++·算法·leetcode·动态规划·哈希算法
Darkwanderor11 小时前
对Linux的进程控制的研究
linux·运维·c++
云泽80811 小时前
从零吃透 C++ 异常:抛出捕获、栈展开、异常重抛与编码规范详解
开发语言·c++·代码规范
轻颂呀11 小时前
约瑟夫环问题
算法
REDcker12 小时前
libdatachannel 快速入门
c++·webrtc·datachannel