求所有子序列
字符串:
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)