12.路径总和
2022-05-19 17:05
495 查看
title: 路径总和
📃 题目描述
题目链接:路径总和
🔔 解题思路
可以参考一下 二叉树的所有路径 这题;
方法一:递归方法,回溯,重点:每次传入当前数据的总和进去,每次还需要和targetSum进行比较,太过于麻烦,直接用减法!传入targetSum - root->val进去和下一个节点的val进行对比!
class Solution { public: bool hasPathSum(TreeNode* root, int targetSum) { if(!root) return false; if(!root->left && !root->right) return targetSum == root->val; return hasPathSum(root->left,targetSum - root->val) || hasPathSum(root->right,targetSum - root->val); } }; //为什么不在传入完一条路的所有节点后,判断和是否为0就行?因为避免root = [], targetSum = 0 的情况发生;
方法二:
迭代法,为什么达到和递归函数保存状态,需要用到两个栈,一个保存节点,另一个保存节点所对应的sum值;
class Solution { public: bool hasPathSum(TreeNode* root, int targetSum) { stack<TreeNode*> treeSt;//保存树遍历的节点; stack<int> pathSum;//保存节点对应的总和值; if (root == nullptr) return false; treeSt.push(root); pathSum.push(root->val); while (!treeSt.empty()) { TreeNode *cur = treeSt.top(); treeSt.pop(); int sum = pathSum.top(); pathSum.pop(); if (!cur->left && !cur->right && sum == targetSum) return true; //叶子节点判断 if (cur->left) { treeSt.push(cur->left); //将该节点压进去 pathSum.push(sum + cur->left->val); //也将该节点对应的总和值压进去,达到递归函数不同点,总和不同的效果; } if (cur->right) { treeSt.push(cur->right); pathSum.push(sum + cur->right->val); } } return false; } };
优化一些的写法:竟然需要节点和节点的值对应上,那么我们就采用pair来将两个值捆绑在一起;
class solution { public: bool haspathsum(treenode* root, int sum) { if (root == null) return false; // 此时栈里要放的是pair<节点指针,路径数值> stack<pair<treenode*, int>> st; st.push(pair<treenode*, int>(root, root->val)); while (!st.empty()) { pair<treenode*, int> node = st.top(); st.pop(); // 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回true if (!node.first->left && !node.first->right && sum == node.second) 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; } };
💥 复杂度分析
- 时间复杂度:o(n);
- 空间复杂度:O(n);
加餐题
题目:路径总和Ⅱ
🔔 解题思路
方法一:回溯法,这题是要把路径拿出啦,那么回溯发就是很好的解决法子,我们采用res作为全局变量保存最后结果,用全局变量path保存当前节点的路径(空间少) / 或者将path作为变量传入(空间多)
下面给出两种代码
代码一:path作为变量
class Solution { public: vector<vector<int>> res; vector<vector<int>> pathSum(TreeNode* root, int targetSum) { finalSum(root, targetSum, {}); return res; } void finalSum(TreeNode* root, int targetSum, vector<int> path) { if (!root) return; if (!root->left && !root->right && targetSum == root->val) { path.emplace_back(root->val); res.emplace_back(path); //将答案路径加入 return; } path.emplace_back(root->val); //加上该路径再进入下一次递归 if (root->left) { finalSum(root->left, targetSum - root->val, path); } if (root->right) { finalSum(root->right, targetSum - root->val, path); } } };
代码二:path作为全局变量,空间更加优化!
class Solution { public: vector<vector<int>> res; vector<int> path; vector<vector<int>> pathSum(TreeNode* root, int targetSum) { backTracking(root, targetSum); return res; } //回溯找路径; void backTracking(TreeNode* root, int targetSum) { if (!root) return; if (!root->left && !root->right && targetSum == root->val) { path.emplace_back(root->val); res.emplace_back(path); path.pop_back();//回退 return; } path.emplace_back(root->val); //加上该路径 if (root->left) { backTracking(root->left, targetSum - root->val); } if (root->right) { backTracking(root->right, targetSum - root->val); } path.pop_back();//回退 } };
时间空间复杂度都和上一题一样;
相关文章推荐
- 面试题12. 矩阵中的路径
- 路径总和(二叉树)
- 路径总和III(python)
- LeetCode 112 路径总和 / LeetCode 113 路径总和II
- java基础12【File、路径、IO流、装饰者模式、字符流、字节流、转换流、系统流、打印流】
- 节点数值总和等于某个给定值的所有路径
- 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径
- 12 矩阵中的路径
- 学习ThinkPHP3.2.2:video12,更改模板路径替换规则
- leetcode面试题 04.12. 求和路径(dfs)
- 113. 路径总和 II
- 12 矩阵中的路径
- 【LeetCode】#112路径总和(Path Sum)
- leetcode 113. 路径总和 II
- leetcode 437路径总和III (深浅复制,hashmap(dic))
- Leetcode 题解 - 搜索--Backtracking(12):输出二叉树中所有从根到叶子的路径
- 【学习笔记】day2数据存储和界面展现第一天 11_api获取外部存储的真实路径 12_检查外部存储状态
- 路径总和
- 剑指Offer面试题12:矩阵中的路径
- 给定一个充满非负数的网格,找到从左上到右下的路径,最小化沿其路径的所有数字的总和。只能向下或向右移动。