【Leetcode]ツリー(Ⅲ)

すべての質問は簡単なレベルです。

BSTのノード間の最短距離

質問[783]:ルート・ノードのルートでバイナリ検索ツリー(BST)が与えられると、ツリー内の任意の2つの異なるノードの値の間の最小の差を返します。

Input: root = [4,2,6,1,3,null,null]
Output: 1
Explanation: Note that root is a TreeNode object, not an array. The given tree [4,2,6,1,3,null,null] is represented by the following diagram:

          4
        /   \
      2      6
     / \    
    1   3  

while the minimum difference in this tree is 1, it occurs between node 1 and node 2, also between node 3 and node 2.

解決

トラバーサル順序どおり、だけトラバーサル一回。

class Solution
{
public:
    int minDiffInBST(TreeNode *root)
    {
        return inorder2(root);
    }

    int inorder2(TreeNode *root)
    {
        bool first = true;
        int diff = 0x7ffffff;
        int pre = -1;
        auto p = root;
        stack<TreeNode *> s;
        while (p != nullptr || !s.empty())
        {
            if (p != nullptr)
            {
                s.push(p);
                p = p->left;
            }
            else
            {
                p = s.top(), s.pop();
                if (first)
                    pre = p->val, first = false;
                else
                    diff = min(diff, abs(p->val - pre)), pre = p->val;
                p = p->right;
            }
        }
        return diff;
    }

    int inorder(TreeNode *root)
    {
        vector<int> v;
        auto p = root;
        stack<TreeNode *> s;
        while (p != nullptr || !s.empty())
        {
            if (p != nullptr)
            {
                s.push(p);
                p = p->left;
            }
            else
            {
                p = s.top(), s.pop();
                v.push_back(p->val);
                p = p->right;
            }
        }
        int diff = abs(v[1] - v[0]);
        for (int i = 2; i < (int)v.size(); i++)
            diff = min(diff, abs(v[i] - v[i - 1]));
        return diff;
    }
};

リーフと同様に木

質問[872]:バイナリツリーのすべての葉を考えてみましょう。左から右の順に、それらの葉の値は、リーフ値のシーケンスを形成します。その葉の値のシーケンスが同じである場合、2つのバイナリツリーは、葉と同様の考えられています。ヘッドノードと場合にのみ与えられた二つの木は、trueを返しますroot1root2葉に類似しています。

解決

トラバーサル順序どおり。

class Solution
{
public:
    bool leafSimilar(TreeNode *root1, TreeNode *root2)
    {
        return inorder(root1) == inorder(root2);
    }
    vector<int> inorder(TreeNode *root)
    {
        vector<int> v;
        auto p = root;
        stack<TreeNode *> s;
        while (!s.empty() || p != nullptr)
        {
            if (p != nullptr)
            {
                s.push(p);
                p = p->left;
            }
            else
            {
                p = s.top(), s.pop();
                if (p->left == nullptr && p->right == nullptr)
                    v.push_back(p->val);
                p = p->right;
            }
        }
        return v;
    }
};

昇順検索ツリー

質問[897]:二分探索木を考えると、ツリー内の左端のノードが今ツリーのルートで、すべてのノードが左の子とだけ1右の子を持っていないようで、順番にツリーを並べ替えます。

Input: [5,3,6,2,4,null,8,1,null,null,null,7,9]
       5
      / \
    3    6
   / \    \
  2   4    8
 /        / \ 
1        7   9
Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]
 1
  \
   2
    \
     3
      \
       4
        \
         5
          \
           6
            \
             7
              \
               8
                \
                 9  

解決

TreeNode *increasingBST(TreeNode *root)
{
    return inorder(root);
}
TreeNode *inorder(TreeNode *oldRoot)
{
    TreeNode *newRoot = new TreeNode(-1);
    auto t = newRoot;
    auto p = oldRoot;
    stack<TreeNode *> s;
    while (p != nullptr || !s.empty())
    {
        if (p != nullptr)
            s.push(p), p = p->left;
        else
        {
            p = s.top(), s.pop();
            t->right = new TreeNode(p->val);
            t = t->right;
            p = p->right;
        }
    }
    return newRoot->right;
}

BSTの範囲和

質問[938]:バイナリサーチツリーのルートノードを考えると、L及びR(両端を含む)の間の値を持つすべてのノードの値の合計を返します。二分探索木は、一意の値を持つことが保証されています。

Input: root = [10,5,15,3,7,null,18], L = 7, R = 15
Output: 32

解決

三つのソリューション。

  • INORDERトラバーサル
int inorder(TreeNode *root, int l, int r)
{
    int sum = 0;
    auto p = root;
    stack<TreeNode *> s;
    while (p != nullptr || !s.empty())
    {
        if (p)
            s.push(p), p = p->left;
        else
        {
            p = s.top(), s.pop();
            if (l <= p->val && p->val <= r)
                sum += p->val;
            else if (p->val > r)
                break;
            p = p->right;
        }
    }
    return sum;
}
  • 再帰で検索
