剑指 Offer 03. 数组中重复的数字
solution
flip num
题目中的所有数字都在 0 ~ n-1 的范围内,所以可以将数组中的所有数字都看作 index。遍历数组,对所有当前指向的数字置为相反数,如果出现 < 0 的数字,说明当前的 index 已经被置为相反数过了,当前的 index 就是一个重复数字。这其中有一个问题是 0,0 的相反数还是 0,所以如果是 0 在 index-0 但是之后又有重复的状况就会判别不出来,所以需要特别处理,比如说 [0, 1, 0]
1 | class Solution: |
swap num
思路是做原地交换, 当前的值与 index 不相等的时候就进行当前值与指向值的交换,知道 nums[i] == nums[nums[i]] , 也就是说当前值和指向值是相等的,这有两种状况。第一种是 i == nums[i],或者 nums[i] == nums[nums[i]] and i != nums[i],第二种状况就是找到了重复值。
1 | class Solution: |
剑指 Offer 04. 二维数组中的查找
solution
搜索思路: [i,j] 左上的所有都是小于 当前数值的,[i,j] 右下的都是大于当前数值的。从右上角开始,如果比当前数值大,说明比本行及其下面的行都大,如果比当前数值小,说明本列及其右都小,所以可以按照如下规则。遇到比 target 小的,向下走一格,遇到比 target 大的,向左走一格。
1 | class Solution: |
剑指 Offer 05. 替换空格
solution
1 | class Solution: |
剑指 Offer 06. 从尾到头打印链表
solution
1 | class Solution: |
剑指 Offer 07. 重建二叉树
solution
两种解法的思路是一致的,以如下列表为例,在前序遍历中,第一个元素一定是当前构建的根节点,在中序遍历中,所有左子树元素一定在根节点的左边,所有右子树元素一定在根节点的右边。通过这两个特性,首先从前序树第一个元素取到根节点,再从中序树中找到根节点,根节点之前的部分就是左子树,根节点之后的部分就是右子树。而左子树的长度是固定的,所以在前序遍历数组中的第一个元素后取同样的长度,就得到了左子树的前序遍历数组。同理可以得到右子树的的相关所需结果。
[3, |9,2,8,| 20,15,7]
[2,9,8,| 3, | 15,20,7]
recursion + list para
1 | class Solution: |
recursion + index para
1 | class Solution: |
test cases
1 | [3,9,20,15,7] |
剑指 Offer 09. 用两个栈实现队列
两个 stak,一个用作 push,一个用作 pop。appendTail 将元素压入 stack 栈,deleteHead 时查看 pop 栈是否还有元素,如果空了就将 push 栈的元素倒入 pop 栈,否则 pop 栈顶的元素。
solution
1 | class CQueue: |
test Cases
1 | ["CQueue","appendTail","deleteHead","deleteHead"] |
剑指 Offer 10- I. 斐波那契数列
solution
iteration
新 python3 可以处理长整数,为了节约时间,只需要在返回前进行 mod 操作
1 | class Solution: |
recursion
recursion 会溢出,使用 lru_cache 来避免这个问题。
1 | from functools import lru_cache |
test cases
1 | 0 |
剑指 Offer 10- II. 青蛙跳台阶问题
solution
与 10-i 同思路,只是停止条件不同
1 | from functools import lru_cache |
剑指 Offer 11. 旋转数组的最小数字
solution
遍历,如果出现了非递增元素,就会是最小的那个。
1 | class Solution: |
备注:因为允许重复数字出现,本题不能使用二分法
比如说 [3,3,3,3,3,3,1,3],无法判断最小值到底是在左边还是在右边
test cases
1 | [1,3,5] |
剑指 Offer 12. 矩阵中的路径
solution
使用 dfs 的思路求解,但需要注意的是两个细节。(a) 重复路径不是通过记录路径,而是通过标记路径,recursion之后再恢复来实现的,这样可以节省空间。(b) dfs 的深度是固定的 len(word),已经遍历 matrix 来作为起始点了,所以遍历的深度不是遍历到无路可走而是没有按位符合 word 中的元素。
dfs + recover node
1 | class Solution: |
test cases
1 | [["a","b"],["c","d"]] |
剑指 Offer 13. 机器人的运动范围
solution
1 | class Solution: |
test cases
1 | 1 |
剑指 Offer 14- II. 剪绳子 II
solution
思路和 14 - I 相同. Python 可以处理任意长度超大整数, 所以在返回前进行 MOD 即可.
1 | class Solution: |
test cases
剑指 Offer 14- I. 剪绳子
solution
trivial dp1
1 | class Solution: |
dp 2
动态规划的思路, 在过程中加入可能的乘数.
1 | class Solution: |
math
拆出尽可能多的 3 直到只剩 2 或者 4
1 | class Solution: |
求导, 最佳是 e
test cases
1 | 2 |
wrong cases
1 | 4 |
剑指 Offer 15. 二进制中1的个数
solution
bit manipulation
1 | class Solution: |
built-in function
1 | class Solution: |
剑指 Offer 16. 数值的整数次方
solution
recursion
recursion 此消彼长, 没有重复计算
1 | from functools import lru_cache |
test cases
1 | 0.00001 |
剑指 Offer 17. 打印从1到最大的n位数
solution
..
1 | class Solution: |
剑指 Offer 18. 删除链表的节点
solution
剑指 offer 的本意是希望以 o(1) 的时间删除链表内部节点的同时,考虑多种情况。(1)目标节点不在尾部且链表长度大于1,(2)目标节点在尾部(3) 链表长度为 1 且目标节点就是头节点。
1 | # Definition for singly-linked list. |
剑指 Offer 19. 正则表达式匹配
solution
dp
1 | dp[i][j]: s[:i+1] - p[:j+1] 的匹配情况 |
1 | class Solution: |
recursion
1 | class Solution: |
test cases
1 | "ab" |
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
solution
使用前后两个指针,维护p_od及之前都为奇数,p_ev及之后都为偶数。如果出现违反当前规则的状况,交换所指向的元素。
1 | class Solution: |
Test Cases
1 | [1,2,3,4] |
剑指 Offer 22. 链表中倒数第k个节点
solution
1 | class Solution: |
test cases
1 | [1,2,3,4,5] |
剑指 Offer 24. 反转链表
solution
从链表头开始遍历,将新的 Node 接在当前新链表之后。
1 | class Solution: |
剑指 Offer 25. 合并两个排序的链表
solution
iteration + 新空间
1 | class Solution: |
recursion
1 | class Solution: |
test cases
1 | [1,2,4] |
剑指 Offer 27. 二叉树的镜像
solution
1 | class Solution: |
test cases
1 | [4,2,7,1,3,6,9] |
剑指 Offer 28. 对称的二叉树
solution
1 | class Solution: |
剑指 Offer 29. 顺时针打印矩阵
solution
题目不困难,但是需要想好 test cases,仔细考虑 edge cases
1 | class Solution: |
test cases
1 | [[1,2,3],[4,5,6],[7,8,9]] |
剑指 Offer 30. 包含min函数的栈
solution
维持一个给 min value 的 stack,如果 push 的元素比栈顶元素小或者等于,就在 min_stack 里压栈。
1 | class MinStack: |
test cases
1 | ["MinStack","push","push","push","min","pop","top","min"] |
剑指 Offer 31. 栈的压入、弹出序列
solution
弄一个新栈,模拟 stack 的操作状况
1 | class Solution: |
test cases
1 | [1,2,3,4,5] |
剑指 Offer 32 - I. 从上到下打印二叉树
solution
1 | class Solution: |
test cases
1 | [3,9,20,null,null,15,7] |
剑指 Offer 32 - II. 从上到下打印二叉树 II
solution
DFS
1 |
|
BFS
1 |
|
test cases
1 | [3,9,20,null,null,15,7] |
剑指 Offer 32 - III. 从上到下打印二叉树 III
solution
BFS
1 | # 在插入元素的时候判断层数,以此判断是从头插入还是从尾插入 |
test cases
1 | [3,9,20,null,null,15,7] |
剑指 Offer 33. 二叉搜索树的后序遍历序列
solution
找到第一个大于 l[-1] 的值作为分割点,保持 left < root < right 的二叉树性质,否则返回 False
1 | import sys |
test cases
1 | [4, 6, 12, 8, 16, 14, 10] |
剑指 Offer 35. 复杂链表的复制
solution
expand and split list
1 | class Solution: |
HashTable + List
1 | class Solution: |
test cases
1 | [[7,null],[13,0],[11,4],[10,2],[1,0]] |
剑指 Offer 36. 二叉搜索树与双向链表
solution
1 | class Solution: |
test cases
剑指 Offer 37. 序列化二叉树
solution
1 | class Codec: |
test cases
1 | [1,2,3,null,null,4,5] |
剑指 Offer 38. 字符串的排列
solution
1 | class Solution: |
test cases
1 | "abc" |
剑指 Offer 39. 数组中出现次数超过一半的数字
solution
sort
1 | class Solution: |
counting
1 | class Solution: |
test cases
1 | [1,2,3,2,2,2,5,4,2] |
剑指 Offer 40. 最小的k个数
solution
heap
1 | from heapq import * |
1 | from heapq import * |
divide + conquer
1 | import random |
test cases
剑指 Offer 41. 数据流中的中位数
solution
heapq
1 | from heapq import * |
test cases
1 | ["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"] |
剑指 Offer 42. 连续子数组的最大和
solution
dp
1 | dp[i] 以 index i 为结尾的连续子数组的最大和 |
1 | class Solution: |
test cases
1 | [-2,1,-3,4,-1,2,1,-5,4] |
剑指 Offer 43. 1~n 整数中 1 出现的次数
solution
recursion
1 | class Solution: |
test cases
1 | 12 |
剑指 Offer 44. 数字序列中某一位的数字
solution
1 | from functools import cmp_to_key |
test cases
1 | [3,20,333,20,33,32,34,1] |
剑指 Offer 46. 把数字翻译成字符串
solution
DP
1 |
|
DFS
1 | class Solution: |
test cases
1 | 80870304 |
剑指 Offer 47. 礼物的最大价值
solution
1 | class Solution: |
test cases
1 | [[1,3,1],[1,5,1],[4,2,1]] |
剑指 Offer 48. 最长不含重复字符的子字符串
solution
Set + Sliding window
1 | class Solution: |
test cases
1 | "abbccddsseessewwsawssdsddwefdosajf" |
剑指 Offer 49. 丑数
solution
dp1
1 | class Solution: |
dp2
1 | class Solution: |
brute force
1 | class Solution: |
test cases
剑指 Offer 50. 第一个只出现一次的字符
solution
OrderedDict
1 | from collections import OrderedDict |
HashTable + list
1 | from collections import defaultdict |
test cases
solution
merge sort
1 | class Solution: |
test cases
1 | [7,5,6,4] |
剑指 Offer 52. 两个链表的第一个公共节点
solution
1 | # Definition for singly-linked list. |
test cases
1 | 8 |
other
- object 相等的比较:需要实现
__ eq __
类: https://stackoverflow.com/questions/14836228/is-there-a-standardized-method-to-swap-two-variables-in-python - is vs == : https://stackoverflow.com/questions/15008380/double-equals-vs-is-in-python
剑指 Offer 53 - I. 在排序数组中查找数字 I
solution
bisect
1 | from bisect import * |
binary search
1 | from bisect import * |
test cases
1 | [5,7,7,8,8,10] |
剑指 Offer 53 - II. 0~n-1中缺失的数字
solution
math
1 | class Solution: |
binary search
1 | class Solution: |
test cases
1 | [0,1,3] |
剑指 Offer 54. 二叉搜索树的第k大节点
solution
1 | class Solution: |
test cases
1 | [5,3,6,2,4,null,null,1] |
剑指 Offer 55 - I. 二叉树的深度
solution
1 | class Solution: |
test cases
1 | [3,9,20,null,null,15,7] |
剑指 Offer 55 - II. 平衡二叉树
solution
1 | class Solution: |
test case
1 | [3,9,20,null,null,15,7] |
剑指 Offer 56 - I. 数组中数字出现的次数
solution
bit manipulation
1 | class Solution: |
test cases
剑指 Offer 56 - II. 数组中数字出现的次数 II
solution
1 | class Solution: |
test cases
1 | [3,4,3,3] |
剑指 Offer 57. 和为s的两个数字
solution
traverse
1 | class Solution: |
two pointers
1 | class Solution: |
test cases
1 | [14,15,16,22,53,60] |
剑指 Offer 57 - II. 和为s的连续正数序列
solution
1 | class Solution: |
test cases
1 | 1 |
剑指 Offer 58 - I. 翻转单词顺序
solution
split
1 | class Solution: |
stack
1 | class Solution: |
test cases
1 | "the sky is blue" |
剑指 Offer 58 - II. 左旋转字符串
solution
1 | class Solution: |
test cases
1 | "abcdefg" |
剑指 Offer 59 - I. 滑动窗口的最大值
solution
deque
1 | from collections import deque |
test cases
1 | [1,3,-1,-3,5,3,6,7] |
剑指 Offer 59 - II. 队列的最大值
solution
1 | class MaxQueue: |
test cases
1 | ["MaxQueue","push_back","push_back","max_value","pop_front","max_value"] |
剑指 Offer 60. n个骰子的点数
solution
DP
1 | class Solution: |
剑指 Offer 61. 扑克牌中的顺子
solution
1 | class Solution: |
test cases
1 | [1,2,1,4,3] |
剑指 Offer 62. 圆圈中最后剩下的数字
solution
array
1 | class Solution: |
dp
1 | class Solution: |
test cases
1 | 5 |
剑指 Offer 63. 股票的最大利润
solution
1 | class Solution: |
test cases
1 | [7,1,5,3,6,4] |
剑指 Offer 64. 求1+2+…+n
solution
and operator
利用了 python and,如果前半部分为 True,后半部分就不会再做比较的性质。
1 | class Solution: |
ref : LCCN 评论区
test cases
1 | 3 |
剑指 Offer 65. 不用加减乘除做加法
solution
bit manipulation
1 | class Solution: |
cr. KrahetsL6
test cases
1 | 1 |
剑指 Offer 66. 构建乘积数组
solution
recursion
1 | class Solution: |
test cases
1 | [1, 2, 3, 4, 5] |
剑指 Offer 67. 把字符串转换成整数
solution
array
1 | class Solution: |
test cases
1 | "42" |
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
solution
brute force
1 | class Solution: |
search
这道题讲真碰到好几次了,每次都忘记考虑搜索树这个问题!!!
1 | class Solution: |
test cases
1 | [6,2,8,0,4,7,9,null,null,3,5] |
剑指 Offer 68 - II. 二叉树的最近公共祖先
solution
brute force
1 | class Solution: |
recursion
1 | class Solution: |
test cases
1 | [3,5,1,6,2,0,8,null,null,7,4] |