排列是n个元素的排列,因此没有元素出现在其原始位置。例如,{0,1,2,3}的排列是{2,3,1,0}。
给定数字n,找到一组n个元素的排列的总数。
例子 :
Input: n = 2
Output: 1
For two elements say {0, 1}, there is only one
possible derangement {1, 0}
Input: n = 3
Output: 2
For three elements say {0, 1, 2}, there are two
possible derangements {2, 0, 1} and {1, 2, 0}
Input: n = 4
Output: 9
For four elements say {0, 1, 2, 3}, there are 9
possible derangements {1, 0, 3, 2} {1, 2, 3, 0}
{1, 3, 0, 2}, {2, 3, 0, 1}, {2, 0, 3, 1}, {2, 3,
1, 0}, {3, 0, 1, 2}, {3, 2, 0, 1} and {3, 2, 1, 0}
令countDer(n)为n个元素的错位计数。下面是它的递归关系。
countDer(n) = (n - 1) * [countDer(n - 1) + countDer(n - 2)]
以上递归关系如何工作?
元素0有n – 1种方式(这说明与n – 1相乘)。
设0放在索引i处。现在有两种可能性,这取决于元素i是否返回为0。
- i的位置为0:这种情况等效于解决n-2个元素的问题,因为两个元素刚刚交换了位置。
- i不在0处:这种情况等效于解决n-1个元素的问题,因为现在有n-1个元素,n-1个位置并且每个元素都有n-2个选择
以下是基于上述递归公式的简单解决方案:
C++
// A Naive Recursive C++ program
// to count derangements
#include
using namespace std;
int countDer(int n)
{
// Base cases
if (n == 1) return 0;
if (n == 2) return 1;
// countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
return (n - 1) * (countDer(n - 1) + countDer(n - 2));
}
// Driver Code
int main()
{
int n = 4;
cout << "Count of Derangements is "
<< countDer(n);
return 0;
}
Java
// A Naive Recursive java
// program to count derangements
import java.io.*;
class GFG
{
// Function to count
// derangements
static int countDer(int n)
{
// Base cases
if (n == 1) return 0;
if (n == 2) return 1;
// countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
return (n - 1) * (countDer(n - 1) +
countDer(n - 2));
}
// Driver Code
public static void main (String[] args)
{
int n = 4;
System.out.println( "Count of Derangements is "
+countDer(n));
}
}
// This code is contributed by vt_m
Python3
# A Naive Recursive Python3
# program to count derangements
def countDer(n):
# Base cases
if (n == 1): return 0
if (n == 2): return 1
# countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
return (n - 1) * (countDer(n - 1) +
countDer(n - 2))
# Driver Code
n = 4
print("Count of Derangements is ", countDer(n))
# This code is contributed by Azkia Anam.
C#
// A Naive Recursive C#
// program to count derangements
using System;
class GFG
{
// Function to count
// derangements
static int countDer(int n)
{
// Base cases
if (n == 1) return 0;
if (n == 2) return 1;
// countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
return (n - 1) * (countDer(n - 1) +
countDer(n - 2));
}
// Driver Code
public static void Main ()
{
int n = 4;
Console.Write( "Count of Derangements is " +
countDer(n));
}
}
// This code is contributed by nitin mittal.
PHP
Javascript
C++
// A Dynamic programming based C++
// program to count derangements
#include
using namespace std;
int countDer(int n)
{
// Create an array to store
// counts for subproblems
int der[n + 1] = {0};
// Base cases
der[1] = 0;
der[2] = 1;
// Fill der[0..n] in bottom up manner
// using above recursive formula
for (int i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
// Return result for n
return der[n];
}
// Driver code
int main()
{
int n = 4;
cout << "Count of Derangements is "
<< countDer(n);
return 0;
}
Java
// A Dynamic programming based
// java program to count derangements
import java.io.*;
class GFG
{
// Function to count
// derangements
static int countDer(int n)
{
// Create an array to store
// counts for subproblems
int der[] = new int[n + 1];
// Base cases
der[1] = 0;
der[2] = 1;
// Fill der[0..n] in bottom up
// manner using above recursive
// formula
for (int i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
// Return result for n
return der[n];
}
// Driver program
public static void main (String[] args)
{
int n = 4;
System.out.println("Count of Derangements is " +
countDer(n));
}
}
// This code is contributed by vt_m
Python3
# A Dynamic programming based Python3
# program to count derangements
def countDer(n):
# Create an array to store
# counts for subproblems
der = [0 for i in range(n + 1)]
# Base cases
der[1] = 0
der[2] = 1
# Fill der[0..n] in bottom up manner
# using above recursive formula
for i in range(3, n + 1):
der[i] = (i - 1) * (der[i - 1] +
der[i - 2])
# Return result for n
return der[n]
# Driver Code
n = 4
print("Count of Derangements is ", countDer(n))
# This code is contributed by Azkia Anam.
C#
// A Dynamic programming based
// C# program to count derangements
using System;
class GFG
{
// Function to count
// derangements
static int countDer(int n)
{
// Create an array to store
// counts for subproblems
int []der = new int[n + 1];
// Base cases
der[1] = 0;
der[2] = 1;
// Fill der[0..n] in bottom up
// manner using above recursive
// formula
for (int i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
// Return result for n
return der[n];
}
// Driver code
public static void Main ()
{
int n = 4;
Console.Write("Count of Derangements is " +
countDer(n));
}
}
// This code is contributed by nitin mittal
PHP
Javascript
C++
// C++ implementation of the above
// approach
#include
using namespace std;
int countDer(int n)
{
// base case
if (n == 1 or n == 2) {
return n - 1;
}
// Variable for just storing
// previous values
int a = 0;
int b = 1;
// using above recursive formula
for (int i = 3; i <= n; ++i) {
int cur = (i - 1) * (a + b);
a = b;
b = cur;
}
// Return result for n
return b;
}
// Driver Code
int main()
{
cout << "Count of Dearrangements is " << countDer(4);
return 0;
}
// Code contributed by skagnihotri
Java
// Java implementation of the
// above approach
import java.io.*;
class GFG {
// Function to count derangements
static int countDer(int n) {
// Base case
if(n == 1 || n == 2) {
return n-1;
}
// Variable for storing prev values
int a = 0;
int b = 1;
// manner using above recursive formula
for (int i = 3; i <= n; ++i) {
int cur = (i-1)*(a+b);
a = b;
b = cur;
}
// Return result for n
return b;
}
// Driver Code
public static void main (String[] args)
{
int n = 4;
System.out.println("Count of Dearrangements is " +
countDer(n));
}
// Code contributed by skagnihotri
}
Python
# Python program to count derangements
def countDer(n):
# Base Case
if n == 1 or n == 2:
return n-1;
# Variables for storing prevoius values
a = 0
b = 1
# using above recursive formula
for i in range(3, n + 1):
cur = (i-1)*(a+b)
a = b
b = cur
# Return result for n
return b
# Driver Code
n = 4
print("Count of Dearrangements is ", countDer(n))
# Code contributed by skagnihotri
C#
// C# implementation of the above
// approach
using System;
class GFG{
// Function to count
// derangements
static int countDer(int n)
{
// Base case
if (n == 1 || n == 2)
{
return n - 1;
}
// Variable for just storing
// previous values
int a = 0;
int b = 1;
// Using above recursive formula
for(int i = 3; i <= n; ++i)
{
int cur = (i - 1) * (a + b);
a = b;
b = cur;
}
// Return result for n
return b;
}
// Driver code
public static void Main()
{
Console.Write("Count of Dearrangements is " +
countDer(4));
}
}
// This code is contributed by koulick_sadhu
输出
Count of Derangements is 9
时间复杂度:T(n)= T(n-1)+ T(n-2)是指数的。
我们可以观察到该实现确实重复了工作。例如,请参见递归树中的countDer(5),对countDer(3)进行两次评估。
cdr() ==> countDer()
cdr(5)
/ \
cdr(4) cdr(3)
/ \ / \
cdr(3) cdr(2) cdr(2) cdr(1)
一个有效的解决方案是使用动态编程将子问题的结果存储在数组中,并以自底向上的方式构建数组。
C++
// A Dynamic programming based C++
// program to count derangements
#include
using namespace std;
int countDer(int n)
{
// Create an array to store
// counts for subproblems
int der[n + 1] = {0};
// Base cases
der[1] = 0;
der[2] = 1;
// Fill der[0..n] in bottom up manner
// using above recursive formula
for (int i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
// Return result for n
return der[n];
}
// Driver code
int main()
{
int n = 4;
cout << "Count of Derangements is "
<< countDer(n);
return 0;
}
Java
// A Dynamic programming based
// java program to count derangements
import java.io.*;
class GFG
{
// Function to count
// derangements
static int countDer(int n)
{
// Create an array to store
// counts for subproblems
int der[] = new int[n + 1];
// Base cases
der[1] = 0;
der[2] = 1;
// Fill der[0..n] in bottom up
// manner using above recursive
// formula
for (int i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
// Return result for n
return der[n];
}
// Driver program
public static void main (String[] args)
{
int n = 4;
System.out.println("Count of Derangements is " +
countDer(n));
}
}
// This code is contributed by vt_m
Python3
# A Dynamic programming based Python3
# program to count derangements
def countDer(n):
# Create an array to store
# counts for subproblems
der = [0 for i in range(n + 1)]
# Base cases
der[1] = 0
der[2] = 1
# Fill der[0..n] in bottom up manner
# using above recursive formula
for i in range(3, n + 1):
der[i] = (i - 1) * (der[i - 1] +
der[i - 2])
# Return result for n
return der[n]
# Driver Code
n = 4
print("Count of Derangements is ", countDer(n))
# This code is contributed by Azkia Anam.
C#
// A Dynamic programming based
// C# program to count derangements
using System;
class GFG
{
// Function to count
// derangements
static int countDer(int n)
{
// Create an array to store
// counts for subproblems
int []der = new int[n + 1];
// Base cases
der[1] = 0;
der[2] = 1;
// Fill der[0..n] in bottom up
// manner using above recursive
// formula
for (int i = 3; i <= n; ++i)
der[i] = (i - 1) * (der[i - 1] +
der[i - 2]);
// Return result for n
return der[n];
}
// Driver code
public static void Main ()
{
int n = 4;
Console.Write("Count of Derangements is " +
countDer(n));
}
}
// This code is contributed by nitin mittal
的PHP
Java脚本
输出
Count of Derangements is 9
时间复杂度: O(n)
辅助空间: O(n)
感谢Utkarsh Trivedi提出上述解决方案。
一个更有效的解决方案,无需使用额外的空间。
由于我们只需要记住两个先前的值,因此,与其将值存储在数组中,还可以使用两个变量仅存储所需的先前的值。
下面是上述方法的实现:
C++
// C++ implementation of the above
// approach
#include
using namespace std;
int countDer(int n)
{
// base case
if (n == 1 or n == 2) {
return n - 1;
}
// Variable for just storing
// previous values
int a = 0;
int b = 1;
// using above recursive formula
for (int i = 3; i <= n; ++i) {
int cur = (i - 1) * (a + b);
a = b;
b = cur;
}
// Return result for n
return b;
}
// Driver Code
int main()
{
cout << "Count of Dearrangements is " << countDer(4);
return 0;
}
// Code contributed by skagnihotri
Java
// Java implementation of the
// above approach
import java.io.*;
class GFG {
// Function to count derangements
static int countDer(int n) {
// Base case
if(n == 1 || n == 2) {
return n-1;
}
// Variable for storing prev values
int a = 0;
int b = 1;
// manner using above recursive formula
for (int i = 3; i <= n; ++i) {
int cur = (i-1)*(a+b);
a = b;
b = cur;
}
// Return result for n
return b;
}
// Driver Code
public static void main (String[] args)
{
int n = 4;
System.out.println("Count of Dearrangements is " +
countDer(n));
}
// Code contributed by skagnihotri
}
Python
# Python program to count derangements
def countDer(n):
# Base Case
if n == 1 or n == 2:
return n-1;
# Variables for storing prevoius values
a = 0
b = 1
# using above recursive formula
for i in range(3, n + 1):
cur = (i-1)*(a+b)
a = b
b = cur
# Return result for n
return b
# Driver Code
n = 4
print("Count of Dearrangements is ", countDer(n))
# Code contributed by skagnihotri
C#
// C# implementation of the above
// approach
using System;
class GFG{
// Function to count
// derangements
static int countDer(int n)
{
// Base case
if (n == 1 || n == 2)
{
return n - 1;
}
// Variable for just storing
// previous values
int a = 0;
int b = 1;
// Using above recursive formula
for(int i = 3; i <= n; ++i)
{
int cur = (i - 1) * (a + b);
a = b;
b = cur;
}
// Return result for n
return b;
}
// Driver code
public static void Main()
{
Console.Write("Count of Dearrangements is " +
countDer(4));
}
}
// This code is contributed by koulick_sadhu
输出
Count of Derangements is 9
时间复杂度: O(n)
辅助空间: O(1)
感谢Shubham Kumar提出上述解决方案。
参考:
https://zh.wikipedia.org/wiki/排列