题意整理
- n个人在排队,它们的位置可能被打乱了,有一个数组记录了一些信息。
- 数组中对应的那个人,记录着站在他左部分和站在他右部分的人的人数差的绝对值。
- 根据上面的信息,求他们可能的站法有多少种。
方法一(排序)
1.解题思路
如果有两个人,a数组只能是[1,1],如果有三个人a数组只能是[2,0,2],如果有4个人,a数组一定是[1,3,3,1]或者[1,3,3,1]打乱顺序后的样子。依此类推,n为奇数时,a一定是形如(0,2,2,4,4,6,6,……)的数组,n为偶数时,a一定是形如(1,1,3,3,5,5,……)的数组。数列a中报0的那个人一定在队伍的正中间,对于其他人,每一个不同的人数差的绝对值,都可以将他们对调一次位置,所以总共有 种可能的站法。
- 首先对数组a排序
- 如果数组a长度是偶数,要验证其是否是形如(1,1,3,3,5,5,……)的数组;如果数组a长度是奇数,要验证其是否是形如(0,2,2,4,4,6,6,……)的数组。
- 最后计算可能的站法数
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @param a int整型一维数组
* @return int整型
*/
//取余常数
int mod=1000000007;
public int solve (int n, int[] a) {
//排序
Arrays.sort(a);
//判断a是否是合理的数组
if(!check(a)) return 0;
//计算可能的站法数
int res=1;
for(int i=0;i<n/2;++i){
res = (res*2)%mod;
}
return res;
}
private boolean check(int[] a){
int n=a.length;
boolean isEven=(n%2==0);
for(int i=0;i<n;i+=2){
//如果是偶数,一定是形如(1,1,3,3,5,5,……)的序列
if(isEven&&(a[i]!=a[i+1]||a[i]!=i+1)){
return false;
}
//如果是奇数,一定是形如(0,2,2,4,4,6,6,……)的序列
if(!isEven){
if(a[0]!=0){
return false;
}
if(i!=0&&(a[i]!=a[i-1]||a[i]!=i)){
return false;
}
}
}
return true;
}
}3.复杂度分析
- 时间复杂度:排序的时间复杂度是
,其他的遍历均是线性的,所以最终的时间复杂度是
。
- 空间复杂度:需要额外常数级别的内存空间,所以空间复杂度是
。
方法二(排序+快幂法)
1.解题思路
此方法与方法一的思路大致相同,不过计算时,使用了快幂法。
很多情况下乘方运算会超出数据范围,造成溢出,可以通过快幂法,在每次运算中通过取余的方式,防溢出,并且,如果有n个数相乘,快幂法的时间复杂度为。
动图展示(快幂法求指数):
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @param a int整型一维数组
* @return int整型
*/
//取余常数
int mod=1000000007;
public int solve (int n, int[] a) {
//排序
Arrays.sort(a);
//判断a是否是合理的数组
if(!check(a)) return 0;
return fastpow(2,n/2);
}
private boolean check(int[] a){
int n=a.length;
boolean isEven=(n%2==0);
for(int i=0;i<n;i+=2){
//如果是偶数,一定是形如(1,1,3,3,5,5,……)的序列
if(isEven&&(a[i]!=a[i+1]||a[i]!=i+1)){
return false;
}
//如果是奇数,一定是形如(0,2,2,4,4,6,6,……)的序列
if(!isEven){
if(a[0]!=0){
return false;
}
if(i!=0&&(a[i]!=a[i-1]||a[i]!=i)){
return false;
}
}
}
return true;
}
//快幂法求指数运算
private int fastpow(long base,int k){
long res=1;
while(k>0){
if((k&1)==1){
res=res*base%mod;
}
base=base*base%mod;
k>>=1;
}
return (int)res;
}
} 3.复杂度分析
- 时间复杂度:排序的时间复杂度是
,快幂法求站法数的时间复杂度为
,其他的遍历均是线性的,所以最终的时间复杂度是
。
- 空间复杂度:需要额外常数级别的内存空间,所以空间复杂度是
。

京公网安备 11010502036488号