LeetCode アルゴリズム バイナリ ツリー - 116. 各ノードの右隣のノード ポインタを入力します。

目次

116. 各ノードの右隣のノード ポインタを設定します。

答え:

コード:

操作結果:


完全な二分木が あると 、そのすべての葉ノードは同じレベルにあり、各親ノードには 2 つの子ノードがあります。バイナリ ツリーは次のように定義されます。

struct ノード { 
  int val; 
  ノード*左; 
  ノード *右; 
  ノード*次; 
}

このポインタが次の右のノードを指すように、次のポインタのそれぞれに値を入力します。次の右のノードが見つからない場合、次のポインタは に設定されます NULL

最初は、すべての次のポインターが に設定されます NULL

例 1:

入力: root = [1,2,3,4,5,6,7]
出力: [1,#,2,3,#,4,5,6,7,#]
説明:指定されたバイナリ ツリーは次のとおりです。図 A に示すように、関数は、図 B に示すように、次のポインターをそれぞれ埋めて、次の右のノードを指すようにする必要があります。シリアル化された出力はレイヤー順のトラバーサルで配置され、同じレイヤー内のノードは次のポインターによって接続され、「#」は各レイヤーの終わりをマークします。

例 2:

入力: root = []
出力: []

ヒント:

  • ツリー内のノード数が [0, 212 - 1] 範囲内にあります
  • -1000 <= node.val <= 1000

高度な:

  • 一定の追加スペースのみを使用できます。
  • 再帰を使用して問題を解決することも要件を満たしますが、この問題で再帰プログラムが占有するスタック領域は、追加の領域の複雑さとしてカウントされません。

問題に対する反復的な解決策:

    // 反復的な解決策: 注意して観察すると、2 つの接続方法があることがわかります。

    // 1. 2 つの接続ポイントには共通の親ノードがあります

    // 2. 2 つの接続点の親ノードは異なり、上位層の次の隣接ノードの 1 つのノードと左のノードです。

    // 現在のノードに基づいて子ノードを処理できます。これは、レイヤーごとに処理することと同等です。

    // したがって、ネストされたループが 2 つ必要になります。内側の水平ループはレイヤーを処理し、次のレイヤーを垂直に入力します。

コード:

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {}
    
    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, Node _left, Node _right, Node _next) {
        val = _val;
        left = _left;
        right = _right;
        next = _next;
    }
};
*/

class Solution {
    // 迭代解决:仔细观察发现有两种连接方式
    // 1、两个连接点有共同父节点
    // 2、两个连接点父节点不同,分别是一个节点和上一层邻居next的左节点
    // 我们可以根据当前节点处理他的子节点,相当于一层一层处理
    // 所以需要两个循环嵌套,里面的横向处理完该层,再竖向进入下一层
    public Node connect(Node root) {
        // 特判:无节点则不需处理
        if(root==null) return root;
        // 定义一个节点等于root
        Node pre=root;
        // 左节点不为空则这层需要处理,进入循环开始处理这一层
        while(pre.left!=null){
            Node tmp=pre;
            while(tmp!=null){
                // 处理有共同父节点的连接点
                tmp.left.next=tmp.right;
                // 处理父节点不同的连接点
                if(tmp.next!=null){
                    tmp.right.next=tmp.next.left;
                }
                // 横向移动处理这一层未处理的节点
                tmp=tmp.next;
            }
            // 竖向移动处理下一层
            pre=pre.left;
        }
        return root;
    }
}

操作結果:

おすすめ

転載: blog.csdn.net/qq_62799214/article/details/133278346