当前位置: 首页 > article >正文

力扣整理版七:二叉树(待更新)

满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。深度为k,有2^k-1个节点的二叉树。

完全二叉树:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。

二叉搜索树:左<根<右。

平衡二叉搜索树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

-----------------------------

(1) 144 二叉树的前序遍历

(2) 145 二叉树的后序遍历

(3) 94 二叉树的中序遍历

(4) 102 二叉树的层序遍历

(5) 107 二叉树的层序遍历2

(6) 199 二叉树的右视图

(7) 637 二叉树的层平均值

(8) 429 N叉树的层序遍历

(9) 515 在每个树行中找最大值

(10) 116 填充每个节点的下一个右侧节点指针

(11) 117 填充2(18) 404 左叶子之和

(12) 104 二叉树的最大深度

(13) 111 二叉树的最小深度

(14) 226 翻转二叉树

(15) 101 对称二叉树

(16) 222 完全二叉树的节点个数

(17) 257 二叉树的所有路径

(18) 404 左叶子之和

-----------------------------

一、二叉树的递归遍历

1、确定递归函数的参数和返回值;2、确定终止条件;3、确定单层递归的逻辑;

144. 二叉树的前序遍历 - 力扣(LeetCode)

1、前序遍历

 -------------  python  -------------

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        
        def dfs(node):
            if node is None:
                return
            
            res.append(node.val)
            dfs(node.left)
            dfs(node.right)
        dfs(root)
        return res

 -------------  c++  -------------

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        vec.push_back(cur->val);    // 中
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

2、中序遍历

94. 二叉树的中序遍历 - 力扣(LeetCode)

 -------------  python  -------------

# 中序遍历-递归-LC94_二叉树的中序遍历
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        
        def dfs(node):
            if node is None:
                return
            
            dfs(node.left)
            res.append(node.val)
            dfs(node.right)
        dfs(root)
        return res

 -------------  c++  -------------

void traversal(TreeNode* cur, vector<int>& vec) {
    if (cur == NULL) return;
    traversal(cur->left, vec);  // 左
    vec.push_back(cur->val);    // 中
    traversal(cur->right, vec); // 右
}

3、后序遍历

145. 二叉树的后序遍历 - 力扣(LeetCode)

-------------  python  -------------

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        
        def dfs(node):
            if node is None:
                return
            
            dfs(node.left)
            dfs(node.right)
            res.append(node.val)

        dfs(root)
        return res

-------------  c++  ------------- 

void traversal(TreeNode* cur, vector<int>& vec) {
    if (cur == NULL) return;
    traversal(cur->left, vec);  // 左
    traversal(cur->right, vec); // 右
    vec.push_back(cur->val);    // 中
}

二、二叉树的迭代遍历

1、前序遍历

144. 二叉树的前序遍历 - 力扣(LeetCode)

-------------  python  -------------

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        stack=[]
        res=[]
        while stack or root:
            if root:
                res.append(root.val)
                stack.append(root)
                root=root.left
            else:
                tem=stack.pop()
                root=tem.right
        return res

-------------  c++  ------------- 

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        if(root==nullptr) return {};
        stack<TreeNode*> stk;
        vector<int> res;
        while(!stk.empty() || root){     //stack不可以转换成bool类型
            if (root){
                res.push_back(root->val);
                stk.push(root);
                root=root->left;
            }
            else{
                TreeNode* tem=stk.top();
                stk.pop();
                root=tem->right;
            }
        }
        return res;
    }
};

2、中序遍历 

94. 二叉树的中序遍历 - 力扣(LeetCode)

-------------  python  -------------

class Solution(object):
	def inorderTraversal(self, root):
		"""
		:type root: TreeNode
		:rtype: List[int]
		"""
		# res = []
		# def dfs(root):
		# 	if not root:
		# 		return
		# 	# 按照 左-打印-右的方式遍历	
		# 	dfs(root.left)
		# 	res.append(root.val)
		# 	dfs(root.right)
		# dfs(root)
		# return res
        # 上面是递归
		res = []
		stack = []
		while stack or root:
			# 不断往左子树方向走,每走一次就将当前节点保存到栈中
			# 这是模拟递归的调用
			if root:
				stack.append(root)
				root = root.left
			# 当前节点为空,说明左边走到头了,从栈中弹出节点并保存
			# 然后转向右边节点,继续上面整个过程
			else:
				tmp = stack.pop()
				res.append(tmp.val)
				root = tmp.right
		return res

-------------  c++  ------------- 

// 不可写成while(stack)  stack不能转化成bool类型,但是root如果是个指针可以
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int>res;
        stack<TreeNode*>stk;
        while(root!=nullptr || !stk.empty()){
            if(root!=nullptr){
                stk.push(root);
                root=root->left;
            }
            else{
                root=stk.top();
                stk.pop();
                res.push_back(root->val);
                root=root->right;
            }
        }
        return res;
    }
};

 3、后序遍历

145. 二叉树的后序遍历 - 力扣(LeetCode)

-------------  python  -------------

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        res=[]
        def dfs(root):
            if not root:
                return
            dfs(root.left)
            dfs(root.right)
            res.append(root.val)
        dfs(root)
        return res

-------------  c++  ------------- 

class Solution {
public:
    vector<int> res;

    void dfs(TreeNode* root){
        if(root==nullptr) return;
        dfs(root->left);
        dfs(root->right);
        res.push_back(root->val);
    }

    vector<int> postorderTraversal(TreeNode* root) {
        if(root==nullptr) return {};
        dfs(root);
        return res;
    }
};

三、二叉树的层序遍历

1、102 二叉树的层序遍历

102. 二叉树的层序遍历 - 力扣(LeetCode)

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

-------------  python  -------------

# 利用长度法
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        queue = collections.deque([root])
        result = []
        while queue:
            level = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            result.append(level)
        return result
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []

        levels = []

        def traverse(node, level):
            if not node:
                return

            if len(levels) == level:
                levels.append([])

            levels[level].append(node.val)
            traverse(node.left, level + 1)
            traverse(node.right, level + 1)

        traverse(root, 0)
        return levels

-------------  c++  -------------  

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<vector<int>> result;
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            result.push_back(vec);
        }
        return result;
    }
};
# 递归法
class Solution {
public:
    void order(TreeNode* cur, vector<vector<int>>& result, int depth)
    {
        if (cur == nullptr) return;
        if (result.size() == depth) result.push_back(vector<int>());
        result[depth].push_back(cur->val);
        order(cur->left, result, depth + 1);
        order(cur->right, result, depth + 1);
    }
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> result;
        int depth = 0;
        order(root, result, depth);
        return result;
    }
};

2、107 二叉树的层序遍历2

107. 二叉树的层序遍历 II - 力扣(LeetCode)

题目描述:给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

Tips:相对于上一题,把result数组反转。

-------------  python  -------------

class Solution:
    """二叉树层序遍历II迭代解法"""

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        queue = collections.deque([root])
        result = []
        while queue:
            level = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            result.append(level)
        return result[::-1]

-------------  c++  -------------  

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<vector<int>> result;
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            result.push_back(vec);
        }
        reverse(result.begin(), result.end()); // 在这里反转一下数组即可
        return result;

    }
};

3、199 二叉树的右视图

199. 二叉树的右视图 - 力扣(LeetCode)

题目描述:给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

Tips:层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。

-------------  python  -------------

class Solution:
    def rightSideView(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        
        queue = collections.deque([root])
        right_view = []
        
        while queue:
            level_size = len(queue)
            
            for i in range(level_size):
                node = queue.popleft()
                
                if i == level_size - 1:
                    right_view.append(node.val)
                
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        
        return right_view

-------------  c++  -------------  

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<int> result;
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (i == (size - 1)) result.push_back(node->val); // 将每一层的最后元素放入result数组中
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return result;
    }
};

