![](https://img-blog.csdnimg.cn/20200705212944741.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
LeetCode
LeetCode的一些题解
SuperFeHanHan
人生得意须尽憨!
展开
-
2021-04-29 403. 青蛙过河 [dfs,动态规划]
403. 青蛙过河思路一:DFS 暴搜class Solution { HashMap<Integer,Integer> map = new HashMap<>(); // step: 上一步走了多少步 // idx: 当前石头块编号 public boolean dfs(int[] stones, int step,int idx){ if(idx == (stones.length-1)){ // Sy原创 2021-04-29 20:25:04 · 277 阅读 · 0 评论 -
2021-04-28 633. 平方数之和
633. 平方数之和思路一:利用sqrt为了避免溢出,需要用long。class Solution { public boolean judgeSquareSum(int c) { // 利用sqrt long a = (long)Math.sqrt(c); for(long i=a;i>=0;i--){ long b = (long)Math.sqrt(c-i*i); if((c-i*i-b原创 2021-04-28 20:37:19 · 138 阅读 · 0 评论 -
2021-04-27 938. 二叉搜索树的范围和 [dfs,递归]
938. 二叉搜索树的范围和思路一: 暴力DFSclass Solution { int sum = 0; public void dfs(TreeNode root,int low, int high){ if(root == null) return; dfs(root.left,low,high); if(low<=root.val && root.val <=high){原创 2021-04-27 23:47:25 · 71 阅读 · 0 评论 -
2021-04-26 1011. 在 D 天内送达包裹的能力 [二分查找]
1011. 在 D 天内送达包裹的能力class Solution { // 判断我们是否能在capacity内完成任务 // 因为是按照给定的顺序,所以只要用O(n) public boolean possible(int[] weights, int D, int capacity){ int tmp = 0; for(int i=0;i<weights.length;i++){ if(tmp + weights[i原创 2021-04-26 17:16:49 · 114 阅读 · 0 评论 -
2021-04-25 897. 递增顺序搜索树 [dfs]
897. 递增顺序搜索树思路一:dfs + 重新构建一棵树class Solution { TreeNode start = new TreeNode(); public void dfs(TreeNode root){ if(root==null) return; dfs(root.left); // System.out.println(root.val); start.right = new T原创 2021-04-25 17:07:36 · 74 阅读 · 0 评论 -
2021-04-24 377. 组合总和 Ⅳ [动态规划]
377. 组合总和 Ⅳ思路一:回溯法 (超时)class Solution { int tmp = 0; // 记录目前组合的和 int res = 0; // 记录目前有的组合的方案种数 LinkedList<Integer> resTmp = new LinkedList<>(); // 记录目前有的组合方案 // 利用nums public void dfs(int[] nums, int target){ if(tm原创 2021-04-25 00:04:45 · 87 阅读 · 0 评论 -
2021-04-23 368. 最大整除子集 [动态规划]
368. 最大整除子集因此,我们的结论是,我们每次只需要加入a[n]%a[n−1]==0a[n]\%a[n-1]==0a[n]%a[n−1]==0的元素到list中即可。但是要注意下面的例子[9,18,54,108,540][9,18,90,180,360,720]。即每一个元素的前半部分可能是公用的,如[9,18]。class Solution { public List<Integer> largestDivisibleSubset(int[] nums) {原创 2021-04-23 23:52:30 · 96 阅读 · 0 评论 -
2021-04-22 363. 矩形区域不超过 K 的最大数值和
363. 矩形区域不超过 K 的最大数值和思路一:暴力求解class Solution { public int maxSumSubmatrix(int[][] matrix, int k) { int rows = matrix.length; int cols = matrix[0].length; int max = Integer.MIN_VALUE; int[][][][] dp = new int[rows+1][col原创 2021-04-22 17:58:42 · 85 阅读 · 0 评论 -
2021-04-21 91. 解码方法 [dfs]
91. 解码方法思路一:能显示解答的做法(超时)class Solution { LinkedList<LinkedList<Integer>> res = new LinkedList<>(); public void dfs(char[] msg,int start,LinkedList<Integer> tmp){ if(start==msg.length){ // System.out.pr原创 2021-04-21 17:06:18 · 96 阅读 · 0 评论 -
2021-04-20 28. 实现 strStr() [KMP算法]
KMP算法用于在字符串A中寻找是否出现过字符串B第一步:求最长公共前后缀长度,构建Prefix Tablepublic static void getPrefixTable(char[] pattern,int[] prefix){ int n = pattern.length; assert n>0; // 每次填充一个prefix的值 prefix[0]=0; for(int i=1,len=0;i<原创 2021-04-20 20:13:10 · 52 阅读 · 0 评论 -
2021-04-19 27. 移除元素
2021-04-19 27. 移除元素思路:双指针class Solution { public int removeElement(int[] nums, int val) { int crt = 0, pre = 0; // [0,pre[是已经处理好的要返回的数组,crt每次如果等于val就往后走直到第一个不是val的数 while(crt<nums.length){ while(crt<nums.length &原创 2021-04-19 21:23:36 · 35 阅读 · 0 评论 -
2021-04-16 87. 扰乱字符串 [动态规划]
87. 扰乱字符串首先不要被这道题目是困难给吓到,实际上还是挺简单的。我们不需要纠结特定的规则,只要关注几个不变量即可。交换不改变字符串的长度,所以如果长度不同就直接返回False如果S被分为s1和s2,T被分为t1和t2,则他们相等的必要前提是s1和t1长度相同。此外,s1的构成元素和t1的构成元素相同。我们引入dp[i][j][l]表示s1[i,i+k-1]是否由s2[j,j+k-1]变换而来。按照规则和我们的第二点观察,dp[i][j][l]=true一定只可能来自于下面两种情况:原创 2021-04-16 23:42:28 · 58 阅读 · 0 评论 -
2021-04-15 打家劫舍系列(198, 213, 337) [动态规划]
198. 打家劫舍思路一:dp[i]表示洗劫第i家能获得的最大收益。tmp用来表示[0,i-2]中能获得的最大收益。dp[i]=nums[i]+maxj∈[0,i−2](dp[j])res=maxi∈[0,n]dp[i]dp[i]=nums[i]+max_{j\in[0,i-2]}(dp[j]) \\res = max_{i \in [0,n]} dp[i]dp[i]=nums[i]+maxj∈[0,i−2](dp[j])res=maxi∈[0,n]dp[i]class Soluti原创 2021-04-15 22:55:28 · 76 阅读 · 0 评论 -
2021-04-14 208. 实现 Trie (前缀树)
208. 实现 Trie (前缀树)思路:每一个节点都有一个属性isEnd,如果isEnd =True,则说明从根结点开始到现在位置是一个之前添加过的词。每一个节点还有26个next指针,指向下一个字母(这里字母用0-25的序号表示),如果下一个字母不存在,则是null每次我们添加一个元素,即说明每一个字母存在,只需要将对应的next指针上开一个节点的空间即可。整个单词的存在由最后一个节点的isEnd = True表示。class Trie { class TrieNode{原创 2021-04-14 16:39:11 · 69 阅读 · 0 评论 -
2021-04-13 783. 二叉搜索树节点最小距离 [DFS]
783. 二叉搜索树节点最小距离注意这里是任意两个节点,不是相邻!因为是二叉搜索树的原因,我们可以通过BFS获得递增序列class Solution { public int minDiffInBST(TreeNode root) { dfs(root); return 1; } // 左中右 public void dfs(TreeNode root){ if(root==null) retu原创 2021-04-14 16:34:54 · 49 阅读 · 0 评论 -
2021-04-11 264. 丑数II
263. 丑数把因数一个个除掉。class Solution { public boolean isUgly(int n) { if(n==0) return false; int[] factor = {2,3,5}; for(int f : factor){ while(n%f==0) n/=f; } return n==1; }}...原创 2021-04-11 22:40:29 · 59 阅读 · 0 评论 -
2021-04-10 263. 丑数
263. 丑数把因数一个个除掉。class Solution { public boolean isUgly(int n) { if(n==0) return false; int[] factor = {2,3,5}; for(int f : factor){ while(n%f==0) n/=f; } return n==1; }}...原创 2021-04-10 23:49:05 · 54 阅读 · 0 评论 -
剑指 Offer | 动态规划 [14-I,14-II,42,47,63,19,]
剑指 Offer | 动态规划 [14-I,14-II,47,63]42.连续子数组的最大和63. 股票的最大利润14- I. 剪绳子 | 递归+Memoization14- II. 剪绳子 II ????47. 礼物的最大价值19. 正则表达式匹配 | 倒序思考问题Memoization模版注意42.连续子数组的最大和class Solution { // 用tmp[i]表示[0,i]中包括i的最大子数组的和。 // 最后返回的是max i tmp[i] public int原创 2021-04-06 04:09:21 · 58 阅读 · 0 评论 -
2021-04-06 82.删除排序数组中的重复项 II | 26. 删除有序数组中的重复项 [双指针]
看这架势,估计LeetCode 这个月要是双指针专题了…lol26. 删除有序数组中的重复项class Solution { public int removeDuplicates(int[] nums) { if(nums.length<=1) return nums.length; // [0,pre[ 为原数组[0,cur]删除后最终的结果,即[0,pre[满足题目数组中每一个元素只出现1次的要求。 // 每.原创 2021-04-06 02:46:02 · 53 阅读 · 0 评论 -
2021-04-05 88. 合并两个有序数组 [双指针]
88. 合并两个有序数组思路:倒过来考虑。如果nums1最后一个元素最大,则将它的元素移动到最后一个位置,此时nums1中0的数目不变。反之,将nums2的最后一个元素和nums1中的一个0交换。class Solution { // 倒过来,谁大就放谁 public void merge(int[] nums1, int m, int[] nums2, int n) { int cp = n; int last = nums1.length-1;原创 2021-04-05 00:40:19 · 50 阅读 · 0 评论 -
2021-04-04 781. 森林中的兔子 [HashMap]
781. 森林中的兔子思路:统计报不同数字nnn的兔子的数量iii,然后返回ceil(in+1)∗(n+1)ceil(\frac{i}{n+1})*(n+1)ceil(n+1i)∗(n+1)。原因是报不同数字的兔子肯定有不同的颜色,因为每种颜色的兔子应该等于(自己报的数+1),两只同颜色的兔子报的数字应该是一样的。每只报n的兔子,最多和另外n只兔子构成一种颜色,这种颜色的兔子总数为n+1。因此要满足报n的兔子的颜色,至少需要ceil(in+1)∗(n+1)ceil(\frac{i}{n+1})原创 2021-04-04 16:09:26 · 190 阅读 · 0 评论 -
2021-04-03 1143. 最长公共子序列 [动态规划]
最长公共子序列思路一:递归+记忆化class Solution { char[] t1,t2; HashMap<String,Integer> map = new HashMap<>(); public int recur(char[] t1,char[] t2,int start1, int start2){ if(start1==t1.length || start2==t2.length) return 0原创 2021-04-03 22:17:01 · 50 阅读 · 0 评论 -
2021-04-01 1006. 笨阶乘 | 150. 逆波兰表达式求值 | 224. 基本计算器 I 括号展开 | 227. 基本计算器 II [栈,数学表达式求值]
2021-04-01 1006. 笨阶乘 | 150. 逆波兰表达式求值 | 224. 基本计算器 | 括号展开 | 227. 基本计算器 II[栈,数学表达式求值]1006. 笨阶乘150. 逆波兰表达式求值224. 基本计算器 | 括号展开227. 基本计算器 II一般情况1006. 笨阶乘基本思路:利用一个栈存储待相加的数字。减号就立马对于当前元素进行操作,每次碰到*/立马更新栈顶的元素。如109/8+7-65/4+3=10*9/8+7+(-6)*5/4+3class Solution原创 2021-04-02 23:06:38 · 82 阅读 · 0 评论 -
剑指 Offer | DPS,BFS
剑指 Offer | DPS,BFS32 - I. 从上到下打印二叉树 | BFS32 - II 从上到下打印二叉树 II | 层序遍历32 - III. 从上到下打印二叉树 III55 - I. 二叉树的深度 | 层序遍历 | DFS ????面试题34. 二叉树中和为某一值的路径55 - II. 平衡二叉树12. 矩阵中的路径 | 矩阵搜索问题 深度优先搜索(DFS)+ 剪枝 ????Deque的使用方法:PriorityQueue的使用方法:ArrayList使用方法字符串的使用方法:32 -原创 2021-04-02 03:58:55 · 107 阅读 · 0 评论 -
2021-02-10 567. 字符串的排列
567. 字符串的排列收获:判断是否是全排列->看组成成分,如果组成相同,则就是全排列的一个结果。思路一:class Solution { public boolean equal(int[] map1,int[] map2){ for(int i=0;i<map1.length;i++) if(map1[i]!=map2[i]) return false; return true;原创 2021-02-10 19:19:41 · 56 阅读 · 0 评论 -
2021-02-06 1423. 可获得的最大点数[滑动窗口]
1423. 可获得的最大点数思路一:贪心(错误)如果每次取前后最大的一个数字,则不一定最优秀。如[1,100,3,2] k=2,如果每次取前后最大的一个元素,则结果为3+2 = 5,但是实际结果是1+100=101class Solution { public int maxScore(int[] cardPoints, int k) { int res = 0; int start = 0; int end = cardPoints.lengt原创 2021-02-06 20:35:05 · 72 阅读 · 0 评论 -
2021-02-01 888. 公平的糖果棒交换[哈希表]
888. 公平的糖果棒交换思路一:暴力法class Solution { public int[] fairCandySwap(int[] A, int[] B) { // 假设是A的长度和B的长度至少为1 int sumA = 0; // 求出A拥有糖果的总数 int sumB = 0; for(int i=0;i<A.length;i++) sumA+=A[i]; for(int i原创 2021-02-01 21:07:46 · 46 阅读 · 0 评论 -
2021-01-28 724.寻找数组的中心索引
724.寻找数组的中心索引思路一:两次循环,第一次统计所有的和第二次,计算[0,i[的和,利用2*[0,i[的和+nums[i] = totalsum 进行判断。class Solution { public int pivotIndex(int[] nums) { int totalSum=0; for(int i=0;i<nums.length;i++) totalSum+=nums[i]; int t原创 2021-01-28 01:09:41 · 52 阅读 · 0 评论 -
2021-01-26 1128. 等价多米诺骨牌对的数量
1128. 等价多米诺骨牌对的数量想法很简单,主要是题目意思要理解清楚。// 单出现一个[1,1]是不算的,只有出现两个才算// 出现[1,2],[1,2],[1,2] 算1+2=3次。class Solution { public int numEquivDominoPairs(int[][] dominoes) { int l = dominoes.length; int[] num = new int[100]; int ans = 0;原创 2021-01-26 02:42:42 · 93 阅读 · 0 评论 -
2021-01-23 1319.连通网络的操作次数 [并查集,DFS](连通分量)
1319.连通网络的操作次数思路一:并查集好吧,我不说了,这个月看到题目第一个思路就是并查集。主要分两类情况讨论:鉴于连接n个电脑至少要n-1条线,所以如果线的数量 connections.length < 电脑数量 n-1 ,则我们输出(-1)表示一定不可能。否则,我们直到现在的线的条数一定大于等于n-1条。我们注意到,每个含有nin_ini台电脑的Cluster(即相连通的电脑群)只需要ni−1n_i-1ni−1条线,记CCC为所有Cluster的集合,则包含∣C∣|C|∣C原创 2021-01-24 00:25:55 · 96 阅读 · 0 评论 -
2021-01-24674. 最长连续递增序列
674. 最长连续递增序列思路一:遍历我们利用l记录当前最长的序列长度。class Solution { public int findLengthOfLCIS(int[] nums) { if(nums.length==0) return 0; int res = 1; int l = 1; for(int i=1;i<nums.length;i++){原创 2021-01-24 00:08:28 · 53 阅读 · 0 评论 -
2021-01-22 989.数组形式的整数加法
989.数组形式的整数加法思路一:诸位相加首先遍历A数组的各个位置,其次,如果K比A长,添加K的各个位置最后,如果最后还有一个进位。class Solution { public List<Integer> addToArrayForm(int[] A, int K) { List<Integer> res = new LinkedList<>(); int add1=0; for(in原创 2021-01-22 01:22:03 · 73 阅读 · 0 评论 -
2021-01-19 1584. 连接所有点的最小费用[Kruskal算法,Prim算法]
1584. 连接所有点的最小费用思路一:Kruskal算法 [PriorityQueque + UnionFind]思路:将所有的边一次性全部读入并存储到PriorityQueue中,权重小的在priority queue上方。将pq中的元素一一poll出来,这里使用UnionFind的方式,如果发现有环,就不添加这条边。重复做2,直到所有unionfind中只存在一个类别。class Solution { public int minCostConnectPoints(int[][原创 2021-01-20 05:27:30 · 107 阅读 · 0 评论 -
2021-01-20 628.三个数的最大乘积 [排序,线性扫描]
628.三个数的最大乘积思路一:排序鉴于我们的数字中存在负数,所以三个数字最大乘积只可能有2种情况。最后三个正数最小的两个负数和最后一个最大的正数class Solution { public int maximumProduct(int[] nums) { Arrays.sort(nums); if(nums[0]<0 && nums[1]<0) return Math.max(nums[nums.原创 2021-01-20 00:48:54 · 105 阅读 · 0 评论 -
2021-01-08 721.账户合并[哈希表,并查集]
721.账户合并思路一:哈希表,并查集鉴于很多邮箱公用一个名字,我们只需要现将同一个人的邮箱汇总在一起,然后最后输出答案的时候,用他的一个邮箱反向查询到他对应的用户的名字即可。官方源码分析:class Solution { public List<List<String>> accountsMerge(List<List<String>> accounts) { Map<String, Integer> emailT原创 2021-01-18 22:16:49 · 77 阅读 · 0 评论 -
2021-01-17 1232.缀点成线
1232.缀点成线思路一:直线方程class Solution { public boolean checkStraightLine(int[][] coordinates) { // 因为点的数量一定大于等于2,先用前两个点算斜率 int x0=coordinates[0][0],x1=coordinates[1][0]; int y0=coordinates[0][1],y1=coordinates[1][1]; // 如果是垂原创 2021-01-17 20:18:15 · 48 阅读 · 0 评论 -
2021-01-15 947.移除最多的同行或同列石头 [并查集]
947.移除最多的同行或同列石头思路一:并查集其实这道题看似花里胡哨,实际上能移除的石头个数就是石头总个数减去属于同一类别(我们把处于同一列同一行能联通的石头放在一类)的石头个数。因为一坨互相联通的石头之间总可以移除到只剩下一块。这个想法的证明可以倒过来想,如果只剩一块,根据我们分类的定义,只要没有达到该类别总个数,一定存在同一类的元素与其相连(处于同一行或者同一列),因此可以添加到两块,以此类推,就可以还原到最初状态。又因为能加一块就一定能删一块,因此,我们证明了一坨互相联通的石头之间总可以移除到原创 2021-01-15 19:13:51 · 105 阅读 · 0 评论 -
2021-01-14 1018. 可被 5 整除的二进制前缀
1018. 可被 5 整除的二进制前缀思路一:逐位模拟因为每次左移=*2,所以我们下一次更新为tmp = (tmp%5)*2+A[i]。class Solution { public List<Boolean> prefixesDivBy5(int[] A) { List<Boolean> res = new ArrayList<Boolean>(); int tmp=0; //用来存储当前数字除以5的余数 f原创 2021-01-14 02:26:54 · 88 阅读 · 0 评论 -
2021-01-13 684.冗余连接 [并查集]
684. 冗余连接思路一:并查集(检查环)我们顺次Union每条边,直到出现新加的边已经在同一类里面,因为我们每次循环都会保证UnionFind中的任意两个元素之间都有通路。class Solution { public int[] findRedundantConnection(int[][] edges) { // 用并查集找环 int len = edges.length; UnionFind uf = new UnionFind(len+原创 2021-01-13 01:18:44 · 48 阅读 · 0 评论 -
2021-01-12 207.课程表[拓扑排序]
207.课程表207.课程表思路一:拓扑排序应用场景:重要结论:具体实践1:BFS具体实践2:DFS收获:自己尝试复现代码BFS207.课程表这时候你有可能会问“不是1203项目管理吗?”你怎么偷梁换柱?实际上emmm,不妨让我们先熟悉熟悉拓扑排序。思路一:拓扑排序建议看官方解答的动图此时,根据拓扑排序的结果,0是[1,4,7]的先决条件,但是[1,4,7]没有顺序关系。应用场景:如课程表的安排重要结论:只有有向无环图才有拓扑排序(否则会有相互依赖)拓扑排序的结果不唯一。具体原创 2021-01-13 23:01:15 · 110 阅读 · 0 评论