1.最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。
示例:
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-stack
思路:利用辅助栈
class MinStack { stack<int> s1; stack<int> sMin;//这两个在public之前写 public: /** initialize your data structure here. */ MinStack() { sMin.push(INT_MAX);//先放入一个无穷大 } void push(int x) { s1.push(x); if(!sMin.empty()&&s1.top()<sMin.top()) { sMin.push(s1.top()); } else { sMin.push(sMin.top()); } } void pop() { s1.pop(); sMin.pop(); } int top() { return s1.top(); } int getMin() { return sMin.top(); } }; /** * Your MinStack object will be instantiated and called as such: * MinStack* obj = new MinStack(); * obj->push(x); * obj->pop(); * int param_3 = obj->top(); * int param_4 = obj->getMin(); */
2.丑数
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路:因为丑数只包含质因子2,3和5,因此后面的质因子一定是前面的质因子乘以这三个数产生的,所以我们设置三个位置p2,p3和p5,由前面的丑数来推后面的丑数。
class Solution { public: int GetUglyNumber_Solution(int index) { if(index<=0) return 0; vector<int> res; int num=1; res.push_back(num);//先放入第一个丑数 int p2=0,p3=0,p5=0; while(res.size()<index) { int num=min(res[p2]*2,min(res[p3]*3,res[p5]*5));//找最小的 res.push_back(num); while(res[p2]*2<=num) p2++; while(res[p3]*3<=num) p3++; while(res[p5]*5<=num) p5++;//更新区间 } return res.back(); } };
3.第一个只出现一次的字符
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
class Solution { public: int FirstNotRepeatingChar(string str) { if(str.length()<=0) return -1; //利用数组实现哈希表,key是下标,value是数组的值 int alpha[256]={0}; for(int i=0;str[i]!='\0';i++) { alpha[str[i]]++;//记录次数 } for(int i=0;str[i]!='\0';i++) { if(alpha[str[i]]==1) return i;//返回第一个 } return -1; } };
4.数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。即输出P%1000000007
思路:基于归并排序的统计
class Solution { public: int InversePairs(vector<int> data) { int length=data.size(); if(length<=0) return 0; vector<int> copy; for(int i=0;i<length;i++) copy.push_back(data[i]); long long count=InversePairsCore(data,copy,0,length-1); //假设是7564,先分为75,64,再分为7,5,6,4,合并成57,46产生两个逆序对,然后合并成4567,产生三个逆序对 return count%1000000007; } long long InversePairsCore(vector<int> &data,vector<int> ©,int start,int end) { if(start==end) { copy[start]=data[start]; return 0; } int length=(end-start)/2;//二分 long long left=InversePairsCore(copy,data,start,start+length);//57 long long right=InversePairsCore(copy,data,start+length+1,end); //46 int i=start+length; int j=end; int indexcopy=end; long long count=0; while(i>=start&&j>=start+length+1)//从后往前找 { if(data[i]>data[j]) { copy[indexcopy--]=data[i--]; count=count+j-start-length; //count=count+j-(start+length+1)+1; }//i大于j前面所有的数,7大于6,那么就大于4和6 else { copy[indexcopy--]=data[j--];//5小于6,放入6,没有逆序对 } } for(;i>=start;i--) copy[indexcopy--]=data[i]; for(;j>=start+length+1;j--) copy[indexcopy--]=data[j]; return left+right+count; } };