1. 用两个栈实现队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
if(stack2.empty()){
while(!stack1.empty()){
stack2.push(stack1.top());
stack1.pop();
}
}
int res = stack2.top();
stack2.pop();
return res;
}
private:
stack<int> stack1;
stack<int> stack2;
};
2.包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
class Solution {
private:
stack<int> m_data;
stack<int> m_min;
public:
void push(int value) {
m_data.push(value);
if(m_min.empty() || value<m_min.top())
m_min.push(value);
else
m_min.push(m_min.top());
}
void pop() {
m_data.pop();
m_min.pop();
}
int top() {
return m_data.top();
}
int min() {
return m_min.top();
}
};
3. 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
bool res = false;
if(pushV.size()!=popV.size()||popV.empty()||pushV.empty())
return res;
stack<int>data;
int index1=0,index2=0;
while(index1<pushV.size()){
data.push(pushV[index1++]);
while(index2<popV.size()&&data.top()==popV[index2]){
++index2;
data.pop();
}
}
if(index2==popV.size() && data.empty())
res = true;
return res;
}
};
4.滑动窗口的最大值
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
class Solution {
public:
void push(list<int>& q_max,int val){//完成插入元素,确保其中值都有成为某一个窗口最大值的潜力
while(!q_max.empty() && q_max.back()<val)
q_max.pop_back();
q_max.push_back(val);
}
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
if(nums.size()<k || k<1) return res;
list<int> q_max;//辅助队列
for(int i=0;i<k;++i)
push(q_max,nums[i]);
for(int i=k;i<nums.size();++i){
res.push_back(q_max.front());//第i-k个窗口的最大值
if(q_max.front()==nums[i-k])
q_max.pop_front();
push(q_max,nums[i]);//插入下一个元素,求第i-k+1窗口的最大值
}
res.push_back(q_max.front());//别忘了最后一个窗口的最大值
return res;
}
};
5. 扑克牌顺子
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
class Solution {
public:
bool IsContinuous( vector<int> numbers ) {
if(numbers.empty())
return false;
sort(numbers.begin(),numbers.end());
int numofzero = 0;
int numofgap = 0;
for(int i=0;i<numbers.size()&&numbers[i]==0;++i)
++numofzero;
int small = numofzero;
int big = small+1;
while(big<numbers.size()){
if(numbers[small]==numbers[big])
return false;
numofgap += numbers[big]-numbers[small]-1;
small = big;
++big;
}
return (numofzero>=numofgap)?true:false;
}
};
6.圆圈中最后剩下的数
从0开始
class Solution {
public:
//模拟法,效率不高会超时
int lastRemaining(int n, int m) {
if(n<=0 || m<=0) return -1;
list<int> nums;
for(int i=0;i<n;++i){
nums.push_back(i);//构建模拟数组
}
int c= (m-1)%n;//第一个要删除的数的下标,本来应该是c=(0+m-1)%n;
while(nums.size()>1){//当数组中的数大于时不停的迭代执行
auto iter=nums.begin();
for(int i=0;i<c;++i) ++iter;//找到要删除元素的迭代器
nums.erase(iter);//删除它
c = (c+m-1)%nums.size();//继续求下一个待删除元素的下标
}
return nums.front();
}
};
//约瑟夫环数学解法,由递推公式求解
class Solution {
public:
int lastRemaining(int n, int m) {
//f(n,m) = (f(n-1,m)+m)%n; //n为当前数列长
int flag = 0;
for(int i=2;i<=n;++i){
flag = (flag+m)%i;
}
return flag;
}
};
7. 字符流中第一个不重复的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。如果当前字符流没有存在出现一次的字符,返回#字符。
class Solution
{
public:
//Insert one char from stringstream
void Insert(char ch)
{
s +=ch;
map[ch]++;
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
for(auto c:s){
if(map[c]==1)
return c;
}
return '#';
}
private:
unordered_map<char,int> map;
string s;
};
8.丑数
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
class Solution {
public:
int mine(int u2, int u3, int u5){
int min = (u2<u3)?u2:u3;
min = (min<u5)?min:u5;
return min;
}
int GetUglyNumber_Solution(int index) {
if(index<1)
return 0;
vector<int> res;
res.push_back(1);
int uglys = 1;
int u2=0,u3=0,u5=0;
while(uglys<index){
int min = mine(res[u2]*2,res[u3]*3,res[u5]*5);
res.push_back(min);
while(res[u2]*2<=res[uglys])
++u2;
while(res[u3]*3<=res[uglys])
++u3;
while(res[u5]*5<=res[uglys])
++u5;
++uglys;
}
return res.back();
}
};