LandFordPair序列

      今天被问到LandFordPair序列,要求实现输入任意n,输出存在的序列种类,之前对于n皇后这类的算法写的少,所以当场一脸懵。特意在此记录下来。

一个序列f(n)拥有2*n个数,满足如下条件:
1、 1...n,每个数都出现且仅出现两次
2、 其中任意数k,在序列中出现的两个位置,之间有k个其他数
实现算法,对于输入的任意n,输出存在的landFord序列
例如输入3,输出
[3, 1, 2, 1, 3, 2]
[2, 3, 1, 2, 1, 3]

      分析一下,其实也挺简单的,模型上是填充一个Integer[2*n]的数组,假如数字k填充在下标i,那么下标i+k+1也必须填充k,也就是传说中的剪枝思路。只要尝试把n...1所有数都分配下去,那就是一个满足条件的序列。

Talk is cheap. Show me the code!  ^_^

public class LandFordPair {
    private static List<List<Integer>> pairs = Lists.newArrayList();

    public static void main(String[] args) {
        landFord(3);
    }

    private static void landFord(int n) {
        Integer[] a = new Integer[2 * n];
        assign(n, a);
        pairs.forEach(System.out::println);
    }

    private static void assign(int k, Integer a[]) {
        // k为0表示所有数字都分配好了,将结果记录到pairs
        if (k == 0) {
            pairs.add(Lists.newArrayList(a));
            return;
        }

        for (int i = 0; i < (a.length - k - 1); i++) {
            if (a[i] == null && a[i + k + 1] == null) {
                // 尝试分配k的位置
                a[i] = a[i + k + 1] = k;
                // 递归分配k-1的位置
                assign(k - 1, a);
                // 抹掉此次分配回退,继续迭代尝试其他的分配方式
                a[i] = a[i + k + 1] = null;
            }
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值