1. 程式人生 > 實用技巧 >劍指 Offer 34. 二叉樹中和為某一值的路徑 - 8月16日

劍指 Offer 34. 二叉樹中和為某一值的路徑 - 8月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)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。