本文将针对剑指offer题目按照章节进行讲解。
题目表
题号 | 是否掌握 | 题号 | 是否掌握 | 题号 | 是否掌握 |
---|---|---|---|---|---|
3 | * | 27 | 50 | * | |
4 | * | 28 | 51 | ||
5 | 29 | 52 | * | ||
6 | * | 30 | 53-1 | ||
7 | 31 | 53-2 | |||
8 | 32-1 | * | 54 | ||
9 | 55-1 | * | |||
10-1 | 32-3 | 55-2 | |||
10-2 | 33 | * | 56-1 | ||
11 | 34 | 56-2 | |||
12 | 35 | - | 57 | ||
13 | 36 | 57-2 | |||
14-1 | 37 | 58-1 | |||
14-2 | 38 | 58-2 | |||
15 | 39 | 59-1 | |||
16 | 40 | 59-2 | |||
17 | 41 | 60 | |||
18 | 42 | 61 | |||
19 | 43 | 62 | |||
20 | 44 | 63 | |||
21 | 45 | 64 | |||
22 | 46 | 65 | |||
24 | 47 | 66 | * | ||
25 | 48 | 67 | |||
26 | 49 | 68-1 |
第二章
数组中重复的数字
1 | int findRepeatNumber(vector<int>& nums) { |
二维数组中的查找
1 | bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) { |
替换空格
1 | string replaceSpace(string s) { |
从尾到头打印链表
1 | vector<int> reversePrint(ListNode* head) { |
二叉树重建*
1 | TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { |
用两个栈实现队列
1 | class CQueue { |
旋转数组的最小数字*
1 | int minArray(vector<int>& numbers) { |
矩阵中的路径
1 | bool exist(vector<vector<char>>& board, string word) { |
剪绳子
1 |
数值的整数次方
1 | double myPow(double x, int n) { |
删除链表的结点
1 | void DeleteNode(ListNode** head, ListNode* toBeDeleted){ |
链表倒数第K个节点
1 | ListNode* getKthFromEnd(ListNode* head, int k) { |
环的入口节点
1 |
反转链表
1 | ListNode* reverseList(ListNode* head) { |
不使用+-*/实现加法
1 | int add(int a, int b) { |
第四章
二叉树中和为某一路径的值
1 | void dfs(vector<vector<int>>& ans, |
复杂链表的复制
1 | class Solution { |
第五章
把数组排成最小的数
1 | static bool cmp(string a, string b) |
最长不含重复字符的子字符串
1 | class Solution { |
二叉树类题目
对称二叉树
题目描述
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
解答
1 | //解法一:递归 |
二叉树的深度
题目描述
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
解答
- 递归法
- 迭代法
数学
不使用+-×/实现加法
解答
13二进制为:1101,9二进制为:1001。
十进制是遇到大于等于10就保留余数,然后进位1。
那对应到二进制,就是遇到2就保留余数0,然后进位1。(二进制位之和不可能大于2)计算二进制1101+1001:
1.计算不进位的和。从左到右,第1位为0,第2位为1,第3位为0,第4位为0,结果为0100;
2.计算进位。从左到右,第1位进位1,第2、3位没有进位,第4位进位1,结果为1001。不对,进位右边要补0,正确结果是10010。计算二进制0100+10010:
1.计算不进位的和:10110;
2.计算进位:无。因此结果为10110=22。
1)分析上面对二进制的计算过程,不难发现:
1.计算不进位的和,相当于对两个数进制异或:1101^1001=0100;
2.计算进位,第1位相当于对两个数求与:1101&1001=1001,然后再对其进行左移1位:1001<<1=10010。
然后再重复以上两个步骤。这里再异或一次就得到结果了,没进位:0100^10010=10110=22。
2)计算a+b,等价于(a^b)+((a&b)<<1)。 由于公式中又出现了+号,因此要再重复2)这个等价的计算过程。 结束条件是:没有进位了1</sup>。1)。>
1 | int add(int a, int b) { |
快速幂
1 | int fast_pow(long long base,int index){ |
快速幂本质是通过二分法对幂指数进行求解,上面是快速幂的模板,需要牢记