LeetCode-46全排列(java,c语言实现)

给定一个不含重复数字的数组 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<string.h>
#include<stdio.h>
#include<stdlib.h>
//交换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());
		}
	}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值