二分木の最大深さ
説明
与えられたバイナリ ツリーの最大の深さを見つけます。
深さとは、ツリーのルート ノードから任意のリーフ ノードまでのパス上のノードの数を指します。
最大深度は、すべてのリーフ ノードの深度の最大値です。
(注: リーフ ノードとは、子ノードを持たないノードを指します。)
[再帰]
class Solution {
public:
int maxDepth(TreeNode* root) {
// write code here
if(root==nullptr)
return 0;
int left = maxDepth(root->left);
int right = maxDepth(root->right);
return left>right?left+1:right+1;
}
};
[非再帰] 層順トラバーサル (キューを使用してノードを格納)
class Solution {
public:
int maxDepth(TreeNode* root) {
// write code here
if(root == nullptr)
return 0;
int res = 0;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
int size = q.size();
while(size--)
{
TreeNode* cur = q.front();
q.pop();
if(cur->left) q.push(cur->left);
if(cur->right) q.push(cur->right);
}
res++;
}
return res;
}
};
二分木で合計が特定の値になるパス (1)
説明
二分木のルートと値の合計が与えられたとき、ルート ノードからリーフ ノードまでのノード値の合計が合計と等しいパスがあるかどうかを判断します。
1. この質問のパスは、ツリーのルート ノードからリーフ ノードまでのノードとして定義されます。
2. リーフ ノードとは、子ノードを持たないノードを指します。
3.パスは、子ノードから親ノードではなく、親ノードから子ノードにのみ移動できます
4. ノードの総数は n
例:
次のバイナリ ツリーの場合、sum=22 sum=22,
5→4→11→25→4→11→2という経路があり、ノード値の合計が22なのでtrueを返す
class Solution {
public:
bool flag = false;
void dfs(TreeNode* root, int sum)
{
if(root==nullptr)return;
sum-=root->val;
if(sum==0 && root->left==nullptr && root->right==nullptr)
{
flag = true; // 如果为根节点并且sum==0那么存在路径
return;
}
dfs(root->left, sum);
dfs(root->right, sum);
}
bool hasPathSum(TreeNode* root, int sum) {
dfs(root, sum);
return flag;
}
};
二分探索木と双方向リンクリスト
二分探索木を入力し、二分探索木をソート済み二重連結リストに変換します。以下に示すように
データ範囲: 入力二分木のノード数 0≤n≤10000≤n≤1000、二分木の各ノードの値 0≤val≤10000≤val≤1000
要件: 空間複雑度 O(1)O( 1) (つまり、元の Tree 操作では)、時間計算量 O(n)O(n)知らせ:
1. 新しいノードを作成できないようにする必要があります。ツリー内のノード ポインタのポイントのみを調整できます。変換が完了した後、ツリー内のノードの左ポインターは先行ノードを指し、ツリー内のノードの右ポインターは後続ノードを指す必要があります。 2. ポインターをリンクされたノードの最初のノードに戻します
。リスト
3. 関数によって返された TreeNode には、左右のポインターがあり、実際には双方向リンク リストのデータ構造で見ることができます。4. 双方向リンク リストを出力する必要はありません。プログラムは戻り値に従って自動的に出力します。
class Solution {
public:
vector<TreeNode*> res;
void Inoder(TreeNode* root)
{
if(root == NULL)
return;
Inoder(root->left);
res.push_back(root);
Inoder(root->right);
}
TreeNode* Convert(TreeNode* pRootOfTree) {
if(pRootOfTree==NULL)
return NULL;
Inoder(pRootOfTree);
for(int i = 0; i < res.size()-1; ++i)
{
res[i]->right = res[i+1];
res[i+1]->left = res[i];
}
return res[0];
}
};
対称二分木
説明
与えられた二分木で、それ自体の鏡像であるかどうか (つまり、対称かどうか) を判断します。
たとえば、次の二分木は対称です。
次の二分木は非対称です。
データ範囲:ノード数が0≦n≦10000≦n≦1000、ノード上の値が∣val∣≦1000∣val∣≦1000を満たす
要件: 空間の複雑さ O(n)O(n)、時間の複雑さ O(n)O(n)
述べる:
この問題は、再帰的および反復的な 2 つの方法で解決できます。
[再帰的な解決策]
class Solution {
public:
bool recursion(TreeNode* p, TreeNode* q)
{
if(p==nullptr && q==nullptr)
return true;
else if(p==nullptr || q==nullptr)
return false;
else if(q->val != p->val)
return false;
return recursion(p->left, q->right) &&
recursion(p->right, q->left);
}
bool isSymmetrical(TreeNode* root) {
if(root==nullptr)return true;
return recursion(root, root);
}
};
[非再帰]
class Solution {
public:
bool isSymmetrical(TreeNode* root) {
if(root==nullptr)return true;
queue<TreeNode*> q1;
queue<TreeNode*> q2;
q1.push(root->left);
q2.push(root->right);
while(!q1.empty() && !q2.empty())
{
TreeNode* left = q1.front();
TreeNode* right = q2.front();
q1.pop();
q2.pop();
if(left==nullptr && right==nullptr)
continue;
if(left==nullptr || right==nullptr || left->val != right->val)
return false;
q1.push(left->left);
q1.push(left->right);
q2.push(right->right);
q2.push(right->left);
}
return true;
}
};