[leetcode] Permutations

Given a collection of numbers, return all possible permutations.

For example,
[1,2,3]have the following permutations:
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], and[3,2,1].

https://oj.leetcode.com/problems/permutations/

思路:生成permutation,这题假设没有重复元素,递归求解,每一次在cur位置填元素,添之前判断钙元素是否已经用过,没用过继续下去,指导cur==n。

public class Solution {
	public ArrayList<ArrayList<Integer>> permute(int[] num) {
		if (num == null)
			return null;
		ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
		if (num.length == 0)
			return res;
		int[] permSeq = new int[num.length];
		perm(num.length, 0, num, permSeq, res);
		return res;
	}

	private void perm(int n, int cur, int[] num, int[] perm,
			ArrayList<ArrayList<Integer>> res) {
		if (cur == n) {
			ArrayList<Integer> tmp = new ArrayList<Integer>();
			for (int i = 0; i < perm.length; i++) {
				tmp.add(perm[i]);
			}
			res.add(tmp);
		} else {
			int i;
			for (i = 0; i < num.length; i++) {
				int j;
				boolean ok = true;
				for (j = cur - 1; j >= 0; j--) {
					if (perm[j] == num[i])
						ok = false;
				}
				if (ok) {
					perm[cur] = num[i];
					perm(n, cur + 1, num, perm, res);
				}
			}
		}

	}

	public static void main(String[] args) {
		System.out.println(new Solution().permute(new int[] { 1, 2, 3,4 }));
	}
}

 

第二遍记录:

注意java的写法和c的写法在语法上的区别。

注意 ok java用boolean。

java版本不去要cur变量,而是利用tmp.length代表当前已经填好的元素。

 

java:

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public List<List<Integer>> permute(int[] num) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if (num == null || num.length == 0)
            return res;
        List<Integer> tmp = new ArrayList<Integer>();
        permuteHelper(res, tmp, num);
        return res;

    }

    private void permuteHelper(List<List<Integer>> res, List<Integer> tmp, int[] num) {
        if (tmp.size() == num.length) {
            res.add(new ArrayList<>(tmp));
            return;
        } else {
            for (int i = 0; i < num.length; i++) {
                boolean ok = true;
                for (int j = 0; j < tmp.size(); j++) {
                    if (tmp.get(j) == num[i]) {
                        ok = false;
                        break;
                    }
                }

                if (ok) {
                    tmp.add(num[i]);
                    permuteHelper(res, tmp, num);
                    tmp.remove(tmp.size() - 1);
                }
            }
        }
    }

    public static void main(String[] args) {
        System.out.println(new Solution().permute(new int[] { 1, 2, 3, 4 }));
    }
}

 

参考C语言(并且支持集合有重复元素)

#include<cstdio>
#include<cstdlib>
#define MAXN 10
 
int cmp(const void*a, const void* b) {
    return *(int*) a - *(int*) b;
}
 
void print_permutation(int n, int P[], int A[], int cur) {
    if (cur == n) {
        for (int i = 0; i < n; i++)
            printf("%d ", A[i]);
        putchar('\n');
    } else
        for (int i = 0; i < n; i++)
            if (!i || P[i] != P[i - 1]) {
                //if的意思: 对于重复元素(排序后已经挨在一起),只试它们中的第一个,其余跳过
                //P[0]是必然要试的:若有多个等于P[0]的值,P[0]必为第一个(0-1=-1不在数组下表范围内);若只有一个,更理所当然地要试P[0]。(!i即为i==0)
                int c1 = 0, c2 = 0;
                for (int j = 0; j < cur; j++)
                    if (A[j] == P[i])
                        c1++;
                for (int j = 0; j < n; j++)
                    if (P[j] == P[i])
                        c2++;
                if (c1 < c2) {
                    A[cur] = P[i];
                    print_permutation(n, P, A, cur + 1);
                }
            }
}
int main() {
    int n, A[MAXN], P[MAXN];
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%d", &P[i]);
    qsort(P, n, sizeof(int), cmp);
 
    print_permutation(n, P, A, 0);
    return 0;
}

 

第四遍记录: 又笔误,j小于tmp.size()而不是i!

for(int j=0;j<tmp.size();j++){

  ...

 

posted @ 2014-06-26 19:59  jdflyfly  阅读(166)  评论(0编辑  收藏  举报