From 1710300eb5317624022e08258f366920bdb6c5ac Mon Sep 17 00:00:00 2001 From: haiker2011 Date: Thu, 27 Sep 2018 20:31:45 +0800 Subject: [PATCH] add #9 python implement --- notes/面试总结.md | 204 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/notes/面试总结.md b/notes/面试总结.md index a6704fbe..c83951f4 100644 --- a/notes/面试总结.md +++ b/notes/面试总结.md @@ -7,6 +7,11 @@ * [6. 从尾到头打印链表](#6-从尾到头打印链表) * [7. 重建二叉树](#7-重建二叉树) * [8. 二叉树的下一个结点](#8-二叉树的下一个结点) +* [9. 用两个栈实现队列](#9-用两个栈实现队列) +* [10.1 斐波那契数列](#101-斐波那契数列) +* [10.2 跳台阶](#102-跳台阶) +* [10.3 矩形覆盖](#103-矩形覆盖) +* [10.4 变态跳台阶](#104-变态跳台阶) * [参考文献](#参考文献) @@ -551,7 +556,206 @@ def GetNext(self, pNode): # pNode not have the next node return None ``` +# 9. 用两个栈实现队列 +[NowCoder](https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 题目描述 + +用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。 + +## 解题思路 + +in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。 + +

+ +```java +Stack in = new Stack(); +Stack out = new Stack(); + +public void push(int node) { + in.push(node); +} + +public int pop() throws Exception { + if (out.isEmpty()) + while (!in.isEmpty()) + out.push(in.pop()); + + if (out.isEmpty()) + throw new Exception("queue is empty"); + + return out.pop(); +} +``` + +```python +# -*- coding:utf-8 -*- +class Solution: + def __init__(self): + self.stack1 = [] + self.stack2 = [] + def push(self, node): + # write code here + self.stack1.append(node) + def pop(self): + # return xx + if self.stack2 == []: + while self.stack1: + self.stack2.append(self.stack1.pop()) + return self.stack2.pop() + return self.stack2.pop() +``` +# 10.1 斐波那契数列 + +[NowCoder](https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 题目描述 + +求斐波那契数列的第 n 项,n <= 39。 + +

+ +## 解题思路 + +如果使用递归求解,会重复计算一些子问题。例如,计算 f(10) 需要计算 f(9) 和 f(8),计算 f(9) 需要计算 f(8) 和 f(7),可以看到 f(8) 被重复计算了。 + +

+ +递归是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。 + +```java +public int Fibonacci(int n) { + if (n <= 1) + return n; + int[] fib = new int[n + 1]; + fib[1] = 1; + for (int i = 2; i <= n; i++) + fib[i] = fib[i - 1] + fib[i - 2]; + return fib[n]; +} +``` + +考虑到第 i 项只与第 i-1 和第 i-2 项有关,因此只需要存储前两项的值就能求解第 i 项,从而将空间复杂度由 O(N) 降低为 O(1)。 + +```java +public int Fibonacci(int n) { + if (n <= 1) + return n; + int pre2 = 0, pre1 = 1; + int fib = 0; + for (int i = 2; i <= n; i++) { + fib = pre2 + pre1; + pre2 = pre1; + pre1 = fib; + } + return fib; +} +``` + +由于待求解的 n 小于 40,因此可以将前 40 项的结果先进行计算,之后就能以 O(1) 时间复杂度得到第 n 项的值了。 + +```java +public class Solution { + private int[] fib = new int[40]; + + public Solution() { + fib[1] = 1; + fib[2] = 2; + for (int i = 2; i < fib.length; i++) + fib[i] = fib[i - 1] + fib[i - 2]; + } + + public int Fibonacci(int n) { + return fib[n]; + } +} +``` + +```python + +``` +# 10.2 跳台阶 + +[NowCoder](https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=13&tqId=11161&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 题目描述 + +一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 + +## 解题思路 + +```java +public int JumpFloor(int n) { + if (n <= 2) + return n; + int pre2 = 1, pre1 = 2; + int result = 1; + for (int i = 2; i < n; i++) { + result = pre2 + pre1; + pre2 = pre1; + pre1 = result; + } + return result; +} +``` + +```python + +``` +# 10.3 矩形覆盖 + +[NowCoder](https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6?tpId=13&tqId=11163&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 题目描述 + +我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法? + +## 解题思路 + +```java +public int RectCover(int n) { + if (n <= 2) + return n; + int pre2 = 1, pre1 = 2; + int result = 0; + for (int i = 3; i <= n; i++) { + result = pre2 + pre1; + pre2 = pre1; + pre1 = result; + } + return result; +} +``` + +```python + +``` +# 10.4 变态跳台阶 + +[NowCoder](https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&tqId=11162&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 题目描述 + +一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 + +## 解题思路 + +```java +public int JumpFloorII(int target) { + int[] dp = new int[target]; + Arrays.fill(dp, 1); + for (int i = 1; i < target; i++) + for (int j = 0; j < i; j++) + dp[i] += dp[j]; + return dp[target - 1]; +} +``` + +```python + +``` # 参考文献