抽牌游戏

有一副1 ~ n序号的牌,现在把这带序号的牌随机排列,第一个数默认为0,即有 n + 1 个数字,问有多少种排列结果。
输入整型n,输出整型

排列结果必须满足以下条件:

  1. 末尾必须是n序号的牌
  2. 相邻两张牌序号的绝对值不能大于2

输入示例
3
输出示例
2

解释:
[[0, 1, 2, 3], [0, 2, 1, 3]] 2种排列情况

解题思路:
看到题还有点懵,我在梳理一下。就是默认输入一个n
需要我们构造一个 n+1 的数组
例如:
输入3
数组就是:[ 0, 1, 2, 3]

输入5
数组就是:[ 0, 1, 2, 3, 4, 5]

数组构建出来了,那么要知道输出符合结果的值应该采用全排列+剪枝的方法

  1. 全排列,把所有排列的情况都列举出来
  2. 再剪枝,把符合题目的排列再进行过滤一遍
  3. 结果就是符合题目,也就是我们想要的值

废话不多说,直接上Java代码

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            int[] nums = new int[n + 1];
            //构建数组
            for(int i = 0; i <= n; i++) {
                nums[i] = i;
            }
            List<List<Integer>> res = permute(nums,n);
            System.out.println(res.toString() + "   " + res.size() );
        }
        sc.close();
    }
    
    public static List<List<Integer>> permute(int[] nums,int n) {
        List<List<Integer>> res = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
        backTrack(res,list,nums,n);
        return res;
    }

    public static void backTrack(List<List<Integer>> res, List<Integer> list, int[] nums,int n) {
     //下面的判断就是把相邻两张牌序号的绝对值不能大于2的情况过滤出来
        if(list.size() >= 2) {
            int temp = Math.abs(list.get(list.size() - 1) - list.get(list.size() - 2));
            if(temp > 2) {
                return;
            }
        }
        //这里是判断首为0,末尾为n,如果都符合,那么就是一个符合题目的排列,就保存到res里面
        if(list.size() == nums.length && list.get(0) == 0 && list.get(nums.length - 1) == n ) {
            res.add(new ArrayList<Integer>(list));
            return;
        }

        for(int num : nums) {
            if(!list.contains(num)) {
                list.add(num);
                backTrack(res,list,nums,n);
                list.remove(list.size() - 1);
            }
        }
    }
}

以上就是在做题中遇到的问题,简单的写一下思路,希望大家多多指点,如有不得当之处,留言告知,谢谢。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值