扑克排序(全排列 + String中API的使用)

1. 问题描述:

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

请填写出所有符合要求的排列中,字典序最小的那个1
例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。、

请通过浏览器提交答案。“A”一定不要用小写字母a,也不要用“1”代替。字符间一定不要留空格

2. 思路分析:

① 首先我们需要在对所有字符进行排列然后再对当前得到的排列进行检查看是否满足条件,所有首先要解决的问题是求解出全排列,C++有全排列的方法可以直接使用,但是Java中没有直接求解全排列的方法,所以需要自己写一个求解全排列的方法,典型求解的方法是使用递归的方法来进行求解,在方法中传入一个表示当前位置的变量然后将当前位置与当前位置后面的位置进行元素的交换,这样就可以求解出所以全排列,但是因为有重复元素,所以我们需要使用Set数据结构辅助我们将求解出的重复元素去除

② 在求解全排列的方法中当我们求解出一个全排列的时候,需要对当前的全排列进行判断看一下是否满足条件,这里需要使用到Java的API将char数组转化为String对象的方法,new String(char arr[]); 这样对字符串进行校验

③ 在校验的方法中我们也需要使用到Java的另外一个API,就是获取已知字符的第一个下标和相同的已知字符的最后一个下标,通过分析 "两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌" 可以发现已知的最后一个字符与相同的另外一个字符的下标分别相差2,3,4,5这样经过简单的判断就知道是否满足上面的条件了

private static boolean check(String s) {
	//使用API对四个位置进行检验
	if(s.lastIndexOf('A') - s.indexOf('A') == 2 &&
		s.lastIndexOf('2') - s.indexOf('2') == 3 &&
		s.lastIndexOf('3') - s.indexOf('3') == 4 &&
		s.lastIndexOf('4') - s.indexOf('4') == 5)
		return true;
	return false;
}

其中最主要考察的是全排列的求解与Java中String类字符数组与字符串之间的转换和已知字符获取下标的的相关API的使用

⑤ 最后对于Set进行迭代(遍历)看输出来的字符串是什么然后在里面找到一个字典序最小的

3. 具体的代码如下:

import java.util.HashSet;
import java.util.Set;
public class Main {
	static Set<String> set = new HashSet<String>();
	public static void main(String[] args) {
		char arr[] = {'A', 'A', '2', '2', '3', '3', '4', '4'};
		solve(arr, 0);
		for(String s : set){
			System.out.println(s);
		}
	}
	
	private static void solve(char[] arr, int k) {
		if(k == arr.length){
			String s = new String(arr);
			if(check(s)){
				set.add(s);
			}
		}
		for(int i = k; i < arr.length; i++){
			//进行交换
			char c = arr[k];
			arr[k] = arr[i];
			arr[i] = c;
			solve(arr, k + 1);
			//回溯
			c = arr[k];
			arr[k] = arr[i];
			arr[i] = c;
		}
	}

	private static boolean check(String s) {
		//使用API对四个位置进行检验
		if(s.lastIndexOf('A') - s.indexOf('A') == 2 &&
			s.lastIndexOf('2') - s.indexOf('2') == 3 &&
			s.lastIndexOf('3') - s.indexOf('3') == 4 &&
			s.lastIndexOf('4') - s.indexOf('4') == 5)
			return true;
		return false;
	}
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值