递归基础
递归(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 题解
938. Range Sum of BST 题解
779. K-th Symbol in Grammar 题解
894. All Possible Full Binary Trees 题解
776. Split BST 题解
247. Strobogrammatic Number II 题解
248. Strobogrammatic Number III 题解
698. Partition to K Equal Sum Subsets 题解
761. Special Binary String 题解
有时候递归函数的返回值即是所求,有时候我们利用递归函数的返回值作为中间结果的一部分,例如 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题:
687. Longest Univalue Path 题解
543. Diameter of Binary Tree 题解
783. Minimum Distance Between BST Nodes 题解
时间复杂度
如何计算递归算法的时间复杂度,详见:
Time complexity of recursive functions [Master theorem]
【算法16】递归算法的时间复杂度终结篇