這篇部落格我們主要來看二叉樹和二叉樹問題中使用遞迴來解決問題的思路。這類問題有時思路很簡單,這是因為二叉樹具有天然的遞迴結構,所以我們使用遞迴的解法解決二叉樹有關的問題就變得非常明顯。
二叉樹前序遍歷
//前序遍歷node節點
void preorder(treenode * node)
cout << node -> val;
preorder(node -> left);
preorder(node -> right);//遞迴過程
}複製**
二叉樹查詢某個節點bool contain(node *node, key key)
複製**
刪除一顆二叉樹void destroy(node * node)
複製**
class solution
return 1 + max(maxdepth(root -> left), maxdepth(root -> right));
}};複製**
leetcode 111
/// definition for a binary tree node.
struct treenode
};class solution
inverttree( root->left );
inverttree( root->right );
swap ( root->left, root->right );
return root;}};
複製**
leetcode 100
leetcode 101
leetcode 222
leetcode 110
有的時候遞迴的終止條件是存在陷阱的。
解題思路
採取遞迴來解決這個問題,我們可以從頭結點開始,向它的左右孩子節點尋找sum-根節點的值,不斷向下尋找。這道題陷阱在於終止條件不是node == null。
/**
* definition for a binary tree node.
* struct treenode
* };
*/class solution
//為葉子節點
if (root -> left == null && root -> right == null)
return haspathsum(root -> left, sum - root -> val) || haspathsum(root -> right, sum - root -> val);
return
false;
}}; 複製**
我們如何使用遞迴的返回值來解決問題。 函式的語義很重要
思路
對於每乙個節點,就是該節點的值加上「->」再加上左子樹的路徑字串和右子樹路徑字串。當到達葉節點時,將字串加入結果集。實現
/**
* definition for a binary tree node.
* struct treenode
* };
*/class solution
if (root -> left == null && root -> right == null)
vectorlefts = binarytreepaths(root -> left);
for(int i = 0; i < lefts.size(); i++)
vectorrights = binarytreepaths(root -> right);
for(int i = 0; i < rights.size(); i++)
return res;
}};複製**
leetcode 113
leetcode 129
解題思路
猛地一看這個描述,和我們之前的path sum是一樣的。但是區別在於我們對於路徑的定義不一定要起始於根節點,終止於葉子結點,路徑可以從任意節點開始,但是只能是向下走的。
在乙個節點上要通過三個部分獲得答案,第乙個部分看看有沒有一條路徑,它包含node這個節點,並且它的和為sum,這個路徑我們進入findpath這個子過程,這個子過程本身又是乙個遞迴函式。另外的兩部分就是要在node的左右子樹去尋找沒有這個ndoe節點的值,有沒有這樣的路徑,他們的和仍然為sum,這件事就是我們pathsum這個函式所做的。在node->left和node->right分別呼叫pathsum的過程中,他們也會呼叫findpath來求解。**實現
#include
using namespace std;
// definition for a binary tree node.
struct treenode
};class solution
int res = findpath( root, sum );
res += pathsum( root->left, sum );
res += pathsum( root->right, sum );
return res;
}private:
// 在以node為根節點的二叉樹中,尋找包含node的路徑,和為sum
// 返回這樣的路徑個數
int findpath( treenode* node, int num)
int res = 0;
if ( node->val == num )
res += findpath( node->left, num - node->val );
res += findpath( node->right, num - node->val );
return res;}};
複製**
思路
二分搜尋樹:每個節點的鍵值大於左孩子
每個節點的鍵值小於右孩子
以左右孩子為跟的子樹仍為二分搜尋樹
如果我們給的p,q節點都小於node節點,那麼他們最近的公共祖先一定在node左邊。如果我們給的p,q節點都大於node節點,那麼他們最近的公共祖先一定在ndoe右邊。如果一小一大,那麼node一定是最近的公眾祖先。**實現
/**
* definition for a binary tree node.
* struct treenode
* };
*/class solution
if ((root -> val > p -> val) && (root -> val > q -> val))
return lowestcommonancestor(root -> left, p, q);
if ((root -> val < p -> val) && (root -> val < q -> val))
return lowestcommonancestor(root -> right, p, q);
//p 與q在root的兩側, 則root必為公共祖先,包含p為q的祖先
return root;
}};複製**
leetcode 98
leetcode 450
leetcode 108
leetcode 230
leetcode 236
-------------------------華麗的分割線--------------------
看完的朋友可以點個喜歡/關注,您的支援是對我最大的鼓勵。
個人部落格番茄技術小棧和掘金主頁
leetcode 二叉樹 對稱二叉樹
給定乙個二叉樹,檢查它是否是映象對稱的。例如,二叉樹 1,2,2,3,4,4,3 是對稱的。1 2 2 3 4 4 3 但是下面這個 1,2,2,null,3,null,3 則不是映象對稱的 1 2 2 3 3 方法一 遞迴 思路 如果乙個樹的左子樹與右子樹映象對稱,則該樹是對稱的 兩個樹互為映象的...
LeetCode (二叉樹)反轉二叉樹
遞迴交換每乙個節點的左右子樹,重點在於訪問每乙個節點,然後交換左右子樹 definition for a binary tree node.struct treenode struct treenode inverttree struct treenode root 由於至少要講每乙個節點都訪問一次...
LeetCode112 路徑總和(二叉樹和遞迴)
1 給定乙個二叉樹和乙個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。說明 葉子節點是指沒有子節點的節點。給出一棵二叉樹及乙個sum數字,判斷在這棵二叉樹上是否存在一條從根到葉子的路徑,其路徑上的所有節點的和為sum param root param sum ...