Permutation
Given a collection of numbers, return all possible permutations.
// Note: This code only work when all the numbers are unique
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList();
if (nums == null || nums.length == 0)
return result;
helper(new ArrayList<Integer>(), result, nums);
return result;
}
private void helper(List<Integer> current, List<List<Integer>> result, int[] nums) {
if (current.size() == nums.length) {
result.add(new ArrayList(current));
return;
}
for (int i = 0; i < nums.length; i++) {
if (!current.contains(nums[i])) {
current.add(nums[i]);
helper(current, result, nums);
current.remove(current.size() - 1);
}
}
}
This method doens't have List
public static List<List<Integer>> permutations(List<Integer> A) {
List<List<Integer>> result = new ArrayList<>();
directedPermutations(0, A, result);
return result;
}
private static void directedPermutations(int i, List<Integer> A,
List<List<Integer>> result) {
if (i == A.size() - 1) {
result.add(new ArrayList<>(A));
return;
}
// Try every possibility for A[i].
for (int j = i; j < A.size(); ++j) {
Collections.swap(A, i, j);
// Generate all permutations for A[i + 1 : A.size() - 1].
directedPermutations(i + 1, A, result);
Collections.swap(A, i, j);
}
}
This is identical to the above one except the argument is array.
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList();
helper(nums, 0, result);
return result;
}
private void helper(int[] nums, int currentIndex, List<List<Integer>> result) {
if (currentIndex == nums.length) {
List<Integer> current = new ArrayList();
for (int i : nums) {
current.add(i);
}
result.add(new ArrayList(current));
} else {
for (int i = currentIndex; i < nums.length; i++) {
swap(nums, i, currentIndex);
helper(nums, currentIndex + 1, result);
swap(nums, i, currentIndex);
}
}
}
private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
return;
}
Permutation II
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
- [1,1,2] have the following unique permutations:
- [1,1,2], [1,2,1], and [2,1,1].
Solution: add a set to keep track of what has been added.
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList();
helper(nums, 0, result, new HashSet<List<Integer>>());
return result;
}
private void helper(int[] nums, int currentIndex, List<List<Integer>> result, Set<List<Integer>> set) {
if (currentIndex == nums.length) {
List<Integer> current = new ArrayList();
for (int i : nums) {
current.add(i);
}
if (!set.contains(current)) {
result.add(new ArrayList(current));
set.add(current);
}
} else {
for (int i = currentIndex; i < nums.length; i++) {
swap(nums, i, currentIndex);
helper(nums, currentIndex + 1, result, set);
swap(nums, i, currentIndex);
}
}
}
private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
return;
}
//TODO: not fully understand
public List<List<Integer>> permuteUnique(int[] nums) {
Set<List<Integer>> resultSet = new HashSet();
helper(0, nums, resultSet);
return new ArrayList(resultSet);
}
private void helper(int start, int[] nums, Set<List<Integer>> resultSet) {
if (start >= nums.length) {
List<Integer> result = new ArrayList();
for (int i : nums) {
result.add(i);
}
resultSet.add(result);
return;
}
for (int i = start; i < nums.length; i++) {
// To avoid duplicate, we need to check the existing sequence first.
if (isUnique(nums, start, i)) {
swap(nums, start, i);
helper(start + 1, nums, resultSet);
swap(nums, start, i);
}
}
}
private void swap(int[] array, int i, int j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
private boolean isUnique(int[] array, int start, int end) {
for (int i = start; i <= end-1; i++) {
if (array[i] == array[end]) {
return false;
}
}
return true;
}
Sort the array first, ussing a boolean array to indicate which
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList();
Arrays.sort(nums);
boolean[] visited = new boolean[nums.length];
helper(nums, new ArrayList<Integer>(), result, visited);
return result;
}
private void helper(int[] nums, List<Integer> current, List<List<Integer>> result, boolean[] visited) {
if (current.size() == nums.length) {
result.add(new ArrayList(current));
} else {
for (int i = 0; i < nums.length; i++) {
if (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
continue;
}
if (!visited[i]) {
visited[i] = true;
current.add(nums[i]);
helper(nums, current, result, visited);
current.remove(current.size() - 1);
visited[i] = false;
}
}
}
}