可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have an [] of integers 1<=N<=100 , How can i get permutations of this array? -> Array may contain duplicates, so resulting set of permutations can be duplicate, so need to get all non-duplicate permutations.
- I've found lot of snippets which would convert the int[] to string and perform permutations and printout, but as i hv here is integers of range 1<=N<=100, so converting them into string would spoil integer.
- I can get all permutations with duplicates including, for final set of permutations where duplicates are removed have to check
with each other to remove a duplicate or so, it so heavy process.
Is there any simpler way?
For example : 123 would give
231 321 312 132 213 123
Similarly for 112 program would give
121 211 211 121 112 112
So, for n-set of elements , permutations will be of n! With duplicates in elements, would decrease tht, I'm asking how can i remove those duplicate sets. (duplicate set of permutation arr[])
回答1:
If it is acceptable to first sort the elements lexically, then you can your lexical permutation. Including an algorithm which does it for an array of int, easily modifiable to strings.
public static boolean permuteLexically(int[] data) { int k = data.length - 2; while (data[k] >= data[k + 1]) { k--; if (k < 0) { return false; } } int l = data.length - 1; while (data[k] >= data[l]) { l--; } swap(data, k, l); int length = data.length - (k + 1); for (int i = 0; i < length / 2; i++) { swap(data, k + 1 + i, data.length - i - 1); } return true; }
Example of how to use it
public static void main(String[] args) { int[] data = { 1,2,3 }; do { System.err.println(Arrays.toString(data)); } while(Util.permuteLexically(data)); }
Using this with [1,2,3] you get
[1, 2, 3] [1, 3, 2] [2, 1, 3] [2, 3, 1] [3, 1, 2] [3, 2, 1]
with [1,1,3] you instead get
[1, 1, 3] [1, 3, 1] [3, 1, 1]
which is what you asked for I think.
Since the method retunes the "next" permutation in lexicographically order it is important that the elements are ordered. Starting with [3, 2, 1] you get no more permutations (compare to example above).
回答2:
You could use a Set instead of an array of ints, it could delete your duplications automatic.
Edit: @allingeek give me an idea. More than implements your own Set you could write a wrapper over an int and overwrite your equals and hashcode methods, finding the way where your permutations are equals. Perhaps using the numbers in order and others advise given in "Effective Java" (for equals and hashcode implementations to avoid mistakes). It could give you a better way to find your permutations in the Set. More than use expressions language as I say at first.
回答3:
You want all non-duplicate permutations of an array. The number of these, assuming each array entry is unique, Factorial(array.length), quickly becomes uncomputably large. But assuming you want to enumerate them the simplest way is to do the following :
Your problem is basically a selection problem over your alphabet (1 <= N <= 100). It does not matter if you want to select 5 of these or 500, you want to select some number, call it, x. Think of the unique elements you want to select from, those that you do not want to duplicate (this may be a proper subset of your alphabet, or not). Lay these elements out in a row. The length of this row is n. Now the selection problem of enumerating a selection of x of these can be solved as follows. Think of an n bit number, that can only ever contain n-x zeroes. To get this rank-x number, simply start from 0 and enumerate all possible numbers up to 2**n, selecting only those that have exactly x 1s (and n-x zeroes). These 1s then select x positions from the n positions of your alphabet, and each of these rank-x numbers selects a permutation for you.
If anyone knows an optimization so that you don't have to work out all the non-rank-x ones, please say so. EDIT: The answer, it seems, is here
回答4: