79.实现strStr(KMP)
方法一 .常规方法
方法二.KMP算法
【宫水三叶】简单题学 KMP 算法 - 实现 strStr() - 力扣(LeetCode) (leetcode-cn.com)
80.字符串转换整数(atoi)
81.三数之和(双指针)
82.最接近的三数之和(双指针)
83.反转链表II
84.和为K的子数组
85.把二叉树转换为累加树
86.两数之和
给你两个整数 和 ,不使用 运算符 和 ,计算并返回两整数之和。
87.实现前缀树
88.打家劫舍
89.计数质数
90.最大正方形
91.统计全为1的正方形子矩阵
92.打家劫舍2
93.打家劫舍3
94.删除无效的括号
95.柱状图中最大的矩形
96.最大矩形
97.重新排序得到2的幂
98.课程表
课程表 - 课程表 - 力扣(LeetCode) (leetcode-cn.com)
99.课程表2
100.单词拆分
101.电话号码的字母组合
102.2的幂
103.用rand7()实现rand10()
104.寻找两个正序数组的中位数
105.天际线问题
106.汉诺塔问题
107.有序矩阵中的第K小的元素
108.峰与谷
109.三角形最小路径和
110.最大整数子集
111.接雨水2
112.被围绕的区域
113.和为K的的子数组(前缀和)
114.构成交替字符串需要的最小交换次数
115.乘积为正数的最长子数组的长度
116.最长定差子序列
117.按字典序排在最后的子串
118.向下的路径节点之和(前缀和)
119.求x的幂(位运算)
这类题通常是指,判断一个数是否为x的幂(x=1,2,3....),对于这类型题,有一个通用的模板。
例如,下面的代码是判断一个数是否为4的幂(其他的也一样)
120.汉明距离总和(位运算)
121.丢失的数字
122.乘积小于K的子数组(双指针)
123.展开二叉搜索树(dfs)
124.所有路径(深度优先遍历)
125.爱吃香蕉的猩猩(二分法)
126.数组中第K大的数字(快排)
127.省份数量(并查集)
128.冗余连接(并查集)
129.矩阵中的距离 (BFS)
130.计算后缀表达式
131.向下路径节点之和(深度优先遍历+前缀和)
132.按字典序排在最后的子串(双指针)
133.删除有序数组中的重复项(双指针)
134.所有子字符串美丽值之和
135.乘积为正数的最长子数组长度(动态规划)
136.有效的完全平方数
137.多次搜索
138.复原IP地址
139.范围求和2
140.把数字翻译成字符串(动态规划)
141.
142.栈的压入、弹出序列
143.字符串的排列
144.扑克牌中的顺子
145.和为s的连续正数序列
146.剪绳子2
147.猜数字大小2(动态规划)
148.数组中的逆序对(归并排序解法)
149.构建乘积数组
150.和为s的连续正数序列
151.扑克牌中的顺子
152.字符串的排列
153.栈的压入、弹出序列
154.范围求和2
155.键值映射
156.二叉搜索树的后序遍历序列
157.山峰数组的顶部
普通方法找最大值
158.二叉树的坡度
159.解码方式(动态规划)
160.使用最小花费爬楼梯
161.整数拆分
162.无重叠区间
163.目标和
164.数组中的最长山脉
165.摆动序列
166.二叉树的坡度
167.后继者
168.判定字符是否唯一
169.最大单词长度乘积
170.最长和谐子序列(双指针)
171.硬币
172.最大子矩阵
这要从最大子序和说起,由简到繁 - 最大子矩阵 - 力扣(LeetCode) (leetcode-cn.com)
173.迷路的机器人(回溯)
174.最长单词
175.交换和
176.求和路径
177.最小差
178.回复空格
179.统计封闭岛屿的数目
180.统计子岛屿
什么情况下中的一个岛屿是中的一个岛屿的子岛?
当岛屿中所有陆地在岛屿中也是陆地的时候,岛屿是岛屿的子岛。
反过来说,如果岛屿中存在一片陆地,在岛屿的对应位置是海水,那么岛屿就不是岛屿的子岛。
那么,我们只要遍历中的所有岛屿,把那些不可能是子岛的岛屿排除掉,剩下的就是子岛。
181.岛屿的周长
计算出总的岛屿数量,因为有一对相邻两个陆地,边的总数就减2,那么在计算出相邻岛屿的数量就可以了。
182.不同的岛屿数量
比如题目输入下面这个二维矩阵:
其中有四个岛屿,但是左下角和右上角的岛屿形状相同,所以不同的岛屿共有三个,算法返回 3。
很显然我们得想办法把二维矩阵中的「岛屿」进行转化,变成比如字符串这样的类型,然后利用 HashSet 这样的数据结构去重,最终得到不同的岛屿的个数。
如果想把岛屿转化成字符串,说白了就是序列化,序列化说白了遍历嘛。
首先,对于形状相同的岛屿,如果从同一起点出发,函数遍历的顺序肯定是一样的。
所以,遍历顺序从某种意义上说就可以用来描述岛屿的形状,比如下图这两个岛屿:
假设它们的遍历顺序是:
下,右,上,撤销上,撤销右,撤销下
如果我用分别用代表上下左右,用代表上下左右的撤销,那么可以这样表示它们的遍历顺序:
2, 4, 1, -1, -4, -2
你看,这就相当于是岛屿序列化的结果,只要每次使用遍历岛屿的时候生成这串数字进行比较,就可以计算到底有多少个不同的岛屿了。
要想生成这段数字,需要稍微改造函数,添加一些函数参数以便记录遍历顺序:
记录方向,函数递归结束后,记录着整个遍历顺序,其实这就是回溯算法框架,你看到头来这些算法都是相通的。
有了这个函数就好办了,我们可以直接写出最后的解法代码:
183.分发糖果
这道题目一定是要确定一边之后,再确定另一边,例如比较每一个孩子的左边,然后再比较右边,如果两边一起考虑一定会顾此失彼。
先确定右边评分大于左边的情况(也就是从前向后遍历)
此时局部最优:只要右边评分比左边大,右边的孩子就多一个糖果,全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果
局部最优可以推出全局最优。
如果ratings[i] > ratings[i - 1] 那么[i]的糖 一定要比[i - 1]的糖多一个,所以贪心:candyVec[i] = candyVec[i - 1] + 1
再确定左孩子大于右孩子的情况(从后向前遍历)
遍历顺序这里有同学可能会有疑问,为什么不能从前向后遍历呢?
因为如果从前向后遍历,根据 ratings[i + 1] 来确定 ratings[i] 对应的糖果,那么每次都不能利用上前一次的比较结果了。
所以确定左孩子大于右孩子的情况一定要从后向前遍历!
如果 ratings[i] > ratings[i + 1],此时candyVec[i](第i个小孩的糖果数量)就有两个选择了,一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。
那么又要贪心了,局部最优:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,保证第i个小孩的糖果数量即大于左边的也大于右边的。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。
局部最优可以推出全局最优。
所以就取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,candyVec[i]只有取最大的才能既保持对左边candyVec[i - 1]的糖果多,也比右边candyVec[i + 1]的糖果多。
184.解数独
185.可怜的小猪
本质上在考察数学中的 进制 问题
换底公式: