leetcode刷題(六)路徑總和I、II、III
阿新 • • 發佈:2019-02-02
(一)112題
題目地址:https://leetcode-cn.com/problems/path-sum/description/
題目描述:給定一個二叉樹和一個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。
解決方案:
/** * 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: bool hasPathSum(TreeNode* root, int sum) { if(root==NULL){ return false; } int t=sum-root->val; if(root->left==NULL&& root->right==NULL){ return t==0 ? true :false; } //遞迴呼叫函式,分別判斷根結點的左節點和右節點 return hasPathSum(root->left,t) || hasPathSum(root->right,t); } };
備註:這裡的解決方案,採用遞迴呼叫的形式,每次開始都從sum中減去到根結點的值,然後再判斷當前的節點作為根結點到其左孩子和右孩子的距離與t的關係。
效能分析:
大神的寫法就是厲害,這個故事告訴我們遞迴呼叫效能真的很優,下次直覺想到迴圈呼叫的時候,可以考慮一下遞迴呼叫
(二)113題
題目地址:https://leetcode-cn.com/problems/path-sum-ii/description/
題目描述:給定一個二叉樹和一個目標和,找到所有從根節點到葉子節點路徑總和等於給定目標和的路徑。
解決方案:
class Solution { public: vector<vector<int>> pathSum(TreeNode* root, int sum) { vector<vector<int>> res; vector<int> out; worker(root,sum,out,res); return res; } //遞迴呼叫,實現對節點的路徑總和判斷和路徑記錄功能 void worker(TreeNode* node,int sum,vector<int>& out,vector<vector<int>>& res){ if(!node) return; out.push_back(node->val); if(sum==node->val && !node->left && !node->right) { res.push_back(out); } worker(node->left,sum-node->val,out,res); worker(node->right,sum-node->val,out,res); out.pop_back(); } };
備註:同樣使用遞迴呼叫,但由於程式碼較長,多寫了一個函式,函式實現對二叉樹中不同節點的處理進行記錄。其中res為滿足要求或者等待判斷的當前路徑,out是在新加入的路徑不符合要求時,退出的節點。
效能分析:
說明:這個故事告訴我們遇到不會的問題,參考學習大神的程式碼沒有問題,哪怕學習思路漲漲見識也好
(三)437題
給定一個二叉樹,它的每個結點都存放著一個整數值。
找出路徑和等於給定數值的路徑總數。
路徑不需要從根節點開始,也不需要在葉子節點結束,但是路徑方向必須是向下的(只能從父節點到子節點)。
二叉樹不超過1000個節點,且節點數值範圍是 [-1000000,1000000] 的整數。
解決方案:
/** * 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: int pathSum(TreeNode* root, int sum) { int cnt = 0; dfs1(root, sum, cnt); return cnt; } //dfs用來計算二叉樹中符合要求的路徑的長度 void dfs(TreeNode* root, int sum, int& cnt){ if(root == NULL) return; //累計符合要求的路徑個數 if(root->val == sum) cnt++; dfs(root->left, sum-root->val, cnt); dfs(root->right, sum-root->val, cnt); } //用來遍歷每個節點 void dfs1(TreeNode* root, int sum, int& cnt){ if(root == NULL) return; dfs(root, sum, cnt); dfs1(root->left, sum, cnt); dfs1(root->right, sum, cnt); } };
分析:較II題多了一個遍歷二叉樹節點的函式
效能分析:
分析:看了三篇大神寫的程式碼,發現實現相同功能的不同寫法,其實可以相互借鑑一下