LeetCode 513 找树左下角的值
题目链接:513
递归
思路:找左下角值,即找深度最大叶子节点中最左边的值。因此,可采用中左右顺序遍历,当遍历到叶子节点时,比较深度是否大于记录的最大深度,若大于则记录新的值与新的最大深度。由于顺序为左右,因此在同一深度上,一定是左边的节点值先记录,这样右边的节点值深度一样就不会被记录了。
代码:
/**
* 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 max_depth_;
int bottom_left_val_;
void find(TreeNode* cur, int depth) {
++depth;
if (!cur->left && !cur->right) {
if (depth > max_depth_) {
bottom_left_val_ = cur->val;
max_depth_ = depth;
}
return;
}
if (cur->left) find(cur->left, depth);
if (cur->right) find(cur->right, depth);
}
int findBottomLeftValue(TreeNode* root) {
find(root, 0);
return bottom_left_val_;
}
};
迭代
思路:只需用层序遍历,记录每层的第一个节点即可
代码:
/**
* 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 findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
int result;
if (root) que.push(root);
while (!que.empty()) {
int size = que.size();
for (int i=0; i<size; ++i) {
TreeNode* cur = que.front();
que.pop();
if (i==0) result = cur->val;
if (cur->left) que.push(cur->left);
if (cur->right) que.push(cur->right);
}
}
return result;
}
};
LeetCode 112 路径总和
题目链接:112
递归
思路:递归至叶子节点,判断和是否相等,若相等则返回true。在单层递归中,向左右子树递归,判断左右子树中是否存在符合要求的叶子节点。
代码:
/**
* 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 recurse(TreeNode* cur, int sum, int targetSum) {
sum += cur->val;
if (!cur->left && !cur->right) {
if (sum == targetSum) return true;
return false;
}
if (cur->left && recurse(cur->left, sum, targetSum)) return true;
if (cur->right && recurse(cur->right, sum, targetSum)) return true;
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if (!root) return false;
return recurse(root, 0, 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:
bool hasPathSum(TreeNode* root, int targetSum) {
if (!root) return false;
if (!root->left && !root->right) {
if (targetSum == root->val) return true;
return false;
}
return hasPathSum(root->left, targetSum-root->val) || (root->right && hasPathSum(root->right, targetSum-root->val));
}
};
迭代
思路:维护两个栈,一个存节点,一个存路径和,对于叶子节点判断和是否相等。
代码:
/**
* 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) {
stack<TreeNode*> node_stack;
stack<int> sum_stack;
if (root) {
node_stack.push(root);
sum_stack.push(root->val);
}
while(!node_stack.empty()) {
TreeNode* cur = node_stack.top();
int sum = sum_stack.top();
node_stack.pop();
sum_stack.pop();
if (!cur->left && !cur->right && sum==targetSum) return true;
if (cur->left) {
node_stack.push(cur->left);
sum_stack.push(sum+cur->left->val);
}
if (cur->right) {
node_stack.push(cur->right);
sum_stack.push(sum+cur->right->val);
}
}
return false;
}
};
LeetCode 113 路径总和ii
题目链接:113
递归
思路:与112类似,在单层递归中,向左右子树递归至叶子节点。由于需将所有符合要求的路径保存至结果中,所以不能通过返回值提前返回。注意路径的回溯。
代码:
/**
* 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:
void recurse(TreeNode* cur, int count, vector<int>& path, vector<vector<int>>& paths) {
path.push_back(cur->val);
if (!cur->left && !cur->right) {
if (count == cur->val) paths.push_back(path);
return;
}
if (cur->left) {
recurse(cur->left, count-cur->val, path, paths);
path.pop_back();
}
if (cur->right) {
recurse(cur->right, count-cur->val, path, paths);
path.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<vector<int>> result;
vector<int> path;
if (!root) return result;
recurse(root, targetSum, path, result);
return result;
}
};
迭代
思路:维护两个栈,一个存节点和值的pair,一个存路径,对于叶子节点判断和是否相等。
代码:
/**
* 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>> pathSum(TreeNode* root, int targetSum) {
stack<pair<TreeNode*, int>> node_stack;
stack<vector<int>> path_stack;
vector<vector<int>> result;
int sum = 0;
if (root) {
node_stack.push(make_pair(root, root->val));
vector<int> path;
path.push_back(root->val);
path_stack.push(path);
};
while(!node_stack.empty()) {
auto cur = node_stack.top();
node_stack.pop();
auto cur_path = path_stack.top();
path_stack.pop();
if (!cur.first->left && !cur.first->right && cur.second==targetSum) result.push_back(cur_path);
if (cur.first->right) {
node_stack.push(make_pair(cur.first->right, cur.second+cur.first->right->val));
cur_path.push_back(cur.first->right->val);
path_stack.push(cur_path);
cur_path.pop_back();
}
if (cur.first->left) {
node_stack.push(make_pair(cur.first->left, cur.second+cur.first->left->val));
cur_path.push_back(cur.first->left->val);
path_stack.push(cur_path);
cur_path.pop_back();
}
}
return result;
}
};
LeetCode 106 从中序与后序遍历序列构造二叉树
题目链接:106
思路:中序为左中右,后序为左右中,因此后序的最后一个元素即为根节点,通过该根节点去分割中序,得到左子树的中序和右子树的中序,通过左子树中序的size分割后序,得到左右子树的后序,然后分别递归进一步分割左右子树。
代码:
/**
* 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:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (postorder.size() == 0) return NULL;
int mid_val = postorder[postorder.size()-1];
TreeNode* root = new TreeNode(mid_val);
vector<int>::iterator it = inorder.begin();
for (it; it!=inorder.end(); ++it) {
if (*it == mid_val) break;
}
vector<int> left_inorder(inorder.begin(), it);
vector<int> right_inorder(it+1, inorder.end());
it = postorder.begin() + left_inorder.size();
vector<int> left_postorder(postorder.begin(), it);
vector<int> right_postorder(it, postorder.end()-1);
root->left = buildTree(left_inorder, left_postorder);
root->right = buildTree(right_inorder, right_postorder);
return root;
}
};
LeetCode 105 从前序与中序遍历序列构造二叉树
题目链接:105
思路:与106类似,通过前序分割中序,再反过来分割前序。由于递归中不断构造新数组影响效率,此处采用传入索引的方式。
代码:
/**
* 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:
TreeNode* recurse(vector<int>& preorder, int prebegin, int preend, vector<int>& inorder, int inbegin, int inend) {
if ((preend - prebegin) == 0) return NULL;
int mid_val = preorder[prebegin];
TreeNode* root = new TreeNode(mid_val);
int mid_index_in;
for (int i=inbegin; i<inend; ++i) {
if (mid_val == inorder[i]) mid_index_in = i;
}
int left_inbegin = inbegin;
int left_inend = mid_index_in;
int right_inbegin = mid_index_in+1;
int right_inend = inend;
int left_prebegin = prebegin+1;
int left_preend = left_prebegin + (left_inend - left_inbegin);
int right_prebegin = left_preend;
int right_preend = preend;
root->left = recurse(preorder, left_prebegin, left_preend, inorder, left_inbegin, left_inend);
root->right = recurse(preorder, right_prebegin, right_preend, inorder, right_inbegin, right_inend);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return recurse(preorder, 0, preorder.size(), inorder, 0, inorder.size());
}
};