Java 算法 - Find the Derangement of An Array(动态规划)

题意

In combinatorial mathematics, a derangement is a permutation of the elements of a set, such that no element 
appears in its original position.

There's originally an array consisting of n integers from 1 to n in ascending order, you need to find the number 
of derangement it can generate.

Also, since the answer may be very large, you should return the output mod 10^9 + 7.

样例

Given n = 3, return 2.

Explanation: 
The original array is [1,2,3]. The two derangements are [2,3,1] and [3,1,2].

1.解题思路

  咋一看这个题,还真是有点懵逼,其实认真想一想,这个题是非常的简单的。
  我们假设dp数组,dp[i]求得是一共有i个数字的值;dp[i + 1],相对于dp[i]的情况,就是多了一个i + 1的数字。
  这里需要分为两种情况:
  1.前面i个数字都是符合要求的,那么当前i + 1可以跟前面的i个数字任意一个交换,所以为 i * dp[i]。
  2.前面i个数字中有一个不符合要求,也就是它的value和index相等了。这种情况下,i + 1必须跟那个不符合要求的交换,由于前面有i 个数字,每个数字都有可能不符合要求,所以是 i * dp[i - 1]。其中dp[i - 1]就是有一个数字不符合要求的情况数目。
  从而,得知,dp[i + 1] = i * (dp[i ] + dp[i - 1]);

2.代码

    public int findDerangement(int n) {

        if(n <= 3){
            return n - 1;
        }

        int dp[] = new int[n + 1];
        dp[2] = 1;
        dp[3] = 2;

        for(int i = 4; i <= n; i++){
            long t = (i - 1) * ((long)dp[i - 1] + dp[i - 2]);
            dp[i] = (int) (t % (1e9 + 7));
        }

        return dp[n];
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容