每天一道算法题——求全排列

排列:从n个元素中任取m个元素,并按照一定的顺序进行排列,称为排列;
全排列:当n==m时,称为全排列;

比如:集合{ 1,2,3}的全排列为:
{ 1 2 3} 
{ 1 3 2 }
{ 2 1 3 }
{ 2 3 1 }
{ 3 2 1 }
{ 3 1 2 }


方法一




(递归)

	public void swp(char[] ch,int i1,int i2)
	{
		char temp=ch[i1];
		ch[i1]=ch[i2];
		ch[i2]=temp;
		
	
	}
	
	
	public void perm(char[] ch,int start,int end)
	{
		if(start==end)
		{
			System.out.println(Arrays.toString(ch));
		}
		else
		{
			for(int i=start;i<=end;i++)
			{
				swp(ch,start,i);
				perm(ch,start+1,end);
				swp(ch,i,start);
				
			}
		}
	}
	
	public void allSort(String str)
	{
		char[] ch=str.toCharArray();
		perm(ch,0,ch.length-1);
		
	}


方法二





(递归)

	public void perm02(char[] ch, int start, int end)
	{
		if (start > end)
		{
			System.out.println(Arrays.toString(ch));
		} else
		{

			int target = start;
			perm02(ch, start + 1, end);
			while (target > 0)
			{

				char temp = ch[target - 1];
				ch[target - 1] = ch[target];
				ch[target] = temp;
				target--;

				perm02(ch, start + 1, end);
			}

			// }
		}
	}



(非递归)

	/**
	 * 求全排列,非递归
	 * 
	 * @param str
	 * @return
	 */
	public List<char[]> allSort01(String str)
	{
		char[] charArray = str.toCharArray();
		List<char[]> list = new ArrayList<char[]>();

		for (int start = charArray.length - 1; start >= 0; start--)
		{
			List<char[]> changeList = new ArrayList<>();
			if (list.size() == 0)
			{
				changeList.addAll(change(charArray, start, charArray.length - 1));

			}

			for (char[] ch : list)
			{
				changeList.addAll(change(ch, start, charArray.length - 1));

			}

			list.addAll(changeList);

		}

		return list;
	}

	/**
	 * 把给定数组,start指着的那个元素,每次的往后移动一格,把每次移动生成的数组加入list 例如: 数组abc,start指向a,那么返回
	 * bac,bca
	 * 
	 * @param ch
	 * @param start
	 * @param end
	 * @return
	 */
	public List<char[]> change(char[] ch, int start, int end)
	{
		char[] buf = ch.clone();
		List<char[]> list = new ArrayList<char[]>();
		if (start == end)
		{
			list.add(buf);
		} else
		{
			for (int i = start; i < end; i++)
			{

				char temp = buf[i];
				buf[i] = buf[i + 1];
				buf[i + 1] = temp;
				list.add(buf.clone());
			}
			// list.add(buf.clone());
		}

		return list;
	}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值