404.左叶子之和
计算给定二叉树的所有左叶子之和。
示例:
一开始,我把左叶子误认为是左孩子,结果程序写出来发现不对
首先,学会叶子的定义,叶子不能看孩子,只能看父系节点,当父节点的左子树和右子树都为空是时,这个父节点就可以认为是叶子节点。
root->left!=nullptr&&root->left->left== nullptr&&root->left->right==nullptr
代码如下:
#include <iostream>
#include<vector>
#include<cmath>
#include<string>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}
};
//使用数组初始化二叉树
TreeNode* buildTree(vector<int>& nums) {
int n = nums.size();
if (n < 1) return nullptr;
vector<TreeNode*> nodes(n); // 用vector存储所有节点
// 初始化所有节点
for (int i = 0; i < n; i++) {
if (nums[i] != NULL) {
nodes[i] = new TreeNode(nums[i]);
}
}
// 为每个节点指定左右子节点的位置
int leftIndex = 1;
int rightIndex = 2;
for (int i = 0; i < n; i++) {
if (nodes[i] == nullptr) continue;
if (leftIndex < n && nodes[leftIndex] != nullptr) {
nodes[i]->left = nodes[leftIndex];
}
if (rightIndex < n && nodes[rightIndex] != nullptr) {
nodes[i]->right = nodes[rightIndex];
}
leftIndex += 2;
rightIndex += 2;
//cout << nodes[i]->val<<" 我爱我";
}
return nodes[0]; // 返回根节点指针
}
class Solution {
public:
//遍历左叶子之和
int sum; //定义左叶子值的和
int LeftNodeSum(TreeNode* root) {
if (root == nullptr)return 0;
if (root->left!=nullptr&&root->left->left== nullptr&&root->left->right==nullptr) { //当爷爷节点的左孙子和右孙子均为空的时候,这代表这个节点是叶子
sum += root->left->val; //这个时候直接计算父亲节点的左孩子即可
}
LeftNodeSum(root->left);
LeftNodeSum(root->right);
return sum;
}
//前序遍历
void MLF(TreeNode* cur, vector<int>& vec) {
if (cur != nullptr) vec.push_back(cur->val);
MLF(cur->left, vec);
MLF(cur->right, vec);
}
vector<int>result;
vector<int>MLFfunction(TreeNode*&root) {
MLF(root,result);
return result;
}
};
int main()
{
Solution s;
vector<int>num = { 1,2,3,4,5,6,7,8,9,11,12,13};
TreeNode* root = buildTree(num);
int t = s.LeftNodeSum(root);
cout << t<<endl;
return 0;
}
257. 二叉树的所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
这个题目牵扯到了回溯算法,即每次遍历到叶子节点之后,都要返回根节点,重新开辟一条路径,达到叶子节点,所以用栈来储存元素。
代码如下:
// 二叉树的路径.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<cmath>
#include<vector>
#include<string>
using namespace std;
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int val) :val(val), left(nullptr), right(nullptr) {}//
//TreeNode(int val) :val(val){}//没有初始化指针
};
//使用数组初始化二叉树
TreeNode* buildTree(vector<int>& nums) {
int n = nums.size();
if (n < 1) return nullptr;
vector<TreeNode*> nodes(n); // 用vector存储所有节点
// 初始化所有节点
for (int i = 0; i < n; i++) {
if (nums[i] != NULL) {
nodes[i] = new TreeNode(nums[i]);
}
}
// 为每个节点指定左右子节点的位置
int leftIndex = 1;
int rightIndex = 2;
for (int i = 0; i < n; i++) {
if (nodes[i] == nullptr) continue;
if (leftIndex < n && nodes[leftIndex] != nullptr) {
nodes[i]->left = nodes[leftIndex];
}
if (rightIndex < n && nodes[rightIndex] != nullptr) {
nodes[i]->right = nodes[rightIndex];
}
leftIndex += 2;
rightIndex += 2;
//cout << nodes[i]->val<<" 我爱我";
}
return nodes[0]; // 返回根节点指针
}
class Soluiton {
public:
void traversal(TreeNode* node, vector<int>& path, vector<string>& result) {
path.push_back(node->val);
if (node->left == nullptr && node->right == nullptr) {
string sPath;
for (int i = 0; i < path.size(); i++) {
sPath+= to_string(path[i]);
sPath += "->";//"+="操作符可以连接两个字符串
}
result.push_back(sPath);
}
//
if (node->left != nullptr) {
traversal(node->left, path, result);
for (int i = 0; i < path.size() - 1; i++) {
path.pop_back(); //pop.back()为无参函数,作用为弹出栈顶元素
}
}
if (node->right != nullptr) {
traversal(node->right, path, result);
for (int i = 0; i < path.size() - 1; i++) {
path.pop_back(); //pop.back()为无参函数,作用为弹出栈顶元素
}
}
}
vector<string>GetPathofTree(TreeNode* tree) {
vector<string>s;
vector<int>num;
traversal(tree, num, s);
return s;
}
};
int main()
{
vector<string>numresult;
vector<int>num = { 1,2,3,4,5,6,7,8,9 };
Soluiton s;
TreeNode* root = buildTree(num);
numresult = s.GetPathofTree(root);
cout << "[";
for (auto t : numresult) {
cout << t << ",";
}
cout << "]";
return 0;
std::cout << "Hello World!\n";
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件