一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
今天来看两题,分别是 剑指 Offer 09. 用两个栈实现队列 和 剑指 Offer 10- I. 斐波那契数列 。
用两个栈实现队列
题目:本题要求使用两个栈来实现一个队列,要求实现在队列的尾部插入元素,在队列的头部删除元素(若队列没有元素则返回-1)。
解题思路
题目已经要求必须使用两个栈,因此我们需要使用两个栈来进行考虑。尾部插入元素很简单,直接将元素入栈即可,而头部删除元素则需要保证另一个栈的栈首是队列的头(因为我们只能删除栈顶元素),因此我们可以保证两个栈一个为输入栈,另一个是输出栈,当插入元素时直接将元素入栈输入栈,当要删除元素时,则首先判断输出栈是否为空,如果为空则将输入栈元素出栈入输入栈,之后删除即可,代码如下:
class CQueue{
private Stack<Integer> stack1;
private Stack<Integer> stack2;
public CQueue(){
stack1 = new Stack<Integer>();
stack2 = new Stack<Integer>();
}
public void appendTail(int value){
stack1.push(value);
}
public int deleteHead(){
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.isEmpty()?-1:stack2.pop();
}
}
值得注意的是,Java中栈的使用选择也是有比较的,相比于ArrayDeque,Stack的效率是明显不如的,因此将上述栈改为:
private ArrayDeque<Integer> stack1;
private ArrayDeque<Integer> stack2;
public CQueue(){
stack1 = new ArrayDeque<Integer>();
stack2 = new ArrayDeque<Integer>();
}
关于栈的使用,可以看这里: 为什么不推荐 ArrayDeque 代替 Stack 。
斐波那契数列 I
题目,给定斐波那契数列表达式,要求输出其第n项,每项的答案都对 1e9+7(1000000007) 取模。
解题思路
经典动态规划问题,很好解决,代码如下:
public int fib(int n) {
if(n<2) return n;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for(int i=2;i<=n;i++){
dp[i] = (dp[i-1] + dp[i-2])%1000000007;
}
return dp[n];
}
时间复杂度和空间复杂度都是,因为每次只用到了前面两个数,因此我们可以用变量维护前面两个数,这样空间复杂度就降下来了,代码如下:
public int fib(int n){
if(n<2) return n;
int a=0,b=1;
int c = 0;
for(int i=2;i<=n;i++){
c = (a+b) %1000000007;
a = b;
b = c;
}
return c;
}