4、637 二叉树的层平均值

637. 二叉树的层平均值 - 力扣(LeetCode)

题目描述:给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。

-------------  python  -------------

class Solution:
    """二叉树层平均值迭代解法"""

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def averageOfLevels(self, root: TreeNode) -> List[float]:
        if not root:
            return []

        queue = collections.deque([root])
        averages = []
        
        while queue:
            size = len(queue)
            level_sum = 0
            
            for i in range(size):
                node = queue.popleft()
                
                
                level_sum += node.val
                    
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            
            averages.append(level_sum / size)
        
        return averages

-------------  c++  -------------  

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<double> result;
        while (!que.empty()) {
            int size = que.size();
            double sum = 0; // 统计每一层的和
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                sum += node->val;
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            result.push_back(sum / size); // 将每一层均值放进结果集
        }
        return result;
    }
};

5、429 N叉树的层序遍历

429. N 叉树的层序遍历 - 力扣(LeetCode)

题目描述:给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。

-------------  python  -------------

lass Solution:
    def levelOrder(self, root: 'Node') -> List[List[int]]:
        if not root:
            return []

        result = []
        queue = collections.deque([root])

        while queue:
            level_size = len(queue)
            level = []

            for _ in range(level_size):
                node = queue.popleft()
                level.append(node.val)

                for child in node.children:
                    queue.append(child)

            result.append(level)

        return result

-------------  c++  -------------  

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        queue<Node*> que;
        if (root != NULL) que.push(root);
        vector<vector<int>> result;
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            for (int i = 0; i < size; i++) {
                Node* node = que.front();
                que.pop();
                vec.push_back(node->val);
                for (int i = 0; i < node->children.size(); i++) { // 将节点孩子加入队列
                    if (node->children[i]) que.push(node->children[i]);
                }
            }
            result.push_back(vec);
        }
        return result;

    }
};

6、515 在每个树行中找最大值

515. 在每个树行中找最大值 - 力扣(LeetCode)

题目描述:在二叉树的每一行中找到最大的值。

-------------  python  -------------

class Solution:
    def largestValues(self, root: TreeNode) -> List[int]:
        if not root:
            return []

        result = []
        queue = collections.deque([root])

        while queue:
            level_size = len(queue)
            max_val = float('-inf')

            for _ in range(level_size):
                node = queue.popleft()
                max_val = max(max_val, node.val)

                if node.left:
                    queue.append(node.left)

                if node.right:
                    queue.append(node.right)

            result.append(max_val)

        return result

-------------  c++  -------------  

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<int> result;
        while (!que.empty()) {
            int size = que.size();
            int maxValue = INT_MIN; // 取每一层的最大值
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                maxValue = node->val > maxValue ? node->val : maxValue;
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            result.push_back(maxValue); // 把最大值放进数组
        }
        return result;
    }
};

7、116 填充每个节点的下一个右侧节点指针

116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode)

题目描述:给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。

-------------  python  -------------

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        
        queue = collections.deque([root])
        
        while queue:
            level_size = len(queue)
            prev = None
            
            for i in range(level_size):
                node = queue.popleft()
                
                if prev:
                    prev.next = node
                
                prev = node
                
                if node.left:
                    queue.append(node.left)
                
                if node.right:
                    queue.append(node.right)
        
        return root

-------------  c++  -------------  

class Solution {
public:
    Node* connect(Node* root) {
        queue<Node*> que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            // vector<int> vec;
            Node* nodePre;
            Node* node;
            for (int i = 0; i < size; i++) {
                if (i == 0) {
                    nodePre = que.front(); // 取出一层的头结点
                    que.pop();
                    node = nodePre;
                } else {
                    node = que.front();
                    que.pop();
                    nodePre->next = node; // 本层前一个节点next指向本节点
                    nodePre = nodePre->next;
                }
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            nodePre->next = NULL; // 本层最后一个节点指向NULL
        }
        return root;

    }
};

8、117 填充2

117. 填充每个节点的下一个右侧节点指针 II - 力扣(LeetCode)

题目描述:填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

-------------  python  -------------

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        
        queue = collections.deque([root])
        
        while queue:
            level_size = len(queue)
            prev = None
            
            for i in range(level_size):
                node = queue.popleft()
                
                if prev:
                    prev.next = node
                
                prev = node
                
                if node.left:
                    queue.append(node.left)
                
                if node.right:
                    queue.append(node.right)
        
        return root

-------------  c++  -------------  

class Solution {
public:
    Node* connect(Node* root) {
        queue<Node*> que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            Node* nodePre;
            Node* node;
            for (int i = 0; i < size; i++) {
                if (i == 0) {
                    nodePre = que.front(); // 取出一层的头结点
                    que.pop();
                    node = nodePre;
                } else {
                    node = que.front();
                    que.pop();
                    nodePre->next = node; // 本层前一个节点next指向本节点
                    nodePre = nodePre->next;
                }
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            nodePre->next = NULL; // 本层最后一个节点指向NULL
        }
        return root;
    }
};

9、104 二叉树的最大深度

104. 二叉树的最大深度 - 力扣(LeetCode)

题目描述:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。

Tips:使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。在二叉树中,一层一层的来遍历二叉树,记录一下遍历的层数就是二叉树的深度。

-------------  python  -------------

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        
        depth = 0
        queue = collections.deque([root])
        
        while queue:
            depth += 1
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        
        return depth

-------------  c++  -------------  

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root == NULL) return 0;
        int depth = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()) {
            int size = que.size();
            depth++; // 记录深度
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return depth;
    }
};

10、111 二叉树的最小深度

111. 二叉树的最小深度 - 力扣(LeetCode)

题目描述:给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

-------------  python  -------------

class Solution:
    def minDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        depth = 0
        queue = collections.deque([root])
        
        while queue:
            depth += 1 
            for _ in range(len(queue)):
                node = queue.popleft()
                
                if not node.left and not node.right:
                    return depth
            
                if node.left:
                    queue.append(node.left)
                    
                if node.right:
                    queue.append(node.right)

        return depth

-------------  c++  -------------  

class Solution {
public:
    int minDepth(TreeNode* root) {
        if (root == NULL) return 0;
        int depth = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()) {
            int size = que.size();
            depth++; // 记录最小深度
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
                if (!node->left && !node->right) { // 当左右孩子都为空的时候,说明是最低点的一层了,退出
                    return depth;
                }
            }
        }
        return depth;
    }
};

四、226 翻转二叉树

226. 翻转二叉树 - 力扣(LeetCode)

题目描述:翻转这棵二叉树,并返回其根节点。

递归:1、确定参数和返回;2、确定终止条件;3、单层递归的逻辑

-------------  python  -------------

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root:
            return None
        left=self.invertTree(root.left)
        right=self.invertTree(root.right)
        root.left,root.right=right,left
        return root

-------------  c++  -------------  

root->left,root->right=right,left;

C++ 不支持这种逗号表达式的赋值方式。

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root==nullptr) return nullptr;
        TreeNode*left=invertTree(root->left);
        TreeNode*right=invertTree(root->right);
        root->left=right;
        root->right=left;
        return root;
    }
};

--------------------------------

辅助栈迭代法:代码随想录

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root:
            return None
        stack=[root]
        while stack:
            node=stack.pop()
            if node.left:stack.append(node.left)
            if node.right:stack.append(node.right)
            node.left,node.right=node.right,node.left
        return root

