1.用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
考察知识点:队列、栈、STL
问题分析:首先明确栈的特点是先进后出,队列的特点是先进先出。c++标准库中已经实现了栈和队列,这里的题意是让你使用两个在c++ STL中实现的栈来完成先进先出的功能。题解其实很简单:有两个栈1、栈2,栈1的top元素逐一取出并放到栈2,再从栈2中取元素,就实现了先进先出。只不过有一点需要注意,新加入的元素要先放到栈1中,等栈2中的元素取完之后才能再重新从栈1取所有新放进来的元素。即栈1起到一个缓冲的效果,栈2中拿到的元素即实现了队列的功能。
栈的使用方法如下:
#include<stack>
stack< int > s; //注意:栈可理解为上下结构,上边的元素是后push进去的。
s.push(item); //将item压入栈的上边
s.pop; //删除栈顶的元素,但不返回
s.top; //返回栈顶的元素,但不会删除
s.size(); //返回栈的大小,但不会删除
s.empty; //返回栈是否为空
队列的使用方法如下:
#include<queue>
queue< int > q; //注意:队列可理解为左右(前后)结构,左边(前边)的是后push进去的。
q.push(item) //将item压入队列尾部
q.pop() //删除队首元素,但不返回
q.front() //返回队首元素,但不删除
q.back() //返回队尾元素,但不删除
q.size() //返回队列中元素的个数
q.empty() //返回队列是否为空
解题方法:
class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
if(stack2.empty()){ //如果栈2不是空,则不进入if语句,在栈2直接取。
while(!stack1.empty()){//while循环里边的代码块实现将栈1中所有的元素取出放到栈2中,记得pop栈1元素
stack2.push(stack1.top());
stack1.pop();
}
}
int ret = stack2.top();
stack2.pop();
return ret;
}
private:
stack<int> stack1;
stack<int> stack2;
};
2.大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1),n≤39。
考察知识点:递归、动态规划
问题分析:首先明确斐波那契数列是什么。斐波那契数列描述:第0项是0,第1项是第一个1,这个数列从第3项开始,每一项都等于前两项之和(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368)。递归方法可以很容易的解决这个问题,但比较耗时,使用动态规划的方法可以在增加少量内存的情况下提速。
动态规划讲的比较好的博客:https://blog.csdn.net/baidu_28312631/article/details/47418773
解题方法一:递归
class Solution {
public:
int Fibonacci(int n) {
if(n == 0 || n == 1) return n;
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
};
解题方法二:动态规划
class Solution {
public:
int Fibonacci(int n) {
vector<int> dp(n+1, 0);
dp[1] = 1;
for(int i=2; i<=n; ++i){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
};
3.输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。如输入:{1,3,5},{2,4,6},返回值:{1,2,3,4,5,6}。
考察知识点:链表
问题分析:下边代码为程序中给出的链表节点结构体。一般创建单链表,都会设一个虚拟头结点,也叫哨兵,因为这样每一个结点都有一个前驱结点,然后返回该虚拟头结点的next即为我们要的新链表。表。新链表代码:ListNode* pHead = new ListNode(-1);
,然后定义cur指针来依次连接新链表,cur指针初始指向头节点:ListNode* cur = pHead;
。还有一点要注意:在链表中,结点指针后的“=”可理解为“指向”,并非赋值。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
解题方法:
Class Solution{
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2){
ListNode* pHead = new ListNode;
ListNode* cur = pHead;
while(pHead1 && pHead2){ //直到短的那个链表的结点指针指向NULL,跳出循环
if(pHead1.val <= pHead2.val){ //如果pHead1的第一个结点值较小
cur->next = pHead1; //当前指针的next指针指向pHead1
pHead1 = pHead1->next; //pHead1指针后移一位
}else if(pHead1.val <= pHead2.val){
cur->next = pHead2;
pHead2 = pHead2->next;
}
cur = cur->next; //当前指针后移到下一位
}
cur-> = pHead1 ? pHead1 : pHead2;
return pHead->next;
}
}
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
考察知识点: