经典字符串算法题(Java实现)

文章目录

  • 字符数组一定位数的所有排列组合
  • 字符串的全排列
  • 字符串的所有组合


字符数组一定位数的所有排列组合

要求:
字符串的所有排列组合

思路:
函数传入参:每一位可选字符cs数组,当前位置cur,输出的位数,前面的循环所得的子输出str

代码:

public class Main {
    public static void main(String [] args) {
        char[] cs = {'a','b'};
        show(cs,0,3,"");
    }
    //len:位数
    static private void show(char[] cs,int cur,int len,String str){
        if (cur==len){
            System.out.println(str);
            return;
        }
        for (int i = 0;i<cs.length;i++){
            String s = str+cs[i];
            show(cs,cur+1,len,s);
        }
    }
}

经典字符串算法题(Java实现)_第1张图片


字符串的全排列

要求:
求字符串的全排列

思路:

运用递归的思想,需要全排列的字符串是一个字符串,那么它的子字符串也是一个字符串,要全排列该字符串,可以先全排列它的子字符串,直到子字符串长度为1;

先固定字符串第p个位置的字符,然后全排列p+1位置到末尾的子字符串,然后更换p位置的字符,直到每个字符都在p位置出现一次。
接着p++,p位置往后移动一位,针对新的p位置重复上述操作,直至p指向最后一个字符,这个时候输出当前的字符顺序。

(代码有详细注释,好好体会)

代码:

public class Main {

    public static void main(String[] args){
        permutation("abc".toCharArray(),0);
    }
    //全排列数组p位置后面的字符数组
     private static void permutation(char[] arr,int p) {
        //当p位置指向字符串最后一个位置时,输出当前排列的字符数组
        if(p==arr.length-1) {
            System.out.println(String.valueOf(arr));
            return;
        }
        //固定p位置的字符,p后面的字符依次和p交换
        for(int i=p;i<arr.length;i++) {
            swap(arr,i,p);//将第一个字符与后面的字符交换
            permutation(arr,p+1);//对p位置后面的字符进行全排列,递归
            swap(arr,i,p);//再将之前交换的字符交换回来,以便第一个字符再与其他字符交换
        }
    }

    //数组字符交换函数
    private static void swap(char[] charArray,int i,int j)
    {
        char temp = charArray[i];
        charArray[i] = charArray[j];
        charArray[j] = temp;
    }
}

经典字符串算法题(Java实现)_第2张图片
补充:

字符串有重复字符:

解决:

1 直接存到set里面

2 进行交换递归时先判断前面是不是有重复的字符

public class Main {

    public static void main(String[] args){
        permutation("abba".toCharArray(),0);
    }
    //全排列数组p位置后面的字符数组
    private static void permutation(char[] arr, int p) {
        //当p位置指向字符串最后一个位置时,输出当前排列的字符数组
        if(p==arr.length-1) {
            System.out.println(String.valueOf(arr));
            return;
        }
        //固定p位置的字符,p后面的字符依次和p交换
        for(int i=p;i<arr.length;i++) {
            if (check(arr,i,p)) continue;
            swap(arr, i, p);//将第一个字符与后面的字符交换
            permutation(arr, p + 1);//对p位置后面的字符进行全排列,递归
            swap(arr, i, p);//再将之前交换的字符交换回来,以便第一个字符再与其他字符交换
        }
    }

    private static boolean check(char[] arr, int index ,int p) {
        for (int i = p;i<index;i++){
            if (arr[i]==arr[index]) return true;
        }
        return false;
    }

    //数组字符交换函数
    private static void swap(char[] charArray,int i,int j)
    {
        char temp = charArray[i];
        charArray[i] = charArray[j];
        charArray[j] = temp;
    }
}

字符串的全排列,按照字典序输出:
1 把所有字符串存到有序的TreeSet里面
2 Collections.sort()


字符串的所有组合

要求:
求字符串的全部组合

方法一:

思路:

最容易想到的方式是递归,遍历字符串,每个字符串只能取或不取。

若取该字符,就把它放到结果字符串中,遍历完毕后,输出结果字符串。

代码:

public class Main {
    public static void main(String [] args) {
        String s="ABC";
        char[] c=s.toCharArray();
        StringBuffer sb=new StringBuffer();
        //取组合的长度
        for(int i=1;i<=c.length;i++) {
            permutation(c,0,i,sb);
        }
    }
    /**
     * @Description:
     * @Param: c:需排列的字符串 p:当前索引字符串位置 len:取组合的长度 sb:保存字符串
     * @return:
     * @Author: Zhuolinbo
     * @date: 2019/8/6 11:07
    */
    private static void permutation(char[] c,int p,int len, StringBuffer sb) {
        if(len==0) {//当都选择结束时打印sb内容
            System.out.println(sb+" ");
            return;
        }

        if(p==c.length) return;

        sb.append(c[p]);//取
        permutation(c,p+1,len-1,sb);// 剩下的里面选len-1个

        sb.deleteCharAt(sb.length()-1);//不取
        permutation(c,p+1,len,sb);//剩下的里面选len个
    }
}

经典字符串算法题(Java实现)_第3张图片
方法二:

思路:
把每个字符用一个数位表示,用一个01字符串(或者数组)来表示每一个可能的结果。
1代表取该位置代表的字符,0代表不取。
举例,如求abc的所有组合:a,b,c,ab,ac,bc,abc
a:100
b:010
c:001
ab:110
ac:101
bc:011
abc:111
这些10字符串实际上就是,一个个三位数,每位可能的取值为0或1。
利用第一道题的思想,可以很容易求出这些三位数。

代码:

public class Main {

    public static void main(String [] args) {
        String str = "abc";
        show(0,3,"",str);
    }
    //len:位数
    static private void show(int cur,int len,String str,String str1){
        if (cur==len){
            char[] c = str.toCharArray();
            for (int i = 0;i<c.length;i++){
                if (c[i]=='1') System.out.print(str1.charAt(i));
            }
            System.out.println();
            return;
        }
        for (int i = 0;i<2;i++){
            String s = str+i;
            show(cur+1,len,s,str1);
        }
    }
}


你可能感兴趣的:(算法)