655. 输出二叉树

做题总结错误:

1.写函数名和变量名的时候一定注意,在之后引用的场合一定不能换成其他相似的语句

2.if else 语句可以用{}来表明逻辑断句

OK,开始审题!

在一个 m*n 的二维字符串数组中输出二叉树,并遵守以下规则:

  1. 行数 m 应当等于给定二叉树的高度
  2. 列数 n 应当总是奇数
  3. 根节点的值(以字符串格式给出)应当放在可放置的第一行正中间。根节点所在的行与列会将剩余空间划分为两部分(左下部分和右下部分)。你应该将左子树输出在左下部分,右子树输出在右下部分。左下和右下部分应当有相同的大小。即使一个子树为空而另一个非空,你不需要为空的子树输出任何东西,但仍需要为另一个子树留出足够的空间。然而,如果两个子树都为空则不需要为它们留出任何空间。
  4. 每个未使用的空间应包含一个空的字符串""
  5. 使用相同的规则输出子树

示例 1:

输入:
     1
    /
   2
输出:
[["", "1", ""],
 ["2", "", ""]]

示例 2:

输入:
     1
    / \
   2   3
    \
     4
输出:
[["", "", "", "1", "", "", ""],
 ["", "2", "", "", "", "3", ""],
 ["", "", "4", "", "", "", ""]]

示例 3:

输入:
      1
     / \
    2   5
   / 
  3 
 / 
4 
输出:
[["",  "",  "", "",  "", "", "", "1", "",  "",  "",  "",  "", "", ""]
 ["",  "",  "", "2", "", "", "", "",  "",  "",  "",  "5", "", "", ""]
 ["",  "3", "", "",  "", "", "", "",  "",  "",  "",  "",  "", "", ""]
 ["4", "",  "", "",  "", "", "", "",  "",  "",  "",  "",  "", "", ""]]

注意: 二叉树的高度在范围 [1, 10] 中。

解题思路:看函数定义可以知道我们要在一个二重向量中存储每一行的字符串向量

vector<vector<string>> printTree(TreeNode* root) {
    
}

1.首先确定这个二重向量的行数和列数。显然,行数为节点深度,列数为2^0+2^1+……+2^(k-1) = 2^k-1

2.然后接下来我们要确定的是树的节点对应的是字符串双重向量的哪个位置

层数很容易确定,主要是列下标,其实容易发现树的每一个节点所在的位置都在一个区间的中心,考虑

传参递归的时候每次传入这个左闭右开区间的左右端点

OK,代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<string>> printTree(TreeNode* root) {
        //通过计算可得输出的行数是列表的深度k,列数是2^k - 1
        int row = Depth(root);
        int column = pow(2, row) - 1;
        //vector构造函数实现初始化
        vector<vector<string>> outputArray(row, vector<string>(column, ""));
        getSingleRow(outputArray, root, 0, 0, column);
        return outputArray;
    }
    
    int Depth(struct TreeNode*root){
        //获取树的深度
        if(root == NULL)     return 0;
        int DepthL = Depth(root->left);
        int DepthR = Depth(root->right);
        return DepthL > DepthR ? (DepthL + 1) : (DepthR + 1);
    }
    
    void getSingleRow(vector<vector<string>> & output, struct TreeNode*root, int row, int left, int right){
        //树的每一个节点所在的位置都在一个区间的中心,考虑传参递归的时候每次传入这个左闭右开区间的左右端点
        if(root){
            int mid = (left + right)/2;//这里
            output[row][mid] = to_string(root->val);
            //int mid = (left + right - 1)/2也可以,因为left是偶数,right是奇数,所以求平均向下取整
            getSingleRow(output, root->left, row + 1,left, mid);
            getSingleRow(output, root->right, row+1 , mid+1, right);
        }
    }
};

参考blog:https://blog.csdn.net/obrcnh/article/details/78377490#commentBox

欢迎大家评论和提出意见!!!

猜你喜欢

转载自blog.csdn.net/liuxiang15/article/details/82287394