algorithm of combination

刷leetcode遇到了 不擅长的排列组合问题 看了两道以后觉得有必要总结一下。

遇到combination问题 首先考虑recursion也就是回溯的思想

第一题是用九键打字可能的字符串序列 也就是若干个集合的 有序全排列。

eg: {a,b,c} 笛卡尔积{d,e,f}

核心函数:相当于一个DFS,深度优先遍历。

static private void combination(List<List<String>> lists,List<String> result,int depth,String cur)
    {
        if(depth==lists.size())
        {
            result.add(cur);
            return;
        }
        for(int i=0;i<lists.get(depth).size();++i)
            combination(lists,result,depth+1,cur+lists.get(depth).get(i));
    }

从集合list中第一个开始,depth表示集合索引,i是集合内部元素索引。

 

 

 

 

第二题是给出n,写出所有可能的合法的n对括号序列。

eg: n=2  就是 {()(),(())} 这形状哈哈哈我邪恶了

核心函数: lal 已经添加的左括号数 ral已经添加的右括号数

 private static void combination(int n, List<String> result,int lal,int ral,String str) {
        if(str.length()==2*n)
        {
            result.add(str);
            return;
        }
        if(lal<n){
            combination(n,result,lal+1,ral,str+"(");
        }
        if(lal>ral)
        {
            combination(n,result,lal,ral+1,str+")");
        }

    }

recursion的逻辑有点绕 不太好正向推导,但是一旦有思路就水到渠成。这里 就是一开始在n限制内先加左括号,然后根据合法判断加入右括号,这样结果完全。我最开始在想的时候合法性判断这里很容易想到,但是纠结在怎么才能让程序自己找到所有可能,看了一眼答案恍然大悟,只要先插入左括号递归一次,接着判断是否要插入右括号,再递归,自然每种情况都会考虑到。

此外还遇到了一个问题:最初我的函数是这么写的:

        if(lal<n){
            str+="(";
            combination(n,result,lal+1,ral,str);
        }
        if(lal>ral)
        {
            str+=")";
            combination(n,result,lal,ral+1,str);
        }

这样结果是错误的:例如N=3:

Output

["((()))","((()()","((()()","(()(()","(()(()"]

Expected

["((()))","(()())","(())()","()(())","()()()"]

造成这种错误的原因是,在第lal<n的if语句中修改了str,传入第一个递归中之后,str=( 这一改变也传入了下面的lal>ral的if语句。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值