質問の説明
難易度 - 簡単
leetcode606. バイナリ ツリーから文字列を作成する
バイナリ ツリーのルート ノード ルートを指定した場合、プリオーダー トラバーサルを使用してバイナリ ツリーを括弧と整数で構成される文字列に変換し、構築された文字列を返してください。
空のノードは、空の括弧「()」のペアで表されます。変換後、文字列と元のバイナリ ツリー間の 1 対 1 のマッピング関係に影響を与えない空の括弧のペアはすべて省略する必要があります。
例 1:
入力: root = [1,2,3,4]
出力: "1(2(4))(3)"
説明: 初期変換後、「1(2(4)())(3)」が得られます。 () ())" ですが、不要な空括弧のペアをすべて省略すると、文字列は "1(2(4))(3)" になります。
例 2:
入力: root = [1,2,3,null,4]
出力: "1(2()(4))(3)"
説明: 最初の例と似ていますが、最初の null は省略できません。そうしないと、入力と出力の間の 1 対 1 のマッピング関係が破壊されます。
ヒント:
ツリー内のノード数の範囲は [1, 10^4]
-1000 <= Node.val <= 1000です。
DFS
この質問で一番難しいのは質問の意味を理解することですが、この手の記述は非常にわかりにくいので、まず目を通さないとどうすればいいのかわかりません。
質問の意味は、子ノードを () で囲む必要があるということです。たとえば、バイナリ ツリー [root,left,right] は root(left)(right) に変換されます。左のみが空のノードの場合、出力は root()(right) になります。右のみが空のノードの場合は、右のノードの () は無視でき、出力は root(left) になります。
実際の文字列生成のルールは、「事前順序走査」でノード値を出力する際に、各サブツリー(ルートノードを除く)の左右に()のペアを追加すると同時に、不要な()をいくつか追加する必要があります。無視される。
いわゆる不要とは、ノード
がルートで、左側のサブツリーのみがあり右側のサブツリーがない場合、右側のサブツリーの () を無視できるか、左右のサブツリーが存在しない場合、両方の () を無視できることを意味します。無視される。
逆に、空でない各ノードに()を追加すると、「右側のサブツリーがある」場合と「左側のサブツリーがない」場合、左側のサブツリーの()は無視できず、追加で追加する必要があります。したがって、生成された文字列が、あいまいさを引き起こすことなく、「左側のサブツリーがある」状況と「右側のサブツリーがない」状況から区別できることを確認します。
コードデモ:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
StringBuilder sb = new StringBuilder();
public String tree2str(TreeNode root) {
dfs(root);
return sb.substring(1, sb.length() - 1);
}
void dfs(TreeNode root) {
if(root == null){
return ;
}
sb.append("(");
sb.append(root.val);
if(root.left != null){
dfs(root.left);
}else if(root.right != null){
sb.append("()");
}
if(root.right != null){
dfs(root.right);
}
sb.append(")");
}
}