[LeetCode] 623. Add One Row to Tree 二叉樹中增加一行


 

Given the root of a binary tree, then value v and depth d, you need to add a row of nodes with value v at the given depth d. The root node is at depth 1.

The adding rule is: given a positive integer depth d, for each NOT null tree nodes N in depth d-1, create two tree nodes with value v as N's left subtree root and right subtree root. And N's original left subtree should be the left subtree of the new left subtree root, its original right subtree should be the right subtree of the new right subtree root. If depth d is 1 that means there is no depth d-1 at all, then create a tree node with value v as the new root of the whole original tree, and the original tree is the new root's left subtree.

Example 1:

Input: 
A binary tree as following:
       4
     /   \
    2     6
   / \   / 
  3   1 5   

v = 1

d = 2

Output: 
       4
      / \
     1   1
    /     \
   2       6
  / \     / 
 3   1   5   

 

Example 2:

Input: 
A binary tree as following:
      4
     /   
    2    
   / \   
  3   1    

v = 1

d = 3

Output: 
      4
     /   
    2
   / \    
  1   1
 /     \  
3       1

 

Note:

  1. The given d is in range [1, maximum depth of the given tree + 1].
  2. The given binary tree has at least one tree node.

 

這道題讓我們給二叉樹增加一行,給了需要增加的值,還有需要增加的位置深度,題目中給的例子也比較能清晰的說明問題。但是漏了一種情況,那就是當d=1時,這該怎么加?這時候就需要替換根結點了。其他情況的處理方法都一樣,這里博主第一映像覺得應該用層序遍歷來做,每遍歷完一層,d自減1,當d==1時,需要對於當前層的每一個結點,先用臨時變量保存其原有的左右子結點,然后新建值為v的左右子結點,將原有的左子結點連到新建的左子結點的左子結點上,將原有的右子結點連到新建的右子結點的右子結點,是不是很繞-.-|||。如果d不為1,那么就是層序遍歷原有的排入隊列操作,記得當檢測到d為0時,直接返回,因為添加操作已經完成,沒有必要遍歷完剩下的結點,參見代碼如下:

 

解法一:

class Solution {
public:
    TreeNode* addOneRow(TreeNode* root, int v, int d) {
        if (!root) return NULL;
        if (d == 1) {
            TreeNode *newRoot = new TreeNode(v);
            newRoot->left = root;
            return newRoot;
        }
        queue<TreeNode*> q{{root}};
        while (!q.empty()) {
            if (--d == 0) return root;
            int n = q.size();
            for (int i = 0; i < n; ++i) {
                auto t = q.front(); q.pop();
                if (d == 1) {
                    TreeNode *left = t->left;
                    TreeNode *right = t->right;
                    t->left = new TreeNode(v);
                    t->right = new TreeNode(v);
                    t->left->left = left;
                    t->right->right = right;
                } else {
                    if (t->left) q.push(t->left);
                    if (t->right) q.push(t->right);
                }
            }
        }
        return root;
    }
};

 

雖然博主一貫的理念是二叉樹問題肯定首選遞歸來解,但是這道題博主剛開始以為遞歸沒法解,結果看了大神們的帖子,才發現自己還是圖樣圖森破,難道二叉樹的問題皆可遞歸?反正這道題是可以的,而且寫法 so 簡潔,乍一看上去,會有疑問,題目中明明d的范圍是從1開始的,為何要考慮d為0的情況,后來讀懂了整個解法后,才為原作者的聰慧嘆服。這里d的0和1,其實相當於一種 flag,如果d為1的話,那么將 root 連到新建的結點的左子結點上;反之如果d為0,那么將 root 連到新建的結點的右子結點上,然后返回新建的結點。如果 root 存在且d大於1的話,那么對 root 的左子結點調用遞歸函數,注意此時若d的值正好為2,那么就不能直接減1,而是根據左右子結點的情況分別賦值1和0,這樣才能起到 flag 的作用嘛,叼的飛起,參見代碼如下:

 

解法二:

class Solution {
public:
    TreeNode* addOneRow(TreeNode* root, int v, int d) {
        if (d == 0 || d == 1) {
            TreeNode *newRoot = new TreeNode(v);
            (d ? newRoot->left : newRoot->right) = root;
            return newRoot;
        }
        if (root && d > 1) {
            root->left = addOneRow(root->left, v, d > 2 ? d - 1 : 1);
            root->right = addOneRow(root->right, v, d > 2 ? d - 1 : 0);
        }
        return root;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/623

 

參考資料:

https://leetcode.com/problems/add-one-row-to-tree/

https://leetcode.com/problems/add-one-row-to-tree/discuss/104555/C%2B%2B-Java-10-line-Solution-no-helper

https://leetcode.com/problems/add-one-row-to-tree/discuss/104547/Java-three-methods-one-BFS-and-two-DFS

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM