具体思想:
跨区间模拟也行,但是题目不是这么做的,而且极其的麻烦;
相当于只关心现阶段的队列元素个数,以及队头元素即可;
具体代码:
1.模拟思路:
class Solution {
public:
int lastRemaining(int n) {
bool dir=true;//向右true,向左false;
int start=1;
int gap=1;
int pre=1;
while(1){
if(dir){
while(start+gap+1<=n){
start+=gap+1;
}
if(start+pre>n&&start-pre<=0)
return start;
start=start+pre<=n?start+pre:start-pre;
}else{
while(start-(gap+1)>0){
start-=gap+1;
}
if(start+pre>n&&start-pre<=0)
return start;
start=start-pre>0?start-pre:start+pre;
}
pre=gap+1;
gap=gap*2+1;
dir=!dir;
}
}
};
2.等差数列思路:
class Solution {
public:
int lastRemaining(int n) {
int a=1;
int step=1;
bool dir=true;
while(n!=1){
if(dir){
a+=step;
}else{
if(n%2==1)
a+=step;
}
dir=!dir;
step=step<<1;
n/=2;
}
return a;
}
};