leetcode950——按增序显示卡牌(循环队列,标志位的使用,向量vector的基本操作)
//思路:
//翻开-置底的操作,相当于对新数组间隔取值
//在第一轮翻到底之后,被置底的牌依旧是按照下标递增的顺序排列的
//重复执行前2步,直到没有牌
//本质:
//将数组变为”循环队列“,并且间隔取值,取过的位置被移除,且要求取值是升序的
//代码:
//(1)如何将数组变成循环队列, 使用j=(j++)%len
//(2)如何将赋值过的位置移除, 使用标志位
//(3)如何进行间隔赋值, 使用标志位,bool型即可
//注:
//while循环可能还存在冗余计算
class Solution {
public:
vector<int> deckRevealedIncreasing(vector<int>& deck) {
int len=deck.size();
vector<int> vec(len,0); //创建返回值vec,题中已知所有元素>=1,所以令初始向量元素=0,可以起到标志位的作用
bool k=true; //用于实现间隔赋值
sort(deck.begin(), deck.end()); //先对向量排序(增序)
int i,j=0;
int s=0; //用于循环遍历向量时,记录已经有多少已经被赋值,用于定义跳出循环的条件
for(i=0;i<len;i++) //遍历deck
{
while ((vec[j]!=0) || (k == false)){ //当满足s[j]=1且m=0时才跳出循环,其中k[j]用于判断标志位是否可用,m=0代表隔位置
//cout << "进入了循环: " << "vec["<<j<<"]=" << vec[j] << " k=" << k << endl;
if (vec[j] == 0){ k = true; } //如果vec[j]=0,说明是因为k=false进入的循环,此时令k=ture,本质上是,跳过了一个可以赋值的元素
j=(j+1)%len; //循环遍历向量vec
if(s==len) break; //设置最终的(即找不到可以赋值的元素)时的跳出条件
}
vec[j]=deck[i]; //执行至此,跳出while说明找到了下一个赋值位置,赋值
s++;
k=!k; //进行一次赋值后,改变k的值,使下一个位置被跳过
}
return vec;
}
};