LeetCode Permutations

题目:

Given a collection of distinct numbers, return all possible permutations.

For example,
[1,2,3] have the following permutations:
[1,2,3][1,3,2][2,1,3][2,3,1][3,1,2], and [3,2,1].

题意:

给定一个数组,求这个数组中给的所有元素的全排列。此题是典型的数学题,那么如何来做呢?网上找了一篇博客,关于如何编程实现全排列的。

设一组数p = {r1, r2, r3, ... ,rn}, 全排列为perm(p),pn = p - {rn}。

因此perm(p) = r1perm(p1), r2perm(p2), r3perm(p3), ... , rnperm(pn)。当n = 1时perm(p} = r1。

那么具体到做法就是采用递归的方法,首先是第一个元素与后面的元素交换,然后将这个数组分成两部分,第一部分是第一个元素,第二部分就是除第一个元素外的其他所有元素,那么对第二部分继续调用递归来做全排列;以此类推,记得最后要将第一个元素和后面交换的元素给交换回来,否则在递归的时候会将原来的数组给弄乱的。

public class Solution 
{
    List<List<Integer>> list = new ArrayList<List<Integer>>();
    public List<List<Integer>> permute(int[] nums)
	{
		
		int length = nums.length;
		if(nums == null || length == 0)
			return list;
		arrange(nums,0,length - 1);
		return list;
	}
	public void swap(int[] nums,int a,int b)
	{
		int temp = nums[a];
		nums[a] = nums[b];
		nums[b] = temp;
	}
	public void arrange(int[] nums,int start,int end)
	{
		if(start == end)
		{
			List<Integer> l = new ArrayList<Integer>();
			for(int i = 0; i < nums.length; i++)
				l.add(nums[i]);
			list.add(l);
		}
		else
		{
			for(int i = start; i <= end; i++)
			{
				swap(nums,start,i);
				System.out.print(nums[start] + "  " + nums[i]);
				arrange(nums,start + 1,end);
				swap(nums,start,i);    //恢复成原来的数组,必须要有
				System.out.println();
			}
		}
	}
}

原理:

关键的就是arrange方法的else里面的内容,我的理解是(以求str[] = {"a","b","c"}的排列为例子):

用i从str[st]做一遍循环:

每一次循环中,都要将str[i]与str[i]互相调换位置:第一次开始,"a"与自己换,这时候,递归调用arrange[str,st + 1, len]

这是在求取str[str...len - 1]的排列即"b","c"的排列;

第二次,"a"与"b"互相调换,递归调用arrange[str,str + 1, len]就是在求取{"a","c"}的排列。

第三次,"a"与"c"互相调换,递归调用arrange[str, str + 1,len]就是在求取"{"b","a}的排列。

下面再以"b","c"的排列求取为例:

首先还是做循环,第一次,"b"与自己调换,这时候,调用arrange[str,st + 1,len], 就是求c的排列。呵呵,这时候终于到了函数递归调用的出口了

: st = len - 1。输出"b" "c";

第二次,类似的,输出"c","b";

至此,"b" "c"的排列求取完毕。加上前面的a,就输出"a""b""c" "a""c""b"。

类似的,就可以输出所有的排列了。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值