代码随想录算法训练营第十五天|层序遍历、226.翻转二叉树、101.对称二叉树

题目:102.二又树的层序遍历

文章链接:代码随想录

视频链接:LeetCode:102.二叉树的层序遍历

题目链接:力扣题目链接

详解:队列先进先出,符合层序遍历的广度优先遍历;栈先进后出使用于模拟深度优先遍历的递归遍历逻辑

解法1:

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;
            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;
    }
};

递归法:利用depth记录当前递归所在的层数,多少层数的递归,就放在第几行的vector中

// 递归方法 
void order(TreeNode* cur, vector<vector<int>>& result, int depth) {
    // 终止条件
	if (cur==NULL) return;
	// 如果结果集的大小等于深度,则创建一个vector容器,相当于给result多开了一层
	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;
}

题目:107.二叉树的层序遍历II

 文章链接:代码随想录

题目链接:力扣题目链接

解法1:

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;
    }
};

题目:199.二叉树的右视图

题目链接:力扣题目链接

解法1:

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);
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
          return result;
    }
};

题目:637.二叉树的层平均值

题目链接:力扣题目链接

解法1:

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(i == size-1){
                     double average = sum / size;
                     result.push_back(average);
                }
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return result;
    }
};

题目:429.N又树的层序遍历

题目链接:力扣题目链接

解法1:

class Node{
public:
       int val;
       vector<Node*> children; // 存放节点的数组
       // 构造函数
      
       Node(int _val) {
           val = _val;
       }

       Node(int _val, vector<Node*> _children) {
           val = _val;
           children = _children;
       }
};
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 j=0; j<node->children.size(); j++){
                    que.push(node->children[j]);
                }
            }
            result.push_back(vec);
        }
        return result;
    }
};

题目:515.在每个树行中找最大值

题目链接:力扣题目链接

解法1:

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 max = INT32_MIN; // 先定义一个int类型最小值
            for(int i=0; i<size; i++){
                TreeNode* node = que.front();
                que.pop();
                // if(max < node->val) max = node->val;
                // 三目运算符
                max = max > node->val ? max :node->val;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            result.push_back(max);
        }
        return result;
    }
};

题目:116.填充每个节点的下一个右侧节点指针

题目链接:力扣题目链接

解法1:

class Solution {
public:
    Node* connect(Node* root) {
        // 队列
        queue<Node*> que;
        if(root != NULL) que.push(root); 
        while(!que.empty()){
            int size = que.size();
            for(int i=0; i<size; i++){
                Node* node = que.front(); // [2,3]
                que.pop(); // [2]
                if(i == size-1) node->next =NULL;
                else{
                    node->next = que.front(); // 指向队列中的头元素
                }
                if(node->left) que.push(node->left);    // [3,4]
                if(node->right) que.push(node->right);  // [3,4,5]
            }
        }
        return root;
    }
};

题目:117.填充每个节点的下一个右侧节点指针Il

题目链接:力扣题目链接

解法1:

        // 队列
        queue<Node*> que;
        if(root != NULL) que.push(root); 
        while(!que.empty()){
            int size = que.size();
            for(int i=0; i<size; i++){
                Node* node = que.front(); // [2,3]
                que.pop(); // [2]
                if(i == size-1) node->next =NULL;
                else{
                    node->next = que.front(); // 指向队列中的头元素
                }
                if(node->left) que.push(node->left);    // [3,4]
                if(node->right) que.push(node->right);  // [3,4,5]
            }
        }
        return root;

题目:104.二又树的最大深度

题目链接:力扣题目链接

解法1:

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

题目:111.二又树的最小深度

题目链接:力扣题目链接

解法1:

class Solution {
public:
    int minDepth(TreeNode* root) {
        if(root == NULL) return 0;
        // 队列
        queue<TreeNode*> que;
        int result = 0; // 记录深度
        if(root != NULL) que.push(root); 
        while(!que.empty()){
            int size = que.size();
            result ++; 
            for(int i=0; i<size; i++){
                TreeNode* node = que.front(); // [9,20]
                que.pop();
                // 当左右节点都为空时,返回深度
                if(!node->left && !node->right) return result; 
                if(node->left) que.push(node->left);   
                if(node->right) que.push(node->right); 
            } 
        }
        return result;
    }
};

题目:226.翻转二叉树

题目链接:力扣题目链接

解法1:递归法

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        // 确定终止条件
        if(root == NULL) return root;
        // 前序
        swap(root->left, root->right);  //中
        invertTree(root->left);     // 左
        invertTree(root->right);    // 右
        return root;
    }
};

解法2:层序遍历法

TreeNode* inverTree(TreeNode* root) {
	if (root == NULL) return NULL;
	queue<TreeNode*>que;
	que.push(root); 
	while (!que.empty()) {
		int size = que.size();
		while (size--) {
			TreeNode* cur = que.front();
			swap(cur->left, cur->right);
			que.pop();
			if (cur->left)que.push(cur->left);
			if (cur->right)que.push(cur->right);
		}
	}
	return root;
}

题目:101.对称二叉树

题目链接:力扣题目链接

解法1:收集孩子的信息,向上进行反馈,用后序

class Solution {
public:
    //1.确定传入的值(左右节点),返回bool类型,比较结果
    bool compare(TreeNode* left, TreeNode* right){
        //2.确定终止条件  左右都为空,对称, 返回true
        if(left == NULL && right != NULL) return false;
        // 单边为空的情况,则不对称
        else if(left != NULL && right == NULL) return false;
        else if(left == NULL && right == NULL) return true;  // 两遍都为空时不向下遍历,返回true
        // 两边都不为空,则比较值
        else if(left->val != right->val) return false;  // 没有用else剩下只有两值相等的情况
        // 3.处理单层  后序遍历
        bool outnode = compare(left->left, right->right);  // 比较外侧节点
        bool innode = compare(left->right, right->left);   // 比较内侧节点
        bool result = outnode && innode;
        return result;
    }

    bool isSymmetric(TreeNode* root) {
        return compare(root->left, root->right);
    }
};

解法2:迭代法

	bool isSymmetric(TreeNode* root) {
		//return iscompare(root->left, root->right);
        // 迭代法
		if (root == NULL)return true; //空节点也为对称
		queue<TreeNode*>que;
		que.push(root->left);
		que.push(root->right);
		while (!que.empty()) { 
			TreeNode* leftnode = que.front(); que.pop();
			TreeNode* rightnode = que.front(); que.pop();
			// 右为空,左为空,则为对称,继续
			if (rightnode == NULL && leftnode == NULL) continue;
			// 经过上面的判断后,就只剩单边为空的情况了
			if (rightnode == NULL || leftnode == NULL)return false;
			// 比较值相同
			else if (leftnode->val != rightnode->val)return false;
			// 放入节点
			que.push(leftnode->left);
			que.push(rightnode->right);
			que.push(leftnode->right);
			que.push(rightnode->left);
		}
		return true; //当节点都访问完,没有false则为true 
	}

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值