1. 程式人生 > 實用技巧 >[LeetCode] 993. Cousins in Binary Tree 二叉樹的表兄弟節點

[LeetCode] 993. Cousins in Binary Tree 二叉樹的表兄弟節點


In a binary tree, the root node is at depth0, and children of each depthknode are at depthk+1.

Two nodes of a binary tree arecousinsif they have the same depth, but havedifferent parents.

We are given therootof a binary tree with unique values, and the valuesxandyof two different nodes in the tree.

Returntrue

if and only if the nodes corresponding to the valuesxandyare cousins.

Example 1:

Input: root = [1,2,3,4], x = 4, y = 3
Output: false

Example 2:

Input: root = [1,2,3,null,4,null,5], x = 5, y = 4
Output: true

Example 3:

Input: root = [1,2,3,null,4], x = 2, y = 3
Output: false

Constraints:

  • The number of nodes in the tree will be between2
    and100.
  • Each node has a unique integer value from1to100.

這道題定義了一種二叉樹數的表兄弟結點,就是不屬於同一個父結點,但是深度相同,現在給了兩個結點值,問它們代表的結點是否是表兄弟結點。由於表兄弟結點一定是屬於同一層的,所以可以使用二叉樹的層序遍歷,就像之前那道 Binary Tree Level Order Traversal 一樣。這裡額外需要兩個布林型變數 isX,isY 來記錄x和y是否已經遍歷到了。由於是層序遍歷,所以 while 中需要有個 for 迴圈,在迴圈中,取出隊首結點,然後看結點值是否等於x或y,是的話標記布林變數。然後檢查當前結點的左右子結點是否分別是x和y,是的話直接返回 false。否則將左右子結點排入佇列之中,若存在的話。當前層遍歷完了之後,檢查 isX 和 isY 的值,若同時為 true,表示存在表兄弟結點,返回 true。若只有一個為 true 的話,說明二者不在同一層,直接返回 false,參見程式碼如下:


解法一:

class Solution {
public:
    bool isCousins(TreeNode* root, int x, int y) {
        queue<TreeNode*> q{{root}};
        bool isX = false, isY = false;
        while (!q.empty()) {
            for (int i = q.size(); i > 0; --i) {
                TreeNode *cur = q.front(); q.pop();
                if (cur->val == x) isX = true;
                if (cur->val == y) isY = true;
                if (cur->left && cur->right) {
                    int left = cur->left->val, right = cur->right->val;
                    if ((left == x && right == y) || (left == y && right == x)) return false;
                }
                if (cur->left) q.push(cur->left);
                if (cur->right) q.push(cur->right);
            }
            if (isX && isY) return true;
            if (isX || isY) return false;
        }
        return false;
    }
};

當然我們也可以用遞迴的方法來做,由於不能同時處理同一層的結點,就需要兩個變數 depthX 和 depthY 來記錄結點x和y的深度,同時再用個布林變數 sameParent 來記錄這兩個結點是否有相同的父結點。在遞迴函式中,若當前結點 node 為空,直接返回。若當前結點值是x,則 depthX 賦值為當前深度 cur,同理,若當前結點值是y,則 depthY 賦值為當前深度 cur。然後檢查當前結點的左右子結點是否分別是x和y,是的話 sameParent 標記為 true,最後分別對左右子結點呼叫遞迴即可,參見程式碼如下:


解法二:

class Solution {
public:
    bool isCousins(TreeNode* root, int x, int y) {
        int depthX = 0, depthY = 0;
        bool sameParent = false;
        helper(root, x, y, 0, depthX, depthY, sameParent);
        return !sameParent && depthX == depthY;
    }
    void helper(TreeNode* node, int x, int y, int cur, int& depthX, int& depthY, bool& sameParent) {
        if (!node) return;
        if (node->val == x) depthX = cur;
        if (node->val == y) depthY = cur;
        if (node->left && node->right) {
            int left = node->left->val, right = node->right->val;
            if ((left == x && right == y) || (left == y && right == x)) sameParent = true;
        }
        helper(node->left, x, y, cur + 1, depthX, depthY, sameParent);
        helper(node->right, x, y, cur + 1, depthX, depthY, sameParent);
    }
};

接下來這種方法是博主在 Contest 時想出來的,思路比較簡單粗暴,就是建立每個結點和其深度跟父結點組成的 pair 對兒之間的對映,然後就可以直接用x和y去獲得其深度和父結點進行比較即可,參見程式碼如下:


解法三:

class Solution {
public:
    bool isCousins(TreeNode* root, int x, int y) {
		unordered_map<int, pair<int, int>> m;
		helper(root, 0, -1, m);
		return m[x].first == m[y].first && m[x].second != m[y].second;
    }
    void helper(TreeNode* node, int depth, int parent, unordered_map<int, pair<int, int>>& m) {
    	if (!node) return;
    	m[node->val] = {depth, parent};
    	helper(node->left, depth + 1, node->val, m);
    	helper(node->right, depth + 1, node->val, m);
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/993


類似題目:

Binary Tree Level Order Traversal


參考資料:

https://leetcode.com/problems/cousins-in-binary-tree/

https://leetcode.com/problems/cousins-in-binary-tree/discuss/238536/My-Easy-Recursive-C%2B%2B-Solution

https://leetcode.com/problems/cousins-in-binary-tree/discuss/239376/Java-BFS-time-and-space-beat-100


LeetCode All in One 題目講解彙總(持續更新中...)