1.队列的最大值
滑动窗口的最大值:给定一个数组和滑动窗口的大小,找出所有滑动窗口的最大值。
思路:建立一个两段开口的队列index,用来保存有可能是滑动窗口最大值得数字的下标。在存入一个数字的下标之前,首先要判断队列里已有数字是否小于待存入的数字。如果已有的数字小于待存入的数字,那么这些数字不可能是滑动窗口的最大值,因此将他们一次pop_back。同时,如果队列头部的数字已经从窗口滑出,那么滑出的数字也需要从队列的头部删除(pop_front)。
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> maxInWindows;
if(num.size()>=size&&size>=1)
{
deque<int> index;
for(unsigned int i=0;i<size;i++)//放入一个滑动窗口,令队头是窗口的最大值
{
while(!index.empty()&&num[i]>=num[index.back()])
{
index.pop_back();//要放入的数大于队尾,就把队尾弹出
}
index.push_back(i);//放入新数字
}
for(unsigned int i=size;i<num.size();i++)
{
maxInWindows.push_back(num[index.front()]);//存一个最大值
while(!index.empty()&&num[i]>=num[index.back()])
index.pop_back();//要放入的数大于队尾,就把队尾弹出
if(!index.empty()&&index.front()<=(int)(i-size))
index.pop_front();//队头大于滑动窗口范围,就弹出
index.push_back(i);//放入新数字
}
maxInWindows.push_back(num[index.front()]);
}
return maxInWindows;
}
};2.n个骰子的点数
n个骰子扔在地上,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能值出现的概率。
思路:基于循环求骰子点数:考虑两个数组来存储骰子点数的每个总数出现的次数。在一轮循环中,第一个数组中的第n个数字表示骰子和为n出现的次数。在下一轮循环中,加上一个新的骰子,此时和为n的骰子出现的次数应该等于上一轮循环中骰子点数和为n-1,n-2,n-3,n-4,n-5,n-6的次数的总和,所以我们把另一个数组的第n个数字设为前一个数组对应的第n-1,n-2,n-3,n-4,n-5,n-6个数字之和。
void PrintProbability(int number)//n
{
if(number<1) return;
int* pProbabilities[2];
pProbabilities[0]=new int[g_maxValue*number+1];//6*n+1
pProbabilities[1]=new int[g_maxValue*number+1];
for(int i=0;i<g_maxValue*number+1;i++)
{
pProbabilities[0][i]=0;
pProbabilities[1][i]=0;
}
int flag=0;
for(int i=1;i<=g_maxValue;i++)
{
pProbabilities[flag][i]=1;
}//只有一个骰子
for(int k=2;k<=number;k++)
{
for(int i=0;i<k;i++)
{
pProbabilities[1-flag][i]=0;
}
for(int i=k;i<=g_maxValue*k;i++)
{
pProbabilities[1-flag][i]=0;
for(int j=1;j<=i&&j<=g_maxValue;j++)
{
pProbabilities[1-flag][i]+=pProbabilities[flag][i-j];//f(n)=f(n-1)+...+f(n-6)
}
}
flag=1-flag;//交换两个数组
}
double total=pow((double)g_maxValue,number);
for(int i=number;i<=g_maxValue*number;i++)
{
double ratio=(double)pProbabilities[flag][i]/total;
printf("%d: %e\n",i,ratio);
}
delete[] pProbabilities[0];
delete[] pProbabilities[1];
}3.扑克牌中的顺子
从扑克牌中随机抽取5张牌,判断是不是一个顺子。A代表1,J-K 11-13,大小王看作任意数字。
思路:首先把数组排序;其次统计0的个数;最后统计排序之后的数组中相邻数字之间的空缺总数。如果空缺的总数小于或等于0的个数,那么此数组连续;否则不连续。另外要注意不能有对子出现。
class Solution {
public:
bool IsContinuous( vector<int> numbers ) {
int len=numbers.size();
if(len!=5) return false;
sort(numbers.begin(),numbers.end());
int num=0;
for(int i=0;i<len&&numbers[i]==0;i++)
{
num++;//统计0的数目
}
int small=num;
int big=small+1;
int sumOfGap=0;
while(big<len)
{
if(numbers[small]==numbers[big])
return false;//出现了对子
sumOfGap+=numbers[big]-numbers[small]-1;//记录二者间的距离
if(sumOfGap>num)//一旦此距离不能用0填,就返回false
return false;
small++;
big++;
}
return true;
}
};

京公网安备 11010502036488号