如:题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。
诸如此类的操做,接下来我开始带着大家进入算法的乐园
首先看看我们的题目大概分为哪几类
注意:本文的通用类,如ListNode的定义均在common包中
点击此处查找
int []nums={2,1,5,3,7,9,0}
int max=Arrays.stream(nums).max().getAsInt();//数组获取最大值
List<Integer> list=//数组转list
做题思路:
利用逼近的方法逐渐靠近我们需要的结果,首先设置高低位,通过与mid即中间值的对比来进行相应的操作
题目类型:
一般对有序的数组进行操作时可以先考虑使用二分查找法
题目实例:
题目编号 | 题目名称 | 题目链接 | 代码链接 |
---|---|---|---|
704 | 二分查找 | https://leetcode-cn.com/problems/binary-search/ | 点击查看 |
278 | 第一个错误版本 | https://leetcode-cn.com/problems/first-bad-version/ | 点击查看 |
35 | 搜索插入位置 | https://leetcode-cn.com/problems/search-insert-position/ | 点击查看 |
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
34 | 在排序数组中查找元素的第一个和最后一个位置 | https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/ | 点击查看 | 暂无解析 |
33 | 搜索旋转排序数组 | https://leetcode-cn.com/problems/search-in-rotated-sorted-array/ | 点击查看 | 暂无解析 |
74 | 搜索二维矩阵 | https://leetcode-cn.com/problems/search-a-2d-matrix/ | 点击查看 | 暂无解析 |
153 | 寻找旋转排序数组中的最小值 | https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/ | 点击查看 | 点击查看 |
162 | 寻找峰值 | https://leetcode-cn.com/problems/find-peak-element/ | 点击查看 | 暂无解析 |
做题思路:
i指向起始位置,j指向终止位置。
定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。
如果A[i]*A[i] 如果A[i] * A[i] >= A[j] * A[j] 那么result[k–] = A[i] * A[i];
总而言之一句话:务必保证K指向的位置存的都是较大的一个数
如图所示:
题目类型:
数组有序的,而且最大或最小值在数组两端。
题目实例:
题目编号 | 题目名称 | 题目链接 | 代码链接 |
---|---|---|---|
189 | 轮转数组 | https://leetcode-cn.com/problems/rotate-array/ | 点击查看 |
977 | 有序数组的平方 | https://leetcode-cn.com/problems/squares-of-a-sorted-array/ | 点击查看 |
283 | 移动0 | https://leetcode-cn.com/problems/move-zeroes/ | 点击查看 |
167 | 两数之和 II - 输入有序数组 | https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/ | 点击查看 |
344 | 反转字符串 | https://leetcode-cn.com/problems/reverse-string/ | 点击查看 |
557 | 反转字符串中的单词 III | https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/ | 点击查看 |
876 | 链表的中间结点 | https://leetcode-cn.com/problems/middle-of-the-linked-list/ | 点击查看 |
19 | 删除链表第N个结点 | https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/ | 点击查看 |
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
82 | 删除排序链表中的重复元素2 | https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/ | 点击查看 | 暂无解析 |
15 | 三数之和 | https://leetcode-cn.com/problems/3sum/ | 点击查看 | 暂无解析 |
844 | 比较含退格的字符串 | https://leetcode-cn.com/problems/backspace-string-compare/ | 点击查看 | 暂无解析 |
11 | 盛最多水的容器 | https://leetcode-cn.com/problems/container-with-most-water/ | 点击查看 | 暂无解析 |
986 | 区间列表的交集 | https://leetcode-cn.com/problems/interval-list-intersections/ | 点击查看 | 暂无解析 |
做题思路:
此类题目我们一般采用哈希表或相邻元素比较等方式来实现
题目实例:
题目编号 | 题目名称 | 题目链接 | 代码链接 |
---|---|---|---|
217 | 存在重复元素 | https://leetcode-cn.com/problems/contains-duplicate/ | 点击查看 |
1 | 两数之和 | https://leetcode-cn.com/problems/two-sum/ | 点击查看 |
88 | 合并两个有序数组 | https://leetcode-cn.com/problems/merge-sorted-array/ | 点击查看 |
做题思路:
动态规划的思想通过解决了一个一个简单的问题,进而把简单的问题的解组成了复杂的问题的解
题目实例:
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
53 | 最大子数组和 | https://leetcode-cn.com/problems/maximum-subarray/ | 点击查看 | 点击查看 |
77 | 爬楼梯 | https://leetcode-cn.com/problems/climbing-stairs/ | 点击查看 | 点击查看 |
198 | 打家劫舍 | https://leetcode-cn.com/problems/house-robber/ | 点击查看 | 点击查看 |
120 | 三角形最小路径和 | https://leetcode-cn.com/problems/triangle/ | 点击查看 | 暂无解析 |
做题思路:
什么是滑动窗口?
就是将元素一个又一个的放入队列中,其中队列就是我们所说的窗口,如无重复字符的最长子串中abcabcbb的最长子串:
- 当abc依次进入队列之后,此时的最大值max=3
- a又进入了一次,此时我们就会向后滑动一格,即从b最为起始点计算最长无重复的子串,即bca,max=3
- 当b进入之后继续向后滑动一格变为cab,计算无重复子序列值为3(即max=3)
- c进入之后,同理,继续向后滑动一格,变为abc,计算无重复子序列值为3(即max=3)
- b再次进入之后,队列继续向后滑动两格变为cb,注意此处滑动了两格,原因就是需要将已经出现的元素滑动出去,原本队列里是abc,此时只有连续滑动两个才能将b滑动出队列,此时的最大子序列长度变为2,max继续保留原有的最大值3,(注意:只有遇到更大的值才需要更换max的值,因为我们求得就是最长无重复子序列)
- b在次进入,我们同样需要滑动两格将b滑动出去,此时队列变为b,这种情况下的最长序列变为1,max仍保留原值3
至此滑动窗口的全部过程就结束了
题目实例:
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
3 | 无重复字符的最长子串 | https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/ | 点击查看 | 解析参考解题思路的过程 |
567 | 字符串的排列 | https://leetcode-cn.com/problems/permutation-in-string/ | 点击查看 | 在代码的注释中 |
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
438 | 找到字符串中所有字母异位词 | https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/ | 点击查看 | 解析参考解题思路的过程 |
713 | 乘积小于K的子数组 | https://leetcode-cn.com/problems/subarray-product-less-than-k/ | 点击查看 | 在代码的注释中 |
209 | 长度最小的子数组 | https://leetcode-cn.com/problems/minimum-size-subarray-sum/ | 点击查看 | 在代码的注释中 |
做题思路:
广度优先遍历的本质就是层次遍历,使用BFS可以求解非带权图的单源最短路径问题,这是由于 BFS总是按照距离由近到远来遍历图中的每一个顶点的性质决定的,下面 我们具体以一个实际的图进行操作。
具体广度优先遍历的流程如下:
- a入队,a出队,此时a的后继结点bc入队:队列元素为:bc,结果:a
- b出队,b的后继结点d,e入队:队列元素为:cde,结果:ab
- c出队,c的后继结点f,g入队:队列元素为:defg,结果:abc
- d出队,d无后继结点:队列元素为:efg,结果:abcd
- e出队,e的后继结点h入队:队列元素为:fgh,结果:abcde
- f出队,f无后继节点:队列元素为:gh,结果:abcdef
- g出队,g无后继节点:队列元素为:h,结果:abcdefg
- h出队,h无后继节点:队列元素为:空,结果:abcdefgh,由于队列为空,遍历结束
BFS 使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。BFS 总共有两个模板:
while queue 不空:
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)
level = 0
while queue 不空:
size = queue.size()
while (size -->0) {
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未被访问过:
queue.push(该节点)
}
level ++;
深度优先搜索类似于树的先序遍历,同样,我们具体以一个实际的图进行操作。
具体广度优先遍历的流程如下:
- a出,a有后继节点b,b出,b有后继结点d,d出:abd
- d无后继结点,回退到b,b有后继结点d,e但d已经访问过了,e出:abde,e有后继结点h,h出:abdeh
- h无后继结点,回退e,e有后继结点h,但h已经 访问继续回退,回退到b,b的后继结点也全部被访问,继续回退,回退到a,访问后继结点c:abdehc
- c有后继结点f,访问f:abdehcf
- f无后继结点,回退到c,访问另一个 后继结点g:abdehcfg
- 结点全部访问,遍历结束
题目实例:
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
733 | 图像渲染 | https://leetcode-cn.com/problems/flood-fill/ | 点击查看 | 点击查看 |
617 | 合并二叉树 | https://leetcode-cn.com/problems/merge-two-binary-trees/ | 点击查看 | 请参考代码注释解析 |
116 | 填充每个节点的下一个右侧节点指针 | https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/ | 点击查看 | 请参考代码注释解析 |
733 | 图像渲染 | https://leetcode-cn.com/problems/flood-fill/ | 点击查看 | 请参考代码注释解析 |
542 | 0 1矩阵 | https://leetcode-cn.com/problems/01-matrix/ | 点击查看 | 点击查看 |
994 | 腐烂的橘子 | https://leetcode-cn.com/problems/rotting-oranges/ | 点击查看 | 请参考01矩阵的解题思路 |
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
200 | 岛屿数量 | https://leetcode-cn.com/problems/number-of-islands/ | 点击查看 | 暂无解析 |
574 | 省份数量 | https://leetcode-cn.com/problems/flood-fill/ | 点击查看 | 点击查看 |
1091 | 二进制矩阵中的最短路径 | https://leetcode-cn.com/problems/shortest-path-in-binary-matrix/ | 点击查看 | 暂无解析 |
572 | 另一棵树的子树 | https://leetcode-cn.com/problems/subtree-of-another-tree/ | 点击查看 | 暂无解析 |
797 | 所有可能的路径 | https://leetcode-cn.com/problems/all-paths-from-source-to-target/ | 点击查看 | 暂无解析 |
130 | 被围绕的区域 | https://leetcode-cn.com/problems/surrounded-regions/ | 点击查看 | 暂无解析 |
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
206 | 反转链表 | https://leetcode-cn.com/problems/reverse-linked-list/ | 点击查看 | 暂无解析 |
21 | 合并两个有序链表 | https://leetcode-cn.com/problems/merge-two-sorted-lists/ | 点击查看 | 暂无解析 |
77 | 组合 | https://leetcode-cn.com/problems/combinations/ | 点击查看 | 暂无解析 |
46 | 全排列 | https://leetcode-cn.com/problems/permutations/ | 点击查看 | 请务必牢记该题的解决方式,理解不了就把代码背下来,以后遇到类似的题目即可套用,同时应牢记DFS的进退栈思想 |
784 | 字母大小写全排列 | https://leetcode-cn.com/problems/letter-case-permutation/ | 点击查看 | 参考代码解析 |
在位运算的操作者,我们需要 熟知的几个操作:
- 1.如果(n&(n-1))==0表示n是2的幂次方
- 2.a<
a ∗ 2 n a*2^n a∗2n - 3.a>>n:表示a右移n位,相当于
a ÷ 2 n a÷2^n a÷2n- 4.>>= 右移赋值
- 5.>>>= 右移赋值,左边空出的位以0填充
- 6.a⊕0=a
- 7.a⊕a=0
- 8.a⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b
题目编号 | 题目名称 | 题目链接 | 代码链接 | 题目详解 |
---|---|---|---|---|
231 | 2的幂 | https://leetcode-cn.com/problems/power-of-two/ | 点击查看 | 暂无解析 |
191 | 位1的个数 | https://leetcode-cn.com/problems/number-of-1-bits/ | 点击查看 | 暂无解析 |
136 | 只出现一次的数字 | https://leetcode-cn.com/problems/single-number/ | 点击查看 | 暂无解析 |
190 | 颠倒二进制位 | https://leetcode-cn.com/problems/reverse-bits/ | 点击查看 | 暂无解析 |