stack 不支持直接使用花括号进行初始化。正确的方法是先创建一个空栈,然后使用 push 方法添加元素,或者使用 std::vector 来初始化。

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root==nullptr) return nullptr;
        stack<TreeNode*>stk;
        stk.push(root);
        while(!stk.empty()){
            TreeNode*node=stk.top();
            stk.pop();
            if(node->left) stk.push(node->left);
            if(node->right) stk.push(node->right);
            TreeNode*tem=node->left;
            node->left=node->right;
            node->right=tem;
        }
        return root;
    }
};

五、101 对称二叉树

101. 对称二叉树 - 力扣(LeetCode)

题目描述:给定一个二叉树,检查它是否是镜像对称的。

Tips:后序遍历  正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

递归法:

-------------  python  -------------

注意检查not root (不然无法实现root.left)

我把递归的函数写成成员函数了

class Solution:
    def dfs(self,left,right):
        if left is None and right is None:
            return True
        if not left or not right:
            return False
        if left.val!=right.val:
            return False
        return self.dfs(left.left,right.right) and self.dfs(left.right,right.left)
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        return self.dfs(root.left,root.right)

-------------  c++  -------------  

class Solution {
public:
    bool dfs(TreeNode*p,TreeNode*q){
        if(p==nullptr && q==nullptr) return true;  //只有一条语句可以省略大括号
        if(p==nullptr || q==nullptr) return false;
        if(p->val !=q->val) return false;
        return dfs(p->left,q->right) && dfs(p->right,q->left);
    }
    bool isSymmetric(TreeNode* root) {
        if(root==nullptr){
            return true;
        }
        return dfs(root->left,root->right);
    }
};

 和94/100的递归比较:相同的树没有使用辅助函数,没必要使用辅助函数可能是由于1、输入参数相同;2、没有其他的需要保留数据的变量如res=[ ]

迭代法:

-------------  python  -------------

class Solution(object):
	def isSymmetric(self, root):
		"""
		:type root: TreeNode
		:rtype: bool
		"""
		if not root or not (root.left or root.right):
			return True
		# 用队列保存节点	
		queue = [root.left,root.right]
		while queue:
			# 从队列中取出两个节点,再比较这两个节点
			left = queue.pop(0)
			right = queue.pop(0)
			# 如果两个节点都为空就继续循环,两者有一个为空就返回false
			if not (left or right):
				continue
			if not (left and right):
				return False
			if left.val!=right.val:
				return False
			# 将左节点的左孩子, 右节点的右孩子放入队列
			queue.append(left.left)
			queue.append(right.right)
			# 将左节点的右孩子,右节点的左孩子放入队列
			queue.append(left.right)
			queue.append(right.left)
		return True

-------------  c++  -------------   

//用vector实现
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
       if(root==nullptr || (root->left==nullptr && root->right==nullptr )) return true;
       vector<TreeNode*> v;
       v.push_back(root->left);
       v.push_back(root->right);
       while(!v.empty()){
            TreeNode*left=v[0];v.erase(v.begin());
            TreeNode*right=v[0];v.erase(v.begin());
            //如果是v.begin()那么就需要*left->val
            if(left==nullptr and right==nullptr) continue;
            if(left==nullptr or right==nullptr) return false;
            if(left->val != right->val) return false;
            v.push_back(left->left);
            v.push_back(right->right);
            v.push_back(right->left);
            v.push_back(left->right);
       }
       return true;
    }
};
//用queue实现
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
       if (root==nullptr) return true;
       queue<TreeNode*>q;
       q.push(root->left);
       q.push(root->right);
       while(!q.empty()){
            TreeNode*l=q.front(); q.pop();
            TreeNode*r=q.front(); q.pop();
            if(l==nullptr && r==nullptr) continue;
            if(l==nullptr || r==nullptr) return false;
            if(l->val != r->val) return false;
            q.push(l->left);
            q.push(r->right);
            q.push(l->right);
            q.push(r->left);
       }
       return true;
    }
};

六、222 完全二叉树的节点个数

222. 完全二叉树的节点个数 - 力扣(LeetCode)

