给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
import java.util.ArrayList;
import java.util.List;
public class Solution_2 {
static List<List<Integer>> list=new ArrayList<List<Integer>>();
public void swap(int[] nums,int point,int point2) {
int flag=nums[point];
nums[point]=nums[point2];
nums[point2]=flag;
}
public void pailie (List<List<Integer>> e,int index,int[] nums) {
if(index==nums.length-1) {
List<Integer> num=new ArrayList<>();
for(int i=0;i<nums.length;i++) {
num.add(nums[i]);
}
System.out.println(num.toString());
e.add(num);
return;
}
for(int i=index;i<nums.length;i++) {
swap(nums, i, index);
System.out.println("i="+i+"index="+index);
pailie(e, index+1, nums);
System.out.println("i="+i+"index="+index);
swap(nums, i, index);
}
}
public static void main(String[] args) {
int[]nums= {1,2,3,4};
Solution_2 one =new Solution_2();
one.pailie(list, 0, nums);
for(List<Integer> li :list) {
System.out.print(li.toString());
}
}
}
假如4个数,总共有4层,从0~3,index指代往下沉,当index=2时,再往下就是最后一层,这时4层数也就确认了,这时就录入一个序列{1,2,3,4},然后再return,此时i=index=2,然后i++,交换3,2位置的数,之后,递归又打印一个序列{1,2,4,3},然后返回再还原序列{两个swap确保序列能回到1,2,3,4},有点重置的意思。此时i++跳出循环,返回到执行i=index=1时的情形,然后i++,交换2,1位置的数,之后再递归,i=index=2, 打印{1,3,2,4},然后i++ 交换3,2处数据后进入递归打印出{1,3,4,2},然后再慢慢返回去,序列会重置到{1,2,3,4} 此时返回到i等于2,index=1的情形,然后继续i++
/*
* 算法思想:
* 经典回溯算法框架能解决的问题,其中回溯返回的条件为index到头了
*
*/
#define LEN 720
#include
#include
#include
//交换swap
void swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void rec(int* arr, int len, int index, int** ret, int* ret_index) {
int i;
//printf("index=%d\n", index);
if (index == len - 1) {
ret[*ret_index] = (int*)malloc(sizeof(int) * len);
//memcpy()函数,
//由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内
memcpy(ret[*ret_index], arr, len * sizeof(int));
(*ret_index)++;
return;
}
/* 将index位置的元素,分别和其后面的元素交换位置,交换后再考虑index+1位置及以后的全排列 */
/* 假设元素为1 2 3 4 5,则全排列个数为5*四个元素全排列,即在位置1处有5种可能,1 2 3 4 5 都在位置1的话
* 假设1的位置固定为1,则还有2 3 4 5四个元素的全排列,如此递归下去到index到最后一个元素即可结束回溯。
*/
for (i = index; i < len; i++) {
swap(&arr[i], &arr[index]);
rec(arr, len, index + 1, ret, ret_index);
swap(&arr[i], &arr[index]);
}
}
int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
int** ret = (int**)malloc(sizeof(int*) * LEN);
int* ret_size = (int*)malloc(sizeof(int) * LEN); //用来记录二维数组每行的列数
int ret_index = 0;
int i;
rec(nums, numsSize, 0, ret, &ret_index);
*returnColumnSizes = ret_size;
for (i = 0; i < ret_index; i++) {
//printf();
ret_size[i] = numsSize;
}
// printf("ret_index:%d\n", ret_index);
*returnSize = ret_index;
return ret;
}
int main(void) {
int nums[5] = { 1,2,3,4,5};
int numsSize = 5;
int returnSize;// 表示返回的二维数组的行数
int* returnColumnSize;// 用一维数组记录二维数组每一行的列数
int** ret_array = permute(nums, numsSize, &returnSize, &returnColumnSize);
for (int i = 0; i < returnSize; i++) {
for (int j = 0; j < returnColumnSize[i]; j++)
printf("%d", ret_array[i][j]);
printf("\n");
}
return 0;
}
import java.util.ArrayList;
import java.util.List;
//LeetCode_46
//全排列回溯算法
class Solution {
List<List<Integer>> target=new ArrayList<List<Integer>>();
public List<List<Integer>> permute(int[] nums) {
backtrack(nums, new ArrayList<Integer>());
return target;
}
//回溯算法,利用递归
public void backtrack(int[] nums,ArrayList<Integer> cur_array) {
//终止条件
if(cur_array.size()==nums.length) {
target.add(new ArrayList<>(cur_array));
return;
}
//添加
for(int i=0;i<nums.length;i++) {
if(cur_array.contains(nums[i]))
continue;
cur_array.add(nums[i]);
//递归
backtrack(nums,cur_array);
//回溯
cur_array.remove(cur_array.size()-1);
}
}
public static void main(String[] args) {
int[]nums= {1,2,3};
Solution m=new Solution();
List<List<Integer>> list=m.permute(nums);
for(List<Integer> li :list) {
System.out.print(li.toString());
}
}
}