* 动态规划(简单)
1、剑指 Offer 10- I. 斐波那契数列
- 代码
2、剑指 Offer 10- II. 青蛙跳台阶问题
- 代码
3、剑指 Offer 63. 股票的最大利润
- 代码
复杂度分析
时间复杂度:O(n),只需要遍历一次。 空间复杂度:O(1),只使用了常数个变量。
-
动态规划(中等)
1、剑指 Offer 42. 连续子数组的最大和
- 题目
- 代码
2、剑指 Offer 47. 礼物的最大价值
- 题目 (有点难 ) 二维数组 生成过程 剑指 Offer 47. 礼物的最大价值
解题思路
dp[i][j]含义:
从(0,0)移动到(i,j),可以拿的最大价值为dp[i][j]dp数组初始化:
(0,0)位置肯定还是原来的值。
第一行(i,0):只能从左边走到该位置,所以dp[i][0] = dp[i - 1][0] + grid[i][0]
第一列(0,j):只能从上边走到该位置,所以dp[0][j] = dp[0][j - 1] + grid[0][j]
递推公式:
对于除了第一行、第一列的dp[i][j],可以有两个地方走到这里,上边和左边,取他们的最大值,再加上当前位置的价值
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
遍历顺序:
当前值依赖于上边的值、左边的值,所以从左往右、从上到下,一行一行遍历
- 代码
3、剑指 Offer 46.把数字翻译成字符串
- 题目
-
代码
解题思路 大概思路: 1 如果数字中所有的连续两个数字组合起来都比25 要大, 说明只有一种翻译方法 比如 555 只能翻译成 f f f 2 如果连续连个相邻数字组合成的数字比10 小, 说明这两个数字也只有一种翻译方法。 比如 501 只能翻译成 f a b 3 当相邻的两个数字组合成的数字 10 <= num <= 25 时, dp[i] = dp[i-1] + dp[i-2] (i>1)
4、 无重复最长字符串
- 题目
- 代码
解题思路
使用滑动窗口算法;
当遇到重复字符的时候删除重复字符前面(包括这个重复字符)的所有字符;
记录达到不重复的最长子字符长度;
循坏之后有更长的不重复子串就更新我们的不重复最大子字符串长度;
代码
-
双指针(简单)
1、剑指 Offer 18. 删除链表的节点
- 题目
- 代码
解题思路
定义虚拟节点,用指针遍历链表
如果下一个值等于val,则删除下一个值
使用了ES6的?.运算符
2、剑指 Offer 22. 链表中倒数第k个节点
- 题目
- 代码
思路与算法
最简单直接的方法即为顺序查找,假设当前链表的长度为 nn,则我们知道链表的倒数第 kk 个节点即为正数第 n - kn−k 个节点,此时我们只需要顺序遍历到链表的第 n - kn−k 个节点即为倒数第 kk 个节点。
我们首先求出链表的长度 nn,然后顺序遍历到链表的第 n - kn−k 个节点返回即可。
3、剑指 Offer 25. 合并两个排序的链表
- 代码
4、剑指 Offer 52. 两个链表的第一个公共节点
- 题目
- 代码
思路和算法
判断两个链表是否相交,可以使用哈希集合存储链表节点。
首先遍历链表 \textit{headA}headA,并将链表 \textit{headA}headA 中的每个节点加入哈希集合中。然后遍历链表 \textit{headB}headB,对于遍历到的每个节点,判断该节点是否在哈希集合中:
如果当前节点不在哈希集合中,则继续遍历下一个节点;
如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都是两个链表的公共节点,因此在链表 \textit{headB}headB 中遍历到的第一个在哈希集合中的节点就是两个链表的第一个公共节点,返回该节点。
如果链表 \textit{headB}headB 中的所有节点都不在哈希集合中,则两个链表不相交,返回 \text{null}null。
5、剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
- 代码
- sort 竟然还可以这样用
6、剑指 Offer 57. 和为s的两个数字
- 代码
解题思路
既然是递增数组,那么我们可以利用双指针来做这道题。
指针 ii 指向数组首位数字,指针 jj 指向数组末位数字。
若两数字之和大于了 targettarget,则指针 jj 往左移一位。
若两数字之和小于了 targettarget,则指针 ii 往右移一位。
若两数字之和等于了 targettarget,返回结果 [i, j][i,j] 即可。
7、剑指 Offer 58 - I. 翻转单词顺序
- 代码
解题思路
1、先用空格分隔为数组
2、用另一个数组存放倒过来的顺序
3、返回字符串