java 常用模板函数

求所有子序列

字符串:

public class Main {
    public static void main(String[] args) {
        List<String> strs=getAllSubstrings("abbc","");
        System.out.println(strs);
    }
    private static List<String> getAllSubstrings(String str, String substr) {//得到所有子序列
        List<String> subs = new ArrayList();
        if (substr.length() != 0) {
            subs.add(substr);
        } 
        for (int i = 0; i < str.length(); i++) {
                List<String> results = getAllSubstrings(str.substring(i+1), substr+str.charAt(i));
                for (String re : results) {
                    subs.add(re);
                }
        }

        return subs;
    }

}

可能有重复,如果不想重复,可用 Set 存
输出:

[a, ab, abb, abbc, abc, ab, abc, ac, b, bb, bbc, bc, b, bc, c]

数组:

public class Main {
    public static void main(String[] args) {
        List<Integer> numslist=new ArrayList<>();
        numslist.add(11);
        numslist.add(2);
        numslist.add(4);
        List<ArrayList<Integer>> strs=getAllSubArray(numslist,new ArrayList());
        System.out.println(strs);
    }
    private static List<ArrayList<Integer>> getAllSubArray(List<Integer> nums, ArrayList<Integer> subnums) {
        List<ArrayList<Integer>> subs=new ArrayList();
        if(subnums.size()!=0){
            subs.add((ArrayList<Integer>) subnums.clone());//此处要克隆,不然后面subnums改变了,subs里的也跟着改变
        }
        for(int i=0;i<nums.size();i++){
            subnums.add(nums.get(i));
            List<ArrayList<Integer>> results=getAllSubArray(nums.subList(i+1, nums.size()),subnums);
            for(ArrayList al:results){
                subs.add(al);
            }
            subnums.remove(nums.get(i));
        }
        return subs;
    }

}

可能有重复,如果不想重复,可用 Set 存
输出:

[[11], [11, 2], [11, 2, 4], [11, 4], [2], [2, 4], [4]]

求所有排列

public class Main {
    public static void main(String[] args) {
        String s = "abbc";
        List<String> list=listAll(Arrays.asList(s.split("")),"");
        System.out.println(list);
    }
    private static List<String> listAll(List<String> candidate, String prefix) {
        List<String> list=new ArrayList<String>();
        if(candidate.isEmpty()) {
            list.add(prefix);
        }else {
            StringBuilder sb=new StringBuilder();//记录前面已经出现的字符
            for (int i = 0; i < candidate.size(); i++) {
                if(sb.indexOf(candidate.get(i))!=-1){//如果是重复字符就不递归
                    continue;
                }
                List temp = new LinkedList(candidate);//为了方便提取后删除每个元素
                List<String> results=listAll(temp, prefix + temp.remove(i));
                for(String s:results){
                    list.add(s);
                }
                sb.append(candidate.get(i));
            }
        }
        return list;
    }

}
[abbc, abcb, acbb, babc, bacb, bbac, bbca, bcab, bcba, cabb, cbab, cbba]

数组:

public class Main {

    public static void main(String[] args) {
        List<Integer> numslist=new ArrayList<>();
        numslist.add(11);
        numslist.add(2);
        numslist.add(4);
        List<List<Integer>> strs=listAll(numslist,new ArrayList());
        System.out.println(strs);
    }

    private static List<List<Integer>> listAll(List<Integer> candidate, ArrayList<Integer> prefix) {
        List<List<Integer>> list=new ArrayList<>();
        if(candidate.isEmpty()){
            list.add((ArrayList<Integer>)  prefix.clone());
        }else{
            for(int i=0;i<candidate.size();i++){
                List tempcandidate=new LinkedList(candidate);
                ArrayList tempprefix=new ArrayList(prefix);
                tempprefix.add((Integer) tempcandidate.remove(i));
                List<List<Integer>> results=listAll(tempcandidate,tempprefix);
                for(List<Integer> thislist:results){
                    list.add(thislist);
                }
            }
        }
        return list;
    }

}

[[11, 2, 4], [11, 4, 2], [2, 11, 4], [2, 4, 11], [4, 11, 2], [4, 2, 11]]

判断是否是回文

private static boolean check(String s) {
        int i=0,j=s.length()-1;
        while(i<j) {
            if(s.charAt(i)!=s.charAt(j)) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }

求两个数的最大公约数
辗转相除法
当两个数都较大时,采用辗转相除法比较方便.其方法是:
  以小数除大数,如果能整除,那么小数就是所求的最大公约数.否则就用余数来除刚才的除数;再用这新除法的余数去除刚才的余数.依此类推,直到一个除法能够整除,这时作为除数的数就是所求的最大公约数.
  例如:求4453和5767的最大公约数时,可作如下除法.
  5767÷4453=1余1314
  4453÷1314=3余511
  1314÷511=2余292
  511÷292=1余219
  292÷219=1余73
  219÷73=3
  于是得知,5767和4453的最大公约数是73

public static int gcdfunc(int m,int n){  
        if(m<n){  
            int k=m;  
            m=n;  
            n=k;  
        }  
        if(m%n!=0){  
            int temp=m%n;  
            return gcdfunc(n,temp);  
        }else  
            return n;  
  }  

java 求两个数的最大公约数,可以尝试用
BigInteger tmp1=new BigInteger(Integer.toString(i));
BigInteger tmp2 = new BigInteger(Integer.toString(j));
tmp1.gcd(tmp2).intValue()
可能更快

最小公倍数:LCM(a,b)=a*b / GCD(a,b)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值