很容易的递归但是没有利用完全二叉树的特点:

class Solution(object):
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        return self.countNodes(root.left)+self.countNodes(root.right)+1

完全二叉树的定义:它是一棵空树或者它的叶子节点只出在最后两层,若最后一层不满则叶子节点只在最左侧。

-------------  python  -------------

class Solution(object):
    def countNodes(self, root):
        #二叉树的层数
        def countlevel(root):
            if not root:
                return 0
            return max(countlevel(root.left),countlevel(root.right))+1
        if not root:
            return 0
        left=countlevel(root.left)
        right=countlevel(root.right)
        if left==right:
            return (1<<left)+self.countNodes(root.right)
        else:
            return (1<<right)+self.countNodes(root.left)

1<<left 是在计算pow(2,left) <<按位左移

-------------  c++  -------------   

class Solution {
public:
    int countlevel(TreeNode* root){
        if (root==nullptr) return 0;
        return max(countlevel(root->left),countlevel(root->right))+1;
    }
    int countNodes(TreeNode* root) {
        if (root==nullptr) return 0;
        int l=countlevel(root->left);
        int r=countlevel(root->right);
        if (l==r) return (1<<l)+countNodes(root->right);
        else return(1<<r)+countNodes(root->left);
    }
};

七、257 二叉树的所有路径

257. 二叉树的所有路径 - 力扣(LeetCode)

1、递归

深度优先搜索

  • 如果当前节点不是叶子节点,则在当前的路径末尾添加该节点,并继续递归遍历该节点的每一个孩子节点。
  • 如果当前节点是叶子节点,则在当前路径末尾添加该节点后我们就得到了一条从根节点到叶子节点的路径,将该路径加入到答案即可

-------------  python  -------------

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        def con_path(root,path):
            if root:
                path+=str(root.val)
                if not root.left and not root.right: #当前节点是叶子节点
                    paths.append(path) #把路径加入到答案中
                else:
                    path+='->' # 当前节点不是叶子节点,继续递归遍历
                    con_path(root.left,path)
                    con_path(root.right,path)
        paths=[]
        con_path(root,'')
        return paths

-------------  c++  -------------   

class Solution {
public:
    void construct_paths(TreeNode* root, string path, vector<string>& paths) {
        if (root != nullptr) {
            path += to_string(root->val);
            if (root->left == nullptr && root->right == nullptr) {  // 当前节点是叶子节点
                paths.push_back(path);                              // 把路径加入到答案中
            } else {
                path += "->";  // 当前节点不是叶子节点,继续递归遍历
                construct_paths(root->left, path, paths);
                construct_paths(root->right, path, paths);
            }
        }
    }

    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> paths;
        construct_paths(root, "", paths);
        return paths;
    }
};

时间复杂度和空间复杂度都是O(N方)

2、迭代

广度优先搜索

-------------  python  -------------

代码中使用 [] 的目的是为了初始化 deque 时提供一个初始元素。

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        paths=list()
        if not root:
            return paths
        node_queue=collections.deque([root])
        path_queue = collections.deque([str(root.val)])
        while node_queue:
            node = node_queue.popleft()
            path = path_queue.popleft()
            if not node.left and not node.right:
                paths.append(path)
            else:
                if node.left:
                    node_queue.append(node.left)
                    path_queue.append(path+'->'+str(node.left.val))

                if node.right:
                    node_queue.append(node.right)
                    path_queue.append(path + '->' + str(node.right.val))
        return paths

-------------  c++  -------------   

class Solution {
public:
    vector<string> paths;
    vector<string> binaryTreePaths(TreeNode* root) {
        if(root==nullptr)return {};
        deque<TreeNode*>nodes {root};
        deque<string>path {to_string(root->val)};
        while(!nodes.empty()){
            TreeNode* node=nodes.front();
            nodes.pop_front();
            string pa=path.front();
            path.pop_front();
            if(node->left==nullptr && node->right==nullptr){
                paths.push_back(pa);
            }
            else {
                if(node->left){
                    nodes.push_back(node->left);
                    path.push_back(pa+"->"+to_string(node->left->val));
                }
                if(node->right){
                    nodes.push_back(node->right);
                    path.push_back(pa+"->"+to_string(node->right->val));
                }
            }
        }
        return paths;
    }
};

