27. 字符串全排序

这里写图片描述

###思路1
直接使用求解全排序问题的next_permutation() 函数,next_permutation() 的具体实现见Next Permutation

package com.zhumq.leetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Test;

public class Permutations {
	//重新实现next_permutation()
	public List<List<Integer>> permute(int[] nums){
		List<List<Integer>> result = new ArrayList<>(); 
		Arrays.sort(nums);
		
		do {
			ArrayList<Integer> one = new ArrayList<>();
			for(int i :nums) {
				one.add(i);
			}
			result.add(one);
		}while(nextPermutation(nums,0,nums.length));
		return result;
	}
	//主要就是实现next_permutation函数
	private static boolean nextPermutation(int[] nums, int begin, int end) {
		//从右到左找到第一个破坏递增的元素
		int p = end-2;
		while(p>-1&&nums[p]>=nums[p+1]) {
			--p;
		}
		//如果没有找到则代表当前序列已经是最后一个排序,返回false后直接输出全部结果
		if(p==-1) {
			reverse(nums,0,nums.length);
			return false;
		}
		//从右到左找到第一个大于前面破坏增序的元素
		int c = end-1;
		while(nums[c]<=nums[p]&&c>0) {
			--c;
		}
		//交换这两个元素同时将p+1后面的部分反转
		swap(nums,p,c);
		//这里第三个参数是end不是c,为了统一后面的交换函数
		reverse(nums,p+1,end);
		return true;
		
	}
	private static void swap(int[] nums, int p, int c) {
		int temp = nums[p];
		nums[p] = nums[c];
		nums[c] = temp;
	}
	private static void reverse(int[] nums, int begin, int end) {
		end--;
		while(begin<end) {
			swap(nums,begin++,end--);
		}
	}
	
	@Test
	public void test1() {
		int arr[] = {1,2,3};
		/*
		 * 接口引用指向实现类的对象:
		 * 		List result是在栈区开辟一个空间放list引用,并没有创建对象所以不知道ArrayList还是LinkedList
		 * 		当你result = new ArrayList(); 就创建了ArrayList对象,
		 * 		并且把开始创建的List引用指向这个对象ArrayList
		 */
		List<List<Integer>> al = permute(arr);
		for(List<Integer> list : al) {
			for(Integer i : list) {
				//这里不是+' '而是+" "
				System.out.print(i+" ");
			}
			System.out.println();
		}
	}
}

###思路2
我们求整个字符串的排列,可以看成两步:首先求出所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。下图就是分别把第一个字符a和后面的b,c交换的情景。第二步固定第一个字符,求后面所有字符的排列。这个时候我们仍把后面的所有字符分成两部分:后面字符的第一个字符,以及这个字符之后的所有字符。然后把第一个字符逐一和它后面的字符交换……
这里写图片描述
注:(a)把字符串分为两部分,一部分是字符串的第一个字符,另一部分是第一个字符以后的所有字符。接下来我们求阴影部分的字符串的排列。(b)拿第一个字符和它后面的字符逐个交换。

分析到这里,我们就可以看出,这其实是很典型的递归思路,于是我们写出下面的Java代码:

	//递归思路
	public void permute2(char[] arr,int index,int size){
		if(index == size){
			for(int i = 0;i<arr.length;i++){
				System.out.print(arr[i]+ " ");
			}
			System.out.println();
		}
		else{
			for(int i = index;i<size;i++){
				if(i!=index && arr[i] == arr[index])
					continue;
				swapChar(arr,i,index);
				permute2(arr,index+1,size);
				swapChar(arr,i,index);
			}
		}
	}
	public void swapChar(char[] arr,int idx1,int idx2){
		char temp = arr[idx1];
		arr[idx1] = arr[idx2];
		arr[idx2] = temp;
	}
	
	@Test
	public void test2() {
		String str = "abcdef";
		char[] ch = str.toCharArray();
		permute2(ch, 0, ch.length);
	}	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值