二分木 OJ (1) 二分木 && 二分探索木と二重連結リスト && 対称二分木の最大深さ

二分木の最大深さ

二分木で合計が特定の値になるパス (1)

二分探索木と双方向リンクリスト

対称二分木


二分木の最大深さ

説明

与えられたバイナリ ツリーの最大の深さを見つけます。

深さとは、ツリーのルート ノードから任意のリーフ ノードまでのパス上のノードの数を指します。

最大深度は、すべてのリーフ ノードの深度の最大値です。

(注: リーフ ノードとは、子ノードを持たないノードを指します。)

[再帰]

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;
    }
};

おすすめ

転載: blog.csdn.net/weixin_66151870/article/details/129112913