因为最近无次序刷力扣又刷到了当时的递归,每次看递归的代码都会有一定的理解,但隔了一段时间又没啥思路。
先来看一下递归的模版结构:
// JavaScript
function recur(level, param) {
// 递归的终止条件
if (level > MAX_LEVEL) {
return;
}
// 处理当前层逻辑
process(level, param);
// 下探到下一层
recur( level: level + 1, newParam);
// 清理当前层
}
因为时常会陷入递归中使得思路全无,注意我们只要干这一层要做的事情
我们用几个栗子:
// 链表反转
var reverseList = function(head) {
// 迭代
// let prev = null;
// let cur = head;
// let next = head;
// while(cur){
// next = cur.next;
// cur.next = prev
// prev = cur;
// cur = next
// }
// return prev;
// 递归
// 结束条件
if(head == null || head.next == null) return head
// 递归进入下一层
let last = reverseList(head.next)
// 处理当前层的逻辑
head.next.next = head
head.next = null
//返回当前层的结果
return last
};
// 寻找最近公共祖先
// p,q均存在于树中
var lowestCommonAncestor = function(root, p, q) {
// 当前结束条件
if(root == null || root == p || root == q) return root
// 递归进入下一层,分别寻找到左右子树的最近公共祖先
let l = lowestCommonAncestor(root.left,p,q)
let r = lowestCommonAncestor(root.right,p,q)
// 如果左子树中存在p,q节点的公共祖先否,不存在则直接返回右子树
if(l == null) return r
// 再判断右子树是否存在p,q节点的公共祖先否,再不存在直接返回根结点本身
if(r == null) return l
//如果都不存在,那就是根结点本身
return root
};
// 这题我在写的时候又有点糊涂了......
// 要理解l,r节点的真正意义
// 递增顺序搜索树
var increasingBST = function(root) {
let cur = new TreeNode(null)
let ans = cur
// recurise again
const inOrder = (node) =>{
// 判断返回条件
if(node){
// 先处理左子树
inOrder(node.left)
// 当前层的操作处理
node.left = null
cur.right = node
cur = node
// 再处理右子树
inOrder(node.right)
}
}
inOrder(root)
return ans.right
};