换座位题解
解法1:
最后无论如何,一定是牛牛的人坐在一起,牛妹的人坐在一起,牛大的人坐在一起。假设我们把牛牛,牛妹,牛大人用代替。因为是圆桌那么最后从某个点开始一定可以是
这样的
那么我们可以枚举起点,枚举哪一个点作为第一个的位置
,由于
出现了多少次
我们是知道的,那么最后一个
的位置我们也获得到了,我们只需要知道从
里面有多少有多少
,这个用前缀和维护就好了。那么这些
是不用动的,其余的就是需要换位置的。接着我们枚举
旁边是
还是
,并分别计算答案,计算
,
需要换位置的人数的方式同
。
时间复杂度,空间复杂度
。
class Solution {
public:
/**
*
* @param Position int整型一维数组
* @param PositionLen int Position数组长度
* @return int整型
*/
int a[210000],b[210000],c[210000],pos[210000];
int ChangePosition(int* Position, int PositionLen) {
// write code here
int n=PositionLen;
for(int i=1;i<=n;i++) pos[i]=Position[i-1];
for(int i=1;i<=n;i++) pos[i+n]=pos[i];
for(int i=1;i<=2*n;i++) {
a[i]=a[i-1];
b[i]=b[i-1];
c[i]=c[i-1];
if(pos[i]==1) a[i]++;
else if(pos[i]==2) b[i]++;
else c[i]++;
}
int A=a[n],B=b[n],C=c[n];
int ans=1e9;
for(int i=1;i<=n;i++) {//枚举a的起始位置
int movea=A-(a[i+A-1]-a[i-1]);
//假设右边的是b
int j=i+A;
int moveb=B-(b[j+B-1]-b[j-1]);
int k=j+B;
int movec=C-(c[k+C-1]-c[k-1]);
ans=min(ans,movea+moveb+movec);
//假设右边的是c
j=i+A;
movec=C-(c[j+C-1]-c[j-1]);
k=j+C;
moveb=B-(b[k+B-1]-b[k-1]);
ans=min(ans,movea+moveb+movec);
}
return ans;
}
};解法2:TLE
我们枚举每一个人换完位置后的位置。统计有多少个人不是坐在之前自己的位置上,并且判断三类人是不是坐在一起的即可。枚举换完位置后的位置可以用全排列来做。时间复杂度,空间复杂度
。
class Solution {
public:
/**
*
* @param Position int整型一维数组
* @param PositionLen int Position数组长度
* @return int整型
*/
int a[210000],b[210000],c[210000],pos[210000];
int ChangePosition(int* Position, int PositionLen) {
// write code here
int n=PositionLen;
for(int i=1;i<=n;i++) pos[i]=Position[i-1],a[i]=i;
int ans=1e9;vector<int>v;
do {
int flag=0,tot=0;
v.clear();
for(int i=1;i<=n;i++) {
int id=a[i];
if(id!=i) tot++;
v.push_back(pos[id]);
}
v.erase(unique(v.begin(),v.end()),v.end());
if(v.size()<=3||(v.size()==4&&v[0]==v[3])) flag=1;
if(flag) ans=min(ans,tot);
}while(next_permutation(a+1,a+1+n));
return ans;
}
};

迅雷公司福利 193人发布