《剑指offer》面试题28:字符串的排列

本文重点:如果面试题是按照一定要求摆放若干个数字,可以先求出这些数字的所有排列,然后再一一判断每个排列是不是满足题目给定的要求。

基础题:字符串的排列

题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出字符a、b、c所排列出来的所有字符串abc、acb、bac、bca、cab和cba。

思路:将一个字符串看成两个部分:第一部分为它的第一个字符,第二部分是后面的字符。

  1. 将所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。
  2. 固定第一个字符,求后面所有字符的排列。
public static void permutation(char[] cs, int index) {
    if (index == cs.length) {    // 结束交换,进行输出
        System.out.println(Arrays.toString(cs));
    } else {
        for (int loc = index; loc < cs.length; loc++) {
            char tmp = cs[loc];
            cs[loc] = cs[index];
            cs[index] = tmp;
            permutation(cs, index + 1);
            cs[index] = cs[loc];    // 换回原位置
            cs[loc] = tmp;
        }
    }
}

拓展题目:字符串的组合

题目:如果不是求字符的所有排列,而是求字符的所有组合。例如a、b、c,则它们的组合是a、b、c、ab、ac、ad、bc、abc。

思路:利用Java的位与运算。

知识点: a = 1 << 2;    // a =4 (0000 0001 -> 0000 0100)

public static void comb(char[] cs) {
    int len = cs.length;
    int nbits = 1 << len;
    for (int i=0; i

变形题一:立方体

题目:输入一个含有8个数字的数组,判断有没有可能把这8个数字分别放在正方体的8个顶点上(如下图所示)。使得正方体上三组相对的面上的4个顶点的和都相等。

思路:相当于对8个数字进行排列,然后判断有没有某一个的排列符合条件,即a1+a2+a3+a4 = a5+a6+a7+a8,a1+a3+a5+a7=a2+a4+a6+a8,a1+a2+a5+a6=a3+a4+a7+a8。

注意:对数组中的特殊进行排除,比如<=0.

《剑指offer》面试题28:字符串的排列_第1张图片

public void cuboid(int[] nums, int index) {
	if (index == nums.length && 
		nums[0]+nums[1]+nums[2]+nums[3] == nums[4]+nums[5]+nums[6]+nums[7]
		&& nums[0]+nums[2]+nums[4]+nums[6] == nums[1]+nums[3]+nums[5]+nums[7]
		&& nums[0]+nums[1]+nums[4]+nums[5] == nums[2]+nums[3]+nums[6]+nums[7]) {
		System.out.println(Arrays.toString(nums));
		return ;
	} else {
		for (int loc=index; loc

变形题二:八皇后

题目:8皇后的任意两个不能在同一行,同一列,同一条对角线。

思路:定义一个数组,第i个数字表示位于第i行的皇后的列号。首先全排列,只需要判断每一个排列对应的8个皇后是不是在同一条对角线上,也就是数组的任意两个下标i和j,是不是i - j == ColumnIndex[i] - ColumnIndex[j]或者j - i == ColumnIndex[i] - ColumnIndex[j]。

注释:下面代码可以实现n皇后。

public void queen8(int n) {
	int[] res = new int[n];
	for (int i=0; i

 

你可能感兴趣的:(java,剑指offer)