[leetcode] 116. Populating Next Right Pointers in Each Node 解题报告

题目链接:https://leetcode.com/problems/populating-next-right-pointers-in-each-node/

Given a binary tree

    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

Initially, all next pointers are set to NULL.

Note:

  • You may only use constant extra space.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL

思路:可以利用队列进行层次遍历,因为是满二叉树,我们可以判断,只要不是最右边的一个结点,肯定有next结点,那么现在需要解决一个问题就是如何判断一个结点是不是在最右边。

我们可以计算得出每一层的结点个数为2^0, 2^1, 2^2, 2^3, ..., 2^n,而按层次遍历处在最右边的结点编号分别为2^1 - 1, 2^2 -1, ... , 2^n - 1,因此我们在遍历到一个编号为k的结点的时候,我们只要判断(k+1)是不是2的幂就可以知道这个结点是不是在最右边。如果不是的话,就让其next指向队列的下一个结点。

要判断一个数是不是2的幂方法有很多,可以用递归或者循环来解决,但是这样会使时间复杂度增长很多。而实际上有一种O(1)时间内判断一个数是不是2的幂的方法,参照这里。如果要判断一个数n是不是2的幂只要判断n&(n-1)是不是为0即可,因为一个数如果是2的幂,那么这个数换成2进制则只有一位为1。比如8,二进制表示为1000,8-1=7,7的二进制表示为0111, 8&7 = 0,因此这样就可以快速判断2的幂。

代码如下:

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(!root) return;
        int num = 0;
        queue<TreeLinkNode*> que;
        que.push(root);
        while(!que.empty())
        {
            TreeLinkNode* tem = que.front();
            que.pop();
            num++;
            if(tem->left)//如果这个结点有左右子树
            {
                que.push(tem->left);
                que.push(tem->right);
            }
            if((num & (num+1)) != 0)//不是最右边的,即不是2^n-1
                tem->next = que.front();
        }
    }
};


过了几天看II的时候回来再看一下这题,发现要求常量的辅助空间,我用了O(n)的辅助空间,所以有点尴尬,但是我觉得如果不限制空间,我的方法也是挺好的大笑。而II的方法是更广泛的解法,所以同样适用与这题。

代码如下:

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        TreeLinkNode *pHead = new TreeLinkNode(0), *pre = pHead;
        while(root)
        {
            if(root->left)
            {
                pre->next = root->left;
                pre = pre->next;
            }
            if(root->right)
            {
                pre->next = root->right;
                pre = pre->next;
            }
            root = root->next;
            if(!root)//遍历完了一层的所有结点,换到下一层的第一个结点
            {
                pre = pHead;
                root = pHead->next;
                pHead->next = NULL;
            }
        }
    }
};

参考:https://leetcode.com/discuss/67291/java-solution-with-constant-space













你可能感兴趣的:(LeetCode,tree,binary)