LeetCode114バイナリツリーをリンクリストに展開---バイナリツリー問題の3つの解決策(再帰)(反復)(先行ノード)

バイナリツリーをリンクリストに展開

LeetCode 114:バイナリツリーをリンクリストに展開します
説明:
バイナリツリーのルートノードルートを指定して、それを単一リンクリストに展開してください。

  • 展開された単一リンクリストもTreeNodeを使用する必要があります。ここで、右の子ポインターはリンクリスト内の次のノードを指し、左の子ポインターは常にnullです。
  • 展開された単一リンクリスト、バイナリツリーと同じプレオーダートラバーサル順序である必要があります。
    ここに画像の説明を挿入

解決策1:再帰的解決策

問題解決のアイデア:

  1. プレオーダートラバーサルの方法を使用して、それに追加しlistます
  2. list要素をトラバースしてi、添え字ノードの左側のサブツリーを空にし、右側i+1の添え字が添え字ノードを指すようにします。

コード:

class Solution {
    
    
    public void flatten(TreeNode root) {
    
    
        List<TreeNode> list = new ArrayList<TreeNode>();
        preorderTraversal(root, list);
        for (int i = 0; i < list.size() - 1; i++) {
    
    
            list.get(i).left = null;
            list.get(i).right = list.get(i+1);
        }
    }
    public void preorderTraversal(TreeNode root, List<TreeNode> list) {
    
    
        if (root == null) return;
        list.add(root);
        preorderTraversal(root.left, list);
        preorderTraversal(root.right, list);
    }
}

解決策2:反復的な解決策

問題解決のアイデア:

  1. スタックの後入れ先出し機能を使用して、前のノードを記録します。
  2. スタックが空でない場合、またはノードが空でない場合は、ループに入ります。ノードが空でない場合は、スタックをプッシュして挿入しlistます。ノードの左側のサブツリーを空になるまでループして、ループを停止します。 。
  3. 左側のサブツリーが空の場合は、スタックの一番上にある要素をポップし、スタックの一番上にあるノードの右側のサブツリーをループします。
  4. スタックが空でノードがトラバースされている場合、ループは終了します。
  5. 次に、リストをトラバースし、方法1の手順は同じです。

コード:

class Solution {
    
    
    public void flatten(TreeNode root) {
    
    
        if(root == null) return;
        Stack<TreeNode> stack = new Stack<>();
        List<TreeNode> list = new ArrayList<>();
        TreeNode cur = root;
        //cur 不为空 或 栈 不为空 进入循环
        while(cur != null || !stack.isEmpty()){
    
    
            while(cur != null){
    
    
                stack.push(cur);//cur不为空就入栈
                list.add(cur);//入栈的同时插入到list中
                cur = cur.left;//根->左的顺序
            }
            TreeNode top = stack.pop();
            cur = top.right;//根->左 结束之后 就开始 右
        }
        //遍历list
        for (int i = 0; i < list.size() - 1; i++) {
    
    
            list.get(i).left = null;
            list.get(i).right = list.get(i+1);
        }
    }
}

解決策3:プリカーサーノードのスペースの複雑さはO(1)です

問題解決のアイデア:

  1. 常にルートノードの右側のサブツリーを左側のサブツリーの右側のサブツリーに接続し、ルートの左側のサブツリーをルートの右側のサブツリーにし、左側のサブツリーを空のままにして、root=root.rightとします。
  2. ルートノードがnullでない場合、参照はcurを指しrootます。
  3. root左側のサブツリーが空でない場合は、 ;へのcurNextポインタを参照してください。root.left
  4. preポインタを引用しcurNext、ループするまでループしますループが終了する場合は、pre.right = nullletpre.right != nullます。pre = pre.rightpre.right == nullpre.right = cur. right
  5. cur.left = null;; cur.right = curNext_ cur = cur.right_
  6. 手順2〜4を繰り返します。

図面分析:

ここに画像の説明を挿入

コード:

class Solution {
    
    
    public void flatten(TreeNode root) {
    
    
        if(root == null) return;
        TreeNode cur = root;
        TreeNode curNext = null;
        while (cur != null){
    
    
            if(cur.left != null){
    
    
                curNext = cur.left;
            	TreeNode pre = curNext;
            	//让pre指向左子树的最右节点
           		while (pre.right != null){
    
    
                	pre = pre.right;
            	}
            	//让左子树最右节点和右子树链接
	           	pre.right = cur.right;
            	//让根节点的左边断开
            	cur.left = null;
            	//让根节点的右子树连接左子树
            	cur.right = curNext;
            }
            cur = cur.right;
        }
    }

}

おすすめ

転載: blog.csdn.net/wwzzzzzzzzzzzzz/article/details/122172287