Leetcode問題の解決策-662。二分木の最大幅

トピックリンク

タイトル説明:

二分木が与えられた場合、木の最大幅を取得する関数を記述します。ツリーの幅は、すべてのレイヤーの最大幅です。この二分木は完全な二分木と同じ構造ですが、一部のノードは空です。

各レイヤーの幅は、2つの端点間の長さとして定義されます(レイヤーの左端と右端の空でないノード、および2つの端の間のヌルノードも長さに含まれます)。

例1:
ここに画像の説明を挿入
例2:
ここに画像の説明を挿入
例3:
ここに画像の説明を挿入
例4:
ここに画像の説明を挿入


BFS

  タイトルは私たちの满二叉树構造を示唆しているので、完全な二分木の構造的特徴(完全な二分木の特別な場合)を確認しましょう。主題を考えると、深さではなく木の幅を求める必要があり、当然、レベルトラバーサル、つまりBFSである可能性があると考えました。では、各レイヤーの幅を記録する方法は?単純なlevel + 1だけでは問題を解決できないこと明らかです。現時点では、完全な二分木の親ノードと左右の子ノードのインデックス間の数値関係を考慮する必要があります父节点索引为i,左子结点索引为2 * i,右子结点索引为2 * i + 1絵を描いてそれ、当前层的最右端索引 - 当前层的最左端索引 + 1つまり現在のレイヤーの幅について考えてください。残りはmax最大幅を探し続けます。もちろん、list或vector各レイヤーの左端のインデックスの特別なレコードを追加することもできます(これが使用されますlevel)。


コード

class Solution {
    
    
public:
    int widthOfBinaryTree(TreeNode* root) {
    
    
        if(!root)
            return 0;
        
        unsigned long long width = 0;
        queue< pair<TreeNode*,unsigned long long> > q;
        q.push(make_pair(root,1));
        while(!q.empty()){
    
    
            int size = q.size();
            unsigned long long l, r;
            for(int i = 0; i < size; i++){
    
    
                TreeNode* node = q.front().first;
                unsigned long long pos = q.front().second;
                q.pop();

                if(i == 0)
                    l = pos;
                if(i == size - 1)
                    r = pos;

                if(node->left)
                    q.push(make_pair(node->left,pos * 2));
                if(node->right)
                    q.push(make_pair(node->right,pos * 2 + 1));
            }
            width = max(width, r - l + 1);
        }

        return width;
    }
};

DFS

  通常の状況では、DFSを使用して木の高さを見つけますが、この質問を使用できますか?答えはイエスです!最後の文はちょうど今私たちに思い出させました。実際、道路は理想的ですが、各レイヤーのキューを使用して決済を行うのとは異なります。再帰機能のため、各レイヤーの左端のインデックスを記録してlevelから、現在のノードのレイヤーを見つける必要があります。レイヤーの左端のインデックスと比較します。相减并加1max現在の最大幅を取得し続けます。
  では、コンピューターは、現在のノードが現在のレイヤーの左端のノードであるかどうかをどのように知るのでしょうか。フレームワークを順番にトラバースし、ノードを初めて通過するときに続行することをお勧めしvisitます。これは、この要件を解決するための前提条件を提供します。左端のエンドポイントのインデックスrecordLevel記録するコンテナを設定します。明らかに、レイヤーの数はコンテナのsizeサイズと同じです。ノードの後、現在のレイヤーが>コンテナサイズであるかどうかが判断されます。それより大きい場合、明らかです、初めてこのレベルに到達する。あなたが最初に通過した場合根左右、あなたはそれを記録し、これは現在のレイヤーの左端のノードであると結論付けることができます。現在のノードの操作は最大幅を計算することであり、残りは再帰に渡されます〜


コード

class Solution {
    
    
public:
    int widthOfBinaryTree(TreeNode* root) {
    
    
        if(!root)
            return 0;
        
        helper(root, 1, 1);
        return width;
    }

private:
    unsigned long long width = 0;
    vector<unsigned long long> recordLevel;
    void helper(TreeNode* root, unsigned long long pos, int level){
    
    
        if(!root)
            return;

        if(level > recordLevel.size())
            recordLevel.push_back(pos);
        width = max(width, pos - recordLevel[level - 1] + 1);
        if(root->left)
            helper(root->left, pos * 2, level + 1);
        if(root->right)
            helper(root->right, pos * 2 + 1, level + 1);

        return;
    }
};

テストケースについて

DFSであろうとBFSであろう、最大幅とインデックス  を使用intまたはlong long記録する場合テストケースに分類される可能性があります。どうやってそれを知っているのか聞かないでください〜整数オーバーフローwidthpos107

Line 35: Char 54: runtime error: signed integer overflow: 2147483647 * 2 cannot be represented in type 'int' (solution.cpp)

  それを解決する方法は、比較的簡単な方法はunsigned long long、渡す幅とインデックスの変数タイプを設定することです


間違いや厳しくない場合は訂正してください、ありがとうございます。
私のブログ:http//breadhunter.gitee.io

おすすめ

転載: blog.csdn.net/weixin_40807714/article/details/105196135