int sum = 0;
void helper(TreeNode *root, int l, int r)
{
    if (root == nullptr)    return;
    if (root->val < l)      helper(root->right, l, r);
    else if (root->val > r) helper(root->left, l, r);
    else
    {
        sum += root->val;
        helper(root->left, l, r);
        helper(root->right, l, r);
    }
}
  • 反復(スタック)で検索
int search(TreeNode *root, int l, int r)
{
    int result = 0;
    auto p = root;
    stack<TreeNode *> s;
    s.push(p);
    while (!s.empty())
    {
        p = s.top(), s.pop();
        if (p == nullptr)
            continue;
        if (l <= p->val && p->val <= r)
        {
            result += p->val;
            s.push(p->right);
            s.push(p->left);
        }
        else if (p->val < l)
            s.push(p->right);
        else if (p->val > r)
            s.push(p->left);
    }
    return result;
}

バイナリツリーのいとこ

質問[993]:バイナリツリーで、ルートノードは、深さであり0、各深さの子kノードは、深さですk+1バイナリツリーの2つのノードが、彼らは同じ深さを持っている場合はいとこですが、異なる親を持ちます。我々は、ユニークな値を持つ二分木のルートを与え、そして値であるxy、ツリー内の2つの異なるノードの。戻りtrue場合にのみ値に対応するノードの場合xとはyいとこです。

解決

レベル順トラバーサル。

class Solution
{
public:
    bool isCousins(TreeNode *root, int x, int y)
    {
        if (root == nullptr)
            return false;
        queue<TreeNode *> q;
        TreeNode *xparent = nullptr, *yparent = nullptr;
        auto p = root;
        q.emplace(p);
        while (!q.empty())
        {
            queue<TreeNode *> nextlevel;
            while (!q.empty())
            {
                p = q.front(), q.pop();
                if (p->left)
                {
                    nextlevel.emplace(p->left);
                    if (x == p->left->val)
                        xparent = p;
                    if (y == p->left->val)
                        yparent = p;
                }
                if (p->right)
                {
                    nextlevel.emplace(p->right);
                    if (x == p->right->val)
                        xparent = p;
                    if (y == p->right->val)
                        yparent = p;
                }
            }
            q = nextlevel;
            // not found yet
            if (xparent == nullptr && yparent == nullptr)
                continue;
            // not same level
            if ((xparent == nullptr) ^ (yparent == nullptr))
                return false;
            // found at same level
            return xparent != yparent;
        }
        // can not be here
        return false;
    }
};

ルートにリーフバイナリ数の和

質問[1022]バイナリツリーを考えると、各ノードは値を持っています0か、1各ルート・ツー・リーフパスが最上位ビットで始まる2進数を表します。パスがある場合、例えば、0 -> 1 -> 1 -> 0 -> 1これは、ツリー内のすべての葉については13であり、バイナリ01101を表すことができ、次いで、その葉へのルートからのパスで表される数値を考えます。これらの数字の合計を返します。

Input: [1,0,1,0,1,0,1]
Output: 22
Explanation: (100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22

解決

ビット演算とバックトラック法(実際には先行順走査)。使用するval = (val << 1) | p->valパスを記録すること。

class Solution
{
public:
    int sum = 0;
    int sumRootToLeaf(TreeNode *root)
    {
        preorder(0, root);
        return sum;
    }
    void preorder(int val, TreeNode *p)
    {
        if (p == nullptr)
            return;
        val = (val << 1) | p->val;
        if (p->left == nullptr && p->right == nullptr)
            sum += val;
        preorder(val, p->left);
        preorder(val, p->right);
    }
};

面接の質問

BiNode LCCI

質問[17.12]:データ構造はTreeNode二分木のために使用されるが、それはまた、(左がnullであり、右側のリスト内の次のノードである)単一のリンクリストを表すために使用することができます。(で実装バイナリ検索ツリーを変換する方法を実装TreeNode単一リンクされたリストにします)。値は、順番に維持する必要があり、操作が(元のデータ構造に、である)場所で行われるべきです。変換した後、リンクリストのヘッドノードを返します。

Input:  [4,2,5,1,3,null,6,0]
Output:  [0,null,1,null,2,null,3,null,4,null,5,null,6]

解決

トラバーサル順序どおり。

TreeNode *convertBiNode(TreeNode *root)
{
    TreeNode *newRoot = new TreeNode(-1);
    auto t = newRoot;
    auto p = root;
    stack<TreeNode *> s;
    while (!s.empty() || p != nullptr)
    {
        if (p)
        {
            s.emplace(p);
            p = p->left;
        }
        else
        {
            p = s.top(), s.pop();
            t->right = p, t = t->right;
            p = p->right;
        }
    }
    t = newRoot;
    while (t)
        t->left = nullptr, t = t->right;
    return newRoot->right;
}

おすすめ

転載: www.cnblogs.com/sinkinben/p/12668994.html