遞歸基礎
遞歸(Recursion)是常見常用的算法,是DFS、分治法、回溯、二叉樹遍歷等方法的基礎,典型的應用遞歸的問題有求階乘、漢諾塔、斐波那契數列等,可視化過程。
應用遞歸算法一般分三步,一是定義基礎條件(base case),二是改變狀態、向基礎條件轉移,三是遞歸地調用自身。例如 LeetCode題目 1137. N-th Tribonacci Number:
// 1137. N-th Tribonacci Number
private:
//基礎條件 vector<int> nums={0,1,1}; int maxN=2; public: int tribonacci(int n) { if(n<=maxN) return nums[n%3];
//改變狀態、遞歸地調用自身 nums[n%3]=tribonacci(n-3)+tribonacci(n-2)+tribonacci(n-1); maxN=n; return nums[n%3]; }
相關LeetCode題:
1137. N-th Tribonacci Number 題解
779. K-th Symbol in Grammar 題解
894. All Possible Full Binary Trees 題解
247. Strobogrammatic Number II 題解
248. Strobogrammatic Number III 題解
698. Partition to K Equal Sum Subsets 題解
有時候遞歸函數的返回值即是所求,有時候我們利用遞歸函數的返回值作為中間結果的一部分,例如 LeetCode題目 687. Longest Univalue Path:
// 687. Longest Univalue Path private: int helper(TreeNode* root,int& res){ int l=root->left?helper(root->left,res):0; int r=root->right?helper(root->right,res):0; int resl=root->left&&root->left->val==root->val?l+1:0; int resr=root->right&&root->right->val==root->val?r+1:0; res=max(res,resl+resr); return max(resl,resr); } public: int longestUnivaluePath(TreeNode* root) { int res=0; if(root) helper(root,res); return res; }
以上遞歸函數返回 “子樹最長唯一值節點長度” ,而最終所求由左子樹最長、右子樹最長、當前root節點決定。留意這里與函數返回即為所求的差別。
相關LeetCode題:
543. Diameter of Binary Tree 題解
783. Minimum Distance Between BST Nodes 題解
時間復雜度
如何計算遞歸算法的時間復雜度,詳見:
Time complexity of recursive functions [Master theorem]