不使用递归求全排列和组合数

简介:

同学遇到的面试问题,大意是M台机器放在N个房间,不使用递归求打印所有情况

解题思路:情况共计N**M种。开始想将所有情况放入数组,填充好数组再逐个打印。随后发现按照填充的思路,不使用大数组也可以实现。思路是加入M=N=3,则27种情况,记i0...i26。0...M个数,0放入i0[0],i1[1],i2[2],i3[0],i4[1],i5[2]...,1放入i0[,i1,i2,

房间0 房间1 房间2
0 1 2
1 2 0
1 2 0
0 2 1
2 0 1
2 1 0
0 2 1
2 0 1
2 0 1
0 1 2
1 0 2
1 2 0
0 1 2
0 1 2
1 2 0
0 2 1
0 2 1
2 0 1

/*  
 * 非递归打印全排列。 
 */  
public class Permutations {  

    static void swap(char[] s, int i, int j) {  
        char c = s[i];  
        s[i] = s[j];  
        s[j] = c;  
    }  

    static void fullPermutation(char[] s) {  
        for (int i = 0; i < s.length; i++) {  
            for (int j = 1; j < s.length; j++) {  
                swap(s, j, j - 1);  
                System.out.println(s);  
            }  
        }  
    }  

    public static void main(String[] args) {  
        fullPermutation("1234".toCharArray());  
    }  
}  

类似的问题非递归打印组合数。例如Cmn。建立长度为m的数组,前n个置为1。从左到右扫描数组元素值的10组合,找到第一个10组合后将其变为01并将其左边的1移动到最左端。


/* 
 * 非递归打印组合数 
 */  
public class Combinations {  

    static void swap(int[] a, int i, int j) {  
        int t = a[i];  
        a[i] = a[j];  
        a[j] = t;  
    }  

    static void print(char[] s, int[] t) {  
        for (int i = 0; i < t.length; i++) {  
            if (t[i] == 1)  
                System.out.print(s[i] + " ");  
        }  
        System.out.println();  
    }  

    public static void combinations(char[] s, int n) {  
        int[] t = new int[s.length];  
        int m = t.length;  
        for (int i = 0; i < n; i++)  
            t[i] = 1;  
        print(s, t);  
        while (true) {  
            int i;  
            for (i = 1; i < m; i++) {  
                if (t[i] == 0 && t[i - 1] == 1) {  
                    swap(t, i, i - 1);  
                    int p = -1;  
                    for (int j = 0; j < i - 1; j++) {  
                        if (t[j] == 1) {  
                            swap(t, ++p, j);  
                        }  
                    }  
                    print(s, t);  
                    break;  
                }  
            }  
            if (i == m) {  
                return;  
            }  
        }  
    }  

    public static void main(String[] args) {  
        char[] s = "12345".toCharArray();  
        combinations(s, 2);  
    }  
}  


目录
相关文章
子数组问题总结(很多子数组求法类似,暴力求法)
子数组问题总结(很多子数组求法类似,暴力求法)
子数组问题总结(很多子数组求法类似,暴力求法)
利用递归求斐波纳契数列的和
递归的方法更加简单,更容易理解
|
算法
【递归与递推 3】AcWing 717. 简单斐波那契(求解斐波那契数列的若干方法)
【递归与递推 3】AcWing 717. 简单斐波那契(求解斐波那契数列的若干方法)
【递归与递推 3】AcWing 717. 简单斐波那契(求解斐波那契数列的若干方法)
汉诺塔问题, 用递归方法求集合中的中位数
汉诺塔问题, 用递归方法求集合中的中位数
|
机器学习/深度学习 人工智能 算法
『递归』汉诺塔和全排列
使用递归编写一个程序实现汉诺塔问题,要求在输入圆盘数量之后,输出圆盘的移动步骤,输出格式示例如下: 第1步:1号盘从A柱移至B柱第2步:2号盘从A柱移至C柱
216 0
|
存储 C语言
字符串逆序不一样的解法(递归)
字符串逆序不一样的解法(递归)
101 0
字符串逆序不一样的解法(递归)
【递归】斐波那契数列第n个数
递归、递推计算斐波那契数列第n项的值: 1 #include 2 long long fact(int n); //【递推】计算波那契数列第n个数 3 long long fact2(int n);//【递归】 4 int main(int argc, char *arg...
1101 1