1. 程式人生 > 其它 >LeetCode100(力扣100) :相同的樹 C++ 多種思路

LeetCode100(力扣100) :相同的樹 C++ 多種思路

技術標籤:Leetcode筆記c++演算法leetcode

100.相同的樹

給定兩個二叉樹,編寫一個函式來檢驗它們是否相同。

如果兩個樹在結構上相同,並且節點具有相同的值,則認為它們是相同的。

示例 1:

輸入:       1         1
          / \       / \
         2   3     2   3
 
      [1,2,3],   [1,2,3]
輸出: true

示例 2:

輸入:      1          1
          /           \
         2             2

      [1,2],     [1,null,2]

輸出: false

示例 3:

輸入:       1         1
          / \       / \
         2   1     1   2

      [1,2,1],   [1,1,2]
      
輸出: false

我提交的程式碼

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == nullptr && q == nullptr) {
            return true;
        }
        if (
(p == nullptr && q != nullptr) || (p != nullptr && q == nullptr)) { return false; } if (p->val == q->val) { return (isSameTree(p->left, q->left) && isSameTree(p->right, q->right)); }else{ return false
; } } };

在這裡插入圖片描述

我的思想

當然是判斷每個結點是否一樣,如果每個結點都一樣的話那就是相同的樹。所以要遍歷樹,我使用遞迴來深度優先遍歷樹

情況:

​ 1.遞迴結束條件:當兩棵樹同時遍歷結束——>結點同時為空

  1. 如果一個結點為空,一個結點不為空——兩棵樹肯定不一樣的
  2. 結點值相等的時候,遞迴判斷她們的左右結點又是否同時滿足

我的程式碼優化

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == nullptr && q == nullptr) return true;
        if (p == nullptr || q == nullptr)  return false;
        if (p->val == q->val) return (isSameTree(p->left, q->left) && isSameTree(p->right, q->right));
        else  return false;
    }
};

噗,這還能叫優化?只是看起來簡潔了一點而已啊。嘖嘖菜的離譜

 if (p == nullptr || q == nullptr) 
 if ((p == nullptr && q != nullptr) || (p != nullptr && q == nullptr))

這兩句是一個意思,雖然使用 || 運算時,同時為1也能使得if條件為真,但是由於順序執行,就輪不到 || 來執行同時為1的情況。所以只要p、q有一個為真時,就能返回false。

官方題解

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == nullptr && q == nullptr) {
            return true;
        } else if (p == nullptr || q == nullptr) {
            return false;
        } else if (p->val != q->val) {
            return false;
        } else {
            return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
        }
    }
};

在這裡插入圖片描述

我和官方思想是一樣的,當情況相互對立的時候,使用else if減少情況判斷,提高執行效率

其他優秀題解

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == nullptr) return q == nullptr;
        return q != nullptr && p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
};

在這裡插入圖片描述

這個題解好666啊,把成立條件全部寫在return 語句裡,但是我很好奇怎麼做到的減少了記憶體消耗?求大佬解答

我學會了

  1. 樹的問題都是樹的遍歷問題,樹的遍歷問題就會用到遞迴。

    遞迴模板:

    void traverse(Tree root){
    	traverse(root.left);
    	traverse(root.right);
    }
    
  2. 在對立條件時候使用else if,別寫一堆if降低了執行效率

  3. 在遞迴的時候,可以把成立的條件都寫在return裡使用&&運算,減少了if的判斷

有不對的地方,可以改進的地方還望著大佬指出,謝謝呀!我真是太菜了