Leetcode 46 给一个无重复数字的集合,返回所有的可能的组合
求一个数组的全排列,对于数组的下标索引(0~arr.length-1),我们需要考虑将数组中每一个数字放置在该下标的情况。
public class Permutations {
public static List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new LinkedList<>();
helper(nums, 0, result);
return result;
}
private static void helper(int[] nums, int index, List<List<Integer>> result) {
if (index == nums.length) {
List<Integer> list = new LinkedList<>();
Arrays.stream(nums).forEach(list::add);
result.add(list);
return;
}
for (int i = index; i < nums.length; i++) {
// 将其他位置的数字放置到数组的index下标处
swap(nums, i, index);
// 递归交换数字到其它下标处
helper(nums, index + 1, result);
// 将数组恢复为原始的状态,进行下一次交换
swap(nums, i, index);
}
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}
Leetcode 47
因为有重复的元素,我们在交换元素元素之前需要判断该元素是否已经被放置到过这个位置,如果放置过的话,就不再放置了,下面的isPlaced()函数就起到这样的作用。
class Solution {
public static List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new LinkedList<>();
helper(nums, 0, result);
return result;
}
private static void helper(int[] nums, int index, List<List<Integer>> result) {
if (index == nums.length) {
List<Integer> list = new LinkedList<>();
Arrays.stream(nums).forEach(list::add);
result.add(list);
return;
}
for (int i = index; i < nums.length; i++) {
if (isPlaced(nums,index,i)) {
continue;
}
swap(nums, i, index);
// 其实这里不用添加,index等于size的时候nums中就是最终结果
helper(nums, index + 1, result);
swap(nums, i, index);
}
}
private static boolean isPlaced(int[] nums, int start, int end) {
// 如果在end下标之前存在一个和end相同的元素,那么在start位置是已经防止过了的,我们就不再放置
for (int i = start; i < end; i++) {
if (nums[i] == nums[end])//当前元素已经是重复元素
return true;
}
return false;
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
public static void main(String[] args) {
System.out.println(permuteUnique(new int[]{
1, 0, 0, 0, 9}));
}
}