八、404 左叶子之和

404. 左叶子之和 - 力扣(LeetCode)

题目描述:计算给定二叉树的所有左叶子之和。递归法,迭代法。代码随想录

-------------  python  -------------

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumOfLeftLeaves(self, root):
        if root is None:
            return 0
        if root.left is None and root.right is None:
            return 0
        
        leftValue = self.sumOfLeftLeaves(root.left)  # 左
        if root.left and not root.left.left and not root.left.right:  # 左子树是左叶子的情况
            leftValue = root.left.val
            
        rightValue = self.sumOfLeftLeaves(root.right)  # 右

        sum_val = leftValue + rightValue  # 中
        return sum_val

递归精简版。 

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumOfLeftLeaves(self, root):
        if root is None:
            return 0
        leftValue = 0
        if root.left is not None and root.left.left is None and root.left.right is None:
            leftValue = root.left.val
        return leftValue + self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right)
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumOfLeftLeaves(self, root):
        if root is None:
            return 0
        st = [root]
        result = 0
        while st:
            node = st.pop()
            if node.left and node.left.left is None and node.left.right is None:
                result += node.left.val
            if node.right:
                st.append(node.right)
            if node.left:
                st.append(node.left)
        return result

-------------  c++  -------------   

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if (root == NULL) return 0;
        int leftValue = 0;
        if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
            leftValue = root->left->val;
        }
        return leftValue + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
    }
};
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        stack<TreeNode*> st;
        if (root == NULL) return 0;
        st.push(root);
        int result = 0;
        while (!st.empty()) {
            TreeNode* node = st.top();
            st.pop();
            if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
                result += node->left->val;
            }
            if (node->right) st.push(node->right);
            if (node->left) st.push(node->left);
        }
        return result;
    }
};


http://www.kler.cn/a/399478.html

相关文章:

  • Java基础-Java中的常用类(上)
  • 【Go】-bufio库解读
  • 基于大语言模型意图识别和实体提取功能;具体ZK数值例子:加密货币交易验证;
  • 《AI 之影》
  • 【学习】HTTP
  • 【珠海科技学院主办,暨南大学协办 | IEEE出版 | EI检索稳定 】2024年健康大数据与智能医疗国际会议(ICHIH 2024)
  • 小程序-基于java+SpringBoot+Vue的驾校预约平台设计与实现
  • windbg 关于L10比L9多更多行,和poi的含义
  • 【Linux---09】Crontab定时调度
  • 【C++】哈希表的实现详解
  • 如何在 WordPress 中轻松强制所有用户退出登录
  • Android Osmdroid + 天地图 (一)
  • Factory快速入门
  • 超详细:索引介绍(易懂!)
  • React--》如何高效管理前端环境变量:开发与生产环境配置详解
  • 阿里云MYSQL调优之慢查询
  • 刘艳兵-DBA036-Oracle数据库中的触发器(Trigger)可以在以下哪种情况下自动执行?
  • 策略模式、状态机详细解读
  • 力扣 LeetCode 94. 二叉树的中序遍历(Day6:二叉树)
  • 【SPIE出版,EI稳定检索】2024年信号处理与神经网络应用国际学术会议(SPNNA 2024,12月13-15日)
  • ES6进阶知识二
  • 2024山西省网络建设运维第十八届职业院校技能大赛解析答案(6. iscsi 服务)
  • pybullet简介及简单使用
  • lambda 表达式与mutable
  • 【Golang】——Gin 框架中的模板渲染详解
  • 省级金融发展水平数据(2000-2022年)