1. 程式人生 > >【leetcode】二叉樹的鋸齒形層次遍歷

【leetcode】二叉樹的鋸齒形層次遍歷

問題描述:

給定一個二叉樹,返回其節點值的鋸齒形層次遍歷。(即先從左往右,再從右往左進行下一層遍歷,以此類推,層與層之間交替進行)。

例如:
給定二叉樹 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回鋸齒形層次遍歷如下:

[
  [3],
  [20,9],
  [15,7]
]

解題思路:

1、首先計算出樹的高度depth,可以使用遞迴的方法求解,高度主要用於宣告返回陣列的行數,也就是給定函式頭中的int* returnSize的值;

2、宣告返回的陣列變數:    int **result=(int **)malloc(sizeof(int *)*depth);//按要求存放每層節點的數字

3、宣告臨時儲存tree每層節點的陣列變數,因為儲存的是指向節點的指標,所以宣告如下:struct TreeNode*** temp=(struct TreeNode ***)malloc(sizeof(struct TreeNode**)*depth);

4、根據題目要求,開始逐行遍歷節點,可以看出,奇數行是從右往左遍歷,偶數行是從左往右遍歷(從0開始計數)。

提交程式碼如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *columnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int getDepth(struct TreeNode* root)
{
    if(root==NULL)
    {
        return 0;
    }
    int leftDepth=getDepth(root->left);
    int rightDepth=getDepth(root->right);
    int depth=leftDepth>rightDepth?leftDepth:rightDepth;
    return depth+1;
}

int** zigzagLevelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) {
    if(root==NULL)
    {
        return NULL;
    }
    int depth=getDepth(root);
    *returnSize=depth;//樹的高度,即返回陣列的行數
    int **result=(int **)malloc(sizeof(int *)*depth);//按要求存放每層節點的數字
    *columnSizes=(int *)malloc(sizeof(int)*depth);//樹的每行的節點個數
    result[0]=(int *)malloc(sizeof(int));
    result[0][0]=root->val;
    (*columnSizes)[0]=1;
    
    struct TreeNode*** temp=(struct TreeNode ***)malloc(sizeof(struct TreeNode**)*depth);
    temp[0]=(struct TreeNode**)malloc(sizeof(struct TreeNode*));
    temp[0][0]=root;
    
    int i=0;
    for(i=0;i<depth-1;i++)//i表示當前樹的層號,從0開始計數,注意i<depth-1,因為最後1行節點都沒有子節點,不需要再遍歷了,如果i<depth,會報如下錯誤:free(): invalid next size (fast): 0x0000000001d294d0 *** ---因為宣告result或者temp陣列的行樹只有depth,如果i=depth-1繼續執行,則result或者temp會繼續分配一行,超出了宣告的行數,因此指標被汙染了。
    {
        int tempLen=(*columnSizes)[i]*2;//第i+1行的節點個數的最大值
        temp[i+1]=(struct TreeNode **)malloc(sizeof(struct TreeNode*)*tempLen);//臨時存放第i+1行節點的陣列
        (*columnSizes)[i+1]=0;
 
        result[i+1]=(int *)malloc(sizeof(int)*tempLen);//存放第i+1行節點的值

        int nodes=(*columnSizes)[i];
        int j=0;
        if(i%2==0)//如果i是偶數,那麼下一行應該從右往左遍歷
        {            
            for(j=nodes-1;j>=0;j--)
            {
                if(temp[i][j]->right!=NULL)
                {
                    result[i+1][(*columnSizes)[i+1]]=temp[i][j]->right->val;
                    temp[i+1][(*columnSizes)[i+1]++]=temp[i][j]->right;
                }
                if(temp[i][j]->left!=NULL)
                {
                    result[i+1][(*columnSizes)[i+1]]=temp[i][j]->left->val;
                    temp[i+1][(*columnSizes)[i+1]++]=temp[i][j]->left;
                }                
            }
        }
        else//如果i是奇數,那麼下一行應該從左往右遍歷
        {
            for(j=nodes-1;j>=0;j--)
            {
                if(temp[i][j]->left!=NULL)
                {
                    result[i+1][(*columnSizes)[i+1]]=temp[i][j]->left->val;
                    temp[i+1][(*columnSizes)[i+1]++]=temp[i][j]->left;
                }                
                if(temp[i][j]->right!=NULL)
                {
                    result[i+1][(*columnSizes)[i+1]]=temp[i][j]->right->val;
                    temp[i+1][(*columnSizes)[i+1]++]=temp[i][j]->right;
                }
            }
        }
    }
    
    free(temp);
    
    printf("columnSize:");
    for(i=0;i<depth;i++)
    {
        printf("%d,",(*columnSizes)[i]);
    }
    printf("\n returnSize=%d\n",*returnSize);;
    
    return result;
}