扑克排序(不出现重复的全排列)

A A 2 2 3 3 4 4, 一共4对扑克牌。请你把它们排成一行。
要求:两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌。


请填写出所有符合要求的排列中,字典序最小的那个。

例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。


这里考察了一个,全排列的时候回出现重复值的问题。

使用set 集合,把找到的所有重复的值 都过滤掉

import java.util.TreeSet;

public class Main {
	
   
    public static void main(String[] args) {
    	StringBuffer str1 = new StringBuffer("AA223344");
    	StringBuffer str2 = new StringBuffer();
    	All(str1,str2);
    	for(String str:set){
    		System.out.println(str);
    	}
    }
    
    static TreeSet<String> set = new TreeSet<String>(); 
    public static void All(StringBuffer str1,StringBuffer str2){
    	if(str1.length()==0){
    		if(check(str2)){
    			String temp = str2.toString();
    			set.add(temp);
    		}
    	}else{
    		for(int i=0;i<str1.length();i++){
    			str2.append(str1.charAt(i));
    			str1.deleteCharAt(i);
    			All(str1,str2);
    			str1.insert(i,str2.charAt(str2.length()-1));
    			str2.deleteCharAt(str2.length()-1);
    		}
    	}
    }
    
    public static boolean check(StringBuffer str){
    	int a1 = str.indexOf("A");
    	int a2 = str.lastIndexOf("A");
    	
    	int two1 = str.indexOf("2");
    	int two2 = str.lastIndexOf("2");
    	
    	int three1 = str.indexOf("3");
    	int three2 = str.lastIndexOf("3");
    	
    	int four1 = str.indexOf("4");
    	int four2 = str.lastIndexOf("4");
    	
    	if(a1+2==a2&&two1+3==two2&&three1+4==three2&&four1+5==four2){
    		return true;
    	}
    	return false;
    }
    

}


2.分析我们的全排列递归程序

ABCDAEAG

全排列程序的原理每个位置的字母 都和 他后面的 每个位置交换一下。

A ->>A  (考虑到最初始的串,要自己和自己交换一下)

A ->>B

A ->>C

A ->>D

A ->>A  (没有必要的交换。)

A ->>E

A ->>A  (没有必要的交换。)

A ->>G

结果:当我的index 位置 已经 和该位置交换过一次了,就没有必要和重复的值再次交换了

import java.util.TreeSet;

public class Main {
	
   
    public static void main(String[] args) {
    	StringBuffer str1 = new StringBuffer("AA223344");
    	StringBuffer str2 = new StringBuffer();
    	All(str1,str2);
    	
    }
    
 
    public static void All(StringBuffer str1,StringBuffer str2){
    	if(str1.length()==0){
    		if(check(str2)){
    			String temp = str2.toString();
    			System.out.println(temp);
    		}
    	}else{
    		
    		//判断是否已经交换过的set
    		String set = "";
    		for(int i=0;i<str1.length();i++){
    			//已经和他交换过了
    			if(set.indexOf(str1.charAt(i))!=-1)continue;
    			
    			//交换过了一次
    			set += str1.charAt(i);
    			str2.append(str1.charAt(i));
    			str1.deleteCharAt(i);
    			All(str1,str2);
    			str1.insert(i,str2.charAt(str2.length()-1));
    			str2.deleteCharAt(str2.length()-1);
    		}
    	}
    }
    
    public static boolean check(StringBuffer str){
    	int a1 = str.indexOf("A");
    	int a2 = str.lastIndexOf("A");
    	
    	int two1 = str.indexOf("2");
    	int two2 = str.lastIndexOf("2");
    	
    	int three1 = str.indexOf("3");
    	int three2 = str.lastIndexOf("3");
    	
    	int four1 = str.indexOf("4");
    	int four2 = str.lastIndexOf("4");
    	
    	if(a1+2==a2&&two1+3==two2&&three1+4==three2&&four1+5==four2){
    		return true;
    	}
    	return false;
    }
    

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SUNbrightness

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值