因為題目要求路徑是從上到下的,所以最好采用前序遍歷。這樣可以保證按從上到下的順序將節點的值存入一個路徑數組中。另外,此題還有一個難點就是如何求得所有路徑。為了解決這個問題,我們需要用到回溯。回溯和遞歸不分家,每遞歸一次,我們就回溯一次,這樣就能保證回到原來的位置,進而遞歸我們沒有走過的節點,得到新的路徑。大體思路就是這樣,大家可以結合我的代碼以及注釋理解這道題目。另外,如果大家的二叉樹遍歷還不熟悉的話,最好先去看一下我的關于二叉樹遍歷的博客,再來看這道題,否則肯定會比較懵逼。
代碼及注釋如下:
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:
//參數有三個,一個為工作指針,一個為記錄路徑的數組,一個為儲存最后結果的字符串數組
//注意千萬不要將返回值設置為字符串數組,因為我們不需要每次遞歸都返回字符串,這跟之前每次遞歸返回數值不一樣,我們這里將存儲結果的容器放在參數引用就可以了void travel(TreeNode* cur,vector<int>& path,vector<string>& result){//這種記錄路徑的題目的遞歸終止條件不是遍歷到空節點,而是遍歷到葉子結點//為了確保將葉子結點也存入路徑數組,需要在終止條件之前就push,否則會遺漏path.push_back(cur -> val);//處理邏輯(中)//終止條件:遍歷到葉子節點if(cur -> left == NULL && cur -> right == NULL){//將數字轉化為題目所規定的字符串string spath;for(int i = 0;i < path.size() - 1;i++){spath += to_string(path[i]);spath += "->";}spath += to_string(path[path.size() - 1]);result.push_back(spath);return;}if (cur->left) { //遞歸左孩子 travel(cur->left, path, result);path.pop_back(); // 回溯}if (cur->right) { // 遞歸右孩子travel(cur->right, path, result);path.pop_back(); // 回溯}}vector<string> binaryTreePaths(TreeNode* root) {vector<int> path;vector<string> result;if(root == NULL) return result;travel(root,path,result);return result;}
};