[LeetCode] 从LC22谈递归

一种较为好用的递归解题模板

递归模板

1. recursion terminator(递归终结者)

​ 也就是在写递归函数开始,一定要记得先把函数的递归终止条件写上。否则,会造成无限递归(死递归),最后只能把程序杀掉。

2. process logic in current level (处理当前层逻辑)

​ 完成这一层要进行的逻辑代码。

3. drill down(下探到下一层)

​ 需要用参数标记当前是哪一层。并且把参数放进去。

4. reverse the current level status if needed(清理当前层)

​ 如果递归完了,最后一部分这一层有些东西可能要清理。

实战

LeetCode-22
原代码

import java.util.List;
class Solution22 {
    public List<String> generateParenthesis(int n) {
        generate(0, 2 * n, "");     // 自顶向下编程逻辑
        return null;
    }

    private void generate(int level, int max, String s) {
        // terminator
        if (level >= max) {
            System.out.println(s);
            return;
        }

        // process current logic: left, right
        String s1 = s + "(";
        String s2 = s + ")";

        // drill down
        generate(level + 1, max, s1);
        generate(level + 1, max, s2);

        // reverse states
        // s1, s2 are local variables, they will auto clear itself.
        // And we don't change any global variable, so this step can skip
    }
    
    public static void main(String[] args) {
        Solution22 solve = new Solution22();
        System.out.println(solve.generateParenthesis(3));
    }
}

输出结果

((((((
((((()
(((()(
(((())
((()((
((()()
((())(
((()))
(()(((
(()(()
(()()(
(()())
(())((
(())()
(()))(
(())))
()((((
()((()
()(()(
()(())
()()((
()()()
()())(
()()))
())(((
())(()
())()(
())())
()))((
()))()
())))(
()))))
)(((((
)(((()
)((()(
)((())
)(()((
)(()()
)(())(
)(()))
)()(((
)()(()
)()()(
)()())
)())((
)())()
)()))(
)())))
))((((
))((()
))(()(
))(())
))()((
))()()
))())(
))()))
)))(((
)))(()
)))()(
)))())
))))((
))))()
)))))(
))))))
null

加入筛选合法值逻辑,并化简代码

class Solution {
    public List<String> generateParenthesis(int n) {
        ArrayList<String> result = new ArrayList<String>(); // member field
        generate(0, 0, n, "", result);     // 自顶向下编程逻辑
        return result;
    }

    private void generate(int left, int right, int n, String s, ArrayList<String> result) {
        // terminator
        if (left == n && right== n) {
            result.add(s);

            // filter the invalid s
            // method1: invoke a functin to validate the s
            // method2: 直接在括号生成的过程中进行判断. 关键在于:怎样判断一个括号在中间生成的时候怎样是合法的.
            // left 随时可以加, 只要别超标
            // right 必须之前有左括号垫背,  且左个数> 右个数
            // 只要由以上两个条件,就可以保证括号的合法性.
            System.out.println(s);
            return;
        }

        // process current logic: left, right

        // drill down
        if (left < n) {
            generate(left + 1, right, n, s + "(", result);
        }

        if (left > right) {
            generate(left , right + 1, n, s + ")", result);
        }

        // reverse states
        // s1, s2 are local variables, they will auto clear itself.
        // And we don't change any global variable, so this step can skip

    }
    public static void main(String[] args) {
        Solution solve = new Solution();
        System.out.println(solve.generateParenthesis(3));
    }
}

输出结果

((()))
(()())
(())()
()(())
()()()
null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值