劍指 Offer 34. 二叉樹中和為某一值的路徑 - 8月16日
阿新 • • 發佈:2020-08-16
題目
劍指 Offer 34. 二叉樹中和為某一值的路徑
我的思路
我的思路與官方題解有出入,不夠簡練。
先概述一下我的做法:先序遞迴遍歷樹,引數中除了傳遞當前節點外還包括當前路徑和。因為遞迴函式的呼叫棧隱式儲存了路徑資訊,所以當找到滿足要求的路徑並返回時,可以藉助遞迴函式的返回值傳遞是否找到了滿足要求的路徑,並且是哪些路徑的資訊。這個返回引數是一個列表,元素是滿足條件的路徑。如果當前節點為葉子節點並且路徑和滿足要求,那麼為該列表新增一個項,並把葉子節點val加入新的一項;如果不滿足要求,那麼返回一個空的列表;遞迴函式在返回前還需要處理本層呼叫的所有遞迴返回值,把本節點的val新增到已存在的路徑中去。
官方題解的思路更簡潔,概述如下:
用一個全域性變數列表儲存當前已有的滿足條件的路徑,一個全域性變數向量來儲存當前路徑。在遍歷樹的過程中,隨時通過pop_back和push_back,來更新當前路徑。並在訪問葉子節點時判斷路徑和是否滿足要求。如果滿足要求,把當前路徑加入到全域性變數結果列表中即可。實現見拓展學習
兩種思路複雜度相同
時間複雜度 O(N) : N 為二叉樹的節點數,先序遍歷需要遍歷所有節點。
空間複雜度 O(N) : 最差情況下,即樹退化為連結串列時,path 儲存所有樹節點,使用 O(N)額外空間。
我的實現
class Solution { public: vector<vector<int>> PATHS; int SUM; int visit(TreeNode *root,int preSum){ if(root!=NULL){ if(preSum+root->val==SUM){ int no = PATHS.size(); vector<int> temp; PATHS.push_back(temp); return no; }return -1; }return -1; } vector<int> search(TreeNode *root,int preSum){ vector<int> paths; if(root==NULL)return paths; if(root!=NULL){ if(root->left==NULL&&root->right==NULL) paths.push_back(visit(root,preSum)); vector<int> temp1 = search(root->left,preSum+root->val); paths.insert(paths.end(),temp1.begin(),temp1.end()); temp1 = search(root->right,preSum+root->val); paths.insert(paths.end(),temp1.begin(),temp1.end()); } for(auto it:paths){ if(it>=0){ PATHS[it].push_back(root->val); } } vector<int>::iterator iter = paths.begin(); while(iter!=paths.end()){ if(*iter <0){ paths.erase(iter); }else{ iter++;} } return paths; } vector<vector<int>> pathSum(TreeNode* root, int sum) { SUM = sum; search(root,0); vector<vector<int>> result; for(auto it:PATHS){ vector<int> temp; for(vector<int>::iterator it2 = it.end();it2!=it.begin();){ it2--; temp.push_back(*it2); } result.push_back(temp); } return result; } };
拓展學習
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int> > res; vector<int> path; //回溯演算法 void dfs(TreeNode* root,int sum){ if(root==nullptr) return; //先序遍歷 path.push_back(root->val); sum -= root->val; if(sum == 0 && root->left ==nullptr && root->right == nullptr){ res.push_back(path); } dfs(root->left,sum); dfs(root->right,sum); path.pop_back();//最後回溯 } vector<vector<int>> pathSum(TreeNode* root, int sum) { dfs(root,sum); return res; } }; 作者:ni-hen-you-xiu-2 連結:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/solution/c-xian-xu-jia-hui-su-by-ni-hen-you-xiu-2/ 來源:力扣(LeetCode) 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。