LeetCode110:平衡二叉树
思路:递归。和上一题完全二叉树很像,递归判断左右子树是否为平衡二叉树。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
int ans = getBalanced(root);
return ans !=-1;
}
public int getBalanced(TreeNode root){ // 1.明确递归函数的参数和返回值
if(root == null){ // 2.明确终止条件
return 0;
}
// 3.明确单层递归逻辑
int left = getBalanced(root.left); // 得到左子树的高度
if(left == -1){ // 如果左子树已经不是平衡了 直接返回-1
return -1;
}
int right = getBalanced(root.right);// 得到右子树的高度
if(right == -1){ // 如果右子树不平衡了,直接返回-1
return -1;
}
return Math.abs(left-right)>1? -1: Math.max(left, right)+1; // 中 如果发现当前节点的左子树和右子树的高度差大于1 则返回-1。标记这一节点下面的子树已经不平衡了。
// 否则就是返回当前父节点的高度(记得+1)
}
}
/**
* 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 isBalanced(TreeNode* root) {
if(getBalanced(root) != -1){
return true;
}
else{
return false;
}
}
int getBalanced(TreeNode* node){
if(node == NULL) return 0;
int left = getBalanced(node->left);
if(left == -1) return -1; .// 注意这里要先一步判断,如果左子树已经存在-1的情况要将-1传上去的 不要忘了。
int right = getBalanced(node->right);
if(right == -1) return -1;
if(abs(left - right) > 1){
return -1;
}
else{
return 1 + max(left, right);
}
}
};
LeetCode257:二叉树的所有路径
思路:这种找到所有子集合的问题,都用可以考虑回溯来做。与递归的区别是在递归处理之后多了一步回退的操作。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
// 回溯
// 做回溯练习题的的时候可以debug来验证流程
// 在一旁画一个栈。模拟整个过程
List<String> ans = new ArrayList<>(); // 用来存放最后的结果String
if(root == null){
return ans;
}
List<Integer> path = new ArrayList<>(); // 用来存放回溯之前找到的结果,也就是每个路径。
traversal(root, path, ans);
return ans;
}
public void traversal(TreeNode node, List<Integer> path, List<String> ans){
path.add(node.val); // 要在一开始就加上,不然后下面的for判断的时候是依据这个节点的叶子节点,进去了之后就直接返回最后结果就会丢弃这个node了。
if(node.left == null && node.right == null){ // 到了叶子节点
StringBuilder sb = new StringBuilder();
for(int i=0;i<path.size()-1;i++){ // 因为拼接 最后一个单独处理
sb.append(path.get(i)).append("->");
}
sb.append(path.get(path.size() - 1));
ans.add(sb.toString()); // 将这一段从根节点到叶子节点的所有节点收录
}
if(node.left != null){ // 左侧没有到叶子节点,继续往下找
traversal(node.left, path, ans); // 运行到最后肯定会找到路径的
path.remove(path.size() - 1); // 将当前找到的最后一个删掉,依次类推,从后往前删。去找右侧的路劲
}
if(node.right != null){
traversal(node.right, path, ans);
path.remove(path.size() - 1);
}
}
}
/**
* 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 {
private:
void traversal(TreeNode* node, vector<int> & path, vector<string>& ans){
path.push_back(node->val); // 这个path 只又来暂存路劲的数值元素,后面再加上-> 并且变成字符串
if(node->left == NULL && node->right == NULL){
// 如果当前node的左右子节点为NULL 表示到达了需要处理的路径要添加到ans里面去了
string strPath;
int size = path.size() - 1; // 这是因为最后一个数值放在外面处理,在这里处理的话还要加一步判断吧,最后一个-> 删除掉;也可以理解为只要加size个->
for(int i=0;i<size;i++){
strPath += to_string(path[i]); // 注意要to_string转换成String类型
strPath += "->";
}
strPath += to_string(path[size]); // 加上最后一个节点值
ans.push_back(strPath);
}
if(node->left){
traversal(node->left, path, ans);
path.pop_back();
}
if(node->right){
traversal(node->right, path, ans);
path.pop_back();
}
}
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<int> path;
vector<string> ans;
if(root == NULL) return ans;
traversal(root, path, ans);
return ans;
}
};
LeetCode404:左叶子结点之和
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
// 后序遍历一层一层的向上返回左右子树的左叶子结果
if(root == null){
return 0;
}
int left = sumOfLeftLeaves(root.left); // 左:得到左子树的左叶子结点
int right = sumOfLeftLeaves(root.right);// 右:得到右子树的左叶子结点
int temp = 0;
if(root.left != null && root.left.left == null && root.left.right == null){
temp = root.left.val;
}
return temp + left + right; // 中:左右求和
}
}
/**
* 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 {
private:
int getLeftSum(TreeNode* node){
if(node == NULL){
return 0;
}
int left = getLeftSum(node->left);
// 要处理哪一部分 就在哪一部分后面加一个逻辑处理的部分
// 通过通过停止的逻辑 是无法知道当前是不是左子节点的,
// 只有通过父节点再来放下找,再能判断是不是左子节点
if(node->left != NULL && node->left->left == NULL && node->left->right == NULL){
left = node->left->val;
}
int right = getLeftSum(node->right);
return left+right;
}
public:
int sumOfLeftLeaves(TreeNode* root) {
int ans = 0;
if(root == NULL) return ans;
ans = getLeftSum(root);
return ans;
}
};
迭代法
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
// 用栈来实现一遍
Stack<TreeNode> stack = new Stack<>();
if(root == null){
return 0;
}
stack.push(root);
int ans = 0;
while(!stack.isEmpty()){
TreeNode node = stack.pop();
if(node.left != null && node.left.left ==null&& node.left.right == null){// 只能在叶子节点的上一位来判断,不然进入到叶子节点之后无法判断是左叶子还有右叶子
ans += node.left.val;
}
if(node.left != null){ // 这里先push left还是right 不影响。因为他们做叶子节点的相对位置是不变的。
stack.push(node.left);
}
if(node.right != null){
stack.push(node.right);
}
}
return ans;
}
}