![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Leetcode
文章平均质量分 66
RushmcRunRunRun
这个作者很懒,什么都没留下…
展开
-
459. 重复的子字符串(KMP算法)
459. 重复的子字符串优秀解法:KMP(n,n)fail数组定义:最长前后缀长度-1 如ababab为3 最长前后缀为4:abab(第一个) abab(第二个)初始值为什么为-1:让第一个if的now + 1 = 0 否则会少判断第一个字母怎么加速获得fail值:如果s[now + 1] == s[i] 即在最长前缀的后一个字母也和当前串下一个字母相同 那么当然最长前后缀长度加一如果不相等 那么仍可利用原来的最长前后缀我们当然不想把这个长度缩小太多 因为我们要找的是最原创 2021-09-20 12:23:54 · 288 阅读 · 0 评论 -
一步步将dfs回溯剪枝进行优化(LeetCode 79. 单词搜索)
一个极其普通的解法主要思想是找到可行的起始点 深度遍历搜索 保存当前的字符串如果匹配则继续否则剪枝class Solution { char[][] board; boolean res = false; int n; int m; boolean[][] visited; public boolean exist(char[][] board, String word) { this.board = board; n =原创 2021-08-18 12:40:00 · 292 阅读 · 2 评论 -
中序遍历的三种方法
94. 二叉树的中序遍历递归法class Solution { List<Integer> res = new ArrayList<>(); public List<Integer> inorderTraversal(TreeNode root) { mid(root); return res; } public void mid(TreeNode root){ if(root ==原创 2020-12-09 14:01:47 · 3579 阅读 · 0 评论 -
面试题 04.03. 特定深度节点链表
面试题 04.03. 特定深度节点链表层序遍历加虚拟节点思路本题显然需要使用树的层序遍历,关键是怎么把各层节点放入一个串联起来的链表使用队列进行层序遍历虚拟节点实现代码class Solution { public ListNode[] listOfDepth(TreeNode tree) { ListNode dummy = new ListNode(0); LinkedList<TreeNode> queue = new Linke原创 2020-11-24 19:47:54 · 138 阅读 · 0 评论 -
1074. 元素和为目标值的子矩阵数量
1074. 元素和为目标值的子矩阵数量思路sum[x][y]表示从第1行第1列到第x行(注意 此处行列从1开始计数)第y列的元素数值和起始y(startY)和终止y(endY)分别变化,内嵌套for循环进行x的变化哈希表记录每个矩阵的元素和 所以当此时target - 矩阵元素和的元素在哈希表中存在,说明一个大矩阵减去有重合部分的小矩阵得到一个新的小矩阵,这个小矩阵的值等于目标值代码实现public static int numSubmatrixSumTarget(int[][] matr原创 2020-11-22 23:12:57 · 161 阅读 · 0 评论 -
844. 比较含退格的字符串
844. 比较含退格的字符串题解 遍历两个字符串,记录此时需要抵消的字符串个数,找到退格后的字符,比较两个字符串中该位置的字符是否相同,之后前移重复步骤直到字符串遍历完毕class Solution { public boolean backspaceCompare(String S, String T) { if (S == null || T == null) { return false; } /*原创 2020-10-19 10:50:29 · 67 阅读 · 0 评论 -
19. 删除链表的倒数第N个节点
19. 删除链表的倒数第N个节点题解 预设指针pre,start,end,使pre.next = head,start比end多走n步,n–,之后找到要删除的结点的上一个节点(技巧是start.next == null跳出循环),删除即可。最后返回pre.next,因为head结点可能已经被删除。/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode n原创 2020-10-18 10:27:39 · 81 阅读 · 0 评论 -
1002. 查找常用字符
1002. 查找常用字符题解 用一个大小为26的整形数字记录每一个字符串每一个字母出现的个数,每当遍历一个字符串,遇到更小的则替换为更小的字符个数,最后add进list即可class Solution { public List<String> commonChars(String[] A) { //先得到第一个字符串里面每个字符的情况 int[] charCount = new int[26]; for(int i = 0; i原创 2020-10-14 13:10:28 · 156 阅读 · 0 评论 -
142. 环形链表 II
142. 环形链表 II题解 定义两个指针fast和slow,fast一次走两步,slow走一步。有f=2s,设链表有a+b个结点,其中第a个是环的入口,b是环的长度,当fast和slow相遇,fast必定比slow多走了n个环,有f=s+nb,联立上式可得nb = s,f = 2nb,设k为到入口的步数情况,因为有环的存在,所以k = a + nb,现在slow已经走了nb,所以再走a步就可以到达入口处,使fast指针回到头结点与slow指针一直往前,由于两者都是需要a步到入口,那么当两者相遇,两原创 2020-10-11 10:11:22 · 724 阅读 · 0 评论 -
18. 四数之和
18. 四数之和题解 尝试使用暴力遍历法,时间复杂度为O(n^4),不出意料地超出了时间限制,优秀做法是采用排序+剪枝的方法来实现,利用Arrays.sort()方法先将原数组排序(偷懒),之后可以根据已经排序的数组特点剪支,最小值 = 当前数+后三个数,最大值 = 当前数+末尾三个数,如果最小值大于target,则说明后续再无组合符合要求(后续所有值之和只会越来越大),如果最大值小于target,说明当前数值不够大,本轮结束。class Solution { public List<原创 2020-10-05 18:22:44 · 90 阅读 · 0 评论 -
2. 两数相加
2. 两数相加题解 一开始我的思路是先分别获取两个数字,再相加后构造新链表,这样的方法虽然效率低但是可能可以实现(老菜鸡了),但是发现后面的示例的位数超过了Integer.MAX_VALUE,只能用long然后强转……看了优秀的题解之后发现人家是这样做的,直接使用两个链表的单个值进行相加,但是需要取余(题目要求每个值都必须是个位数),最后如果表示十位的变量不为0,还需要补一个1的结点。/** * Definition for singly-linked list. * public clas原创 2020-10-04 11:26:55 · 102 阅读 · 0 评论 -
117. 填充每个节点的下一个右侧节点指针 II
117. 填充每个节点的下一个右侧节点指针 II题解 在当前节点的下一层设置一个哑节点(仅用于标记),串联下一层的左右节点,当当前节点还有next节点(之前串联起来的),使当前节点跳转到next节点,之后,本层遍历完毕,把哑节点的next节点赋值给当前节点(换层),创建新哑节点继续处理即可。/*// Definition for a Node.class Node { public int val; public Node left; public Node righ原创 2020-09-28 11:10:25 · 175 阅读 · 0 评论 -
235. 二叉搜索树的最近公共祖先
235. 二叉搜索树的最近公共祖先题解 本题中的树是特殊的二叉搜索树,所以当本节点的值都大于p、q的值,表示p、q在本节点的左子树,向左移动。当本节点的值都小于p、q的值,表示p、q在本节点的右子树,否则当前节点为p、q中的一个或者刚好为p、q的父节点class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { TreeNode ancestor原创 2020-09-27 10:26:02 · 65 阅读 · 0 评论 -
113. 路径总和 II
113. 路径总和 II题解 使用两个List来记录,一个用于记录当前路径temp,一个用于记录符合情况的路径res,当满足要求把temp加入List,需要注意的是不管是否满足题意,在最后都要把temp的路径清除,否则后面把temp加入List时会有多余的数据。/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNo原创 2020-09-26 10:44:04 · 75 阅读 · 0 评论 -
106. 从中序与后序遍历序列构造二叉树
106. 从中序与后序遍历序列构造二叉树题解 后序遍历的最后一个节点是二叉树的根节点,前序遍历中根节点的左边是左子树,右边是右子树(前提是没有节点的值跟根节点重复)。根据左右子树边界位置递归构造即可。/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int原创 2020-09-25 08:52:11 · 100 阅读 · 0 评论 -
617. 合并二叉树
617. 合并二叉树题解 构造一棵新树,首先判断两棵树节点都为空的情况,返回null,若之后t1为空,则证明t2不为空,则可以直接返回t2,反之亦然。若两者都不为空,构造t1+t2的新节点。/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { v原创 2020-09-23 13:51:19 · 58 阅读 · 0 评论 -
968. 监控二叉树
968. 监控二叉树题解 关于树的问题我们一般使用递归来解决。首先可以遍历到树的最底端(此节点的左右孩子都为空,空孩子标记为状态1),标记此节点为已覆盖(状态0),如果一个节点的其中一个左右节点状态为已覆盖(即还未安装监视器),那么给此节点安装监视器,并且记录监视器数量的全局变量自增。 安装监视器后,给节点标记状态为2,那么它的父节点就会被此监视器监控,即父节点已被覆盖,状态为1。/** * Definition for a binary tree node. * public class原创 2020-09-22 09:46:24 · 893 阅读 · 0 评论 -
538. 把二叉搜索树转换为累加树
538. 把二叉搜索树转换为累加树题解 这是一颗二叉搜索树,右子树的节点都比中间节点大,左子树的节点都比中间节点小。所以当转换成累加树时,右边的节点不变化,中间节点的值为 中+右的值,左边节点的值为左+中+右的值。使用全局变量递归进行反向中序遍历赋值即可。/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode原创 2020-09-22 00:19:44 · 88 阅读 · 0 评论 -
37. 解数独
37. 解数独题解 用三个布尔数组,分别表示该行、该列、该3*3方格是否存在该数字,先遍历初始数独,获取初始的数字使用情况,之后对空的方格进行数字填充,若在布尔数组检索时发现冲突,则返回错误回溯。写法是进行填充后检查下一列填充的返回情况并且递归进行,若返回false表示,该情况无法完成数独,需要回溯并尝试其他情况。class Solution { public void solveSudoku(char[][] board) { // 三个布尔数组 表明 行, 列, 还有原创 2020-09-15 19:18:06 · 120 阅读 · 0 评论 -
332.重新安排行程
332.重新安排行程题解 本题的题意就是找到以JFK为起点的欧拉通路,而且需要找到字典序最小的那个结果。所以我们使用优先队列来实现,普通的队列的特点是先进先出,优先队列的特点是先弹出优先度最高的节点。但我们如果直接走字典序最小的路,可能会走到一个死胡同,无法达成使用每一张机票的目的,所以我们要把会走到死胡同的节点放到最后遍历。 至于如何实现,只有该节点还没走到死胡同,就继续递归,递归不会停止。直至遇到死胡同,然后从死胡同那个节点开始入栈,再将栈内容反转即可。...原创 2020-08-28 20:47:12 · 203 阅读 · 1 评论 -
679.24点游戏
679.24点游戏题解 先找出4个数字所有不同的排列组合,然后再去一一判断四个数前两个数加减乘除,四个数变为两个数,得到三个数一一判断前两个数加减乘除,三个数变为两个数,判断这两个数加减乘除和24的关系即可。class Solution { public boolean judgePoint24(int[] nums) { return backTrack(nums, 0); } // 第一步:求出所有排列,一一验证 public boolean原创 2020-08-23 09:44:01 · 976 阅读 · 0 评论 -
111.二叉树的最小深度
111.二叉树的最小深度题解 当节点为空,则树为一颗空树,深度为0.当左右子节点都为空,则找到了叶子节点,为最终的高度加一。当左右子节点不为空则往下递归,在递归的过程中高度不断叠加。class Solution { public int minDepth(TreeNode root) { if(root == null){ return 0; } if(root.left == null && root原创 2020-08-21 23:25:20 · 151 阅读 · 0 评论 -
529. 扫雷游戏
529. 扫雷游戏题解 对于图形变换的问题我们常常使用广度优先与深度优先算法。一般深度优先算法会较为方便。首先我们构造点周围的一一对应的两个数组dirX和dirY用于遍历。这样的操作使得我们不需要写大量的if语句判断是否会越界。先判断点是否为地雷,然后把周围8个点遍历一遍获得需要标记的地雷数量。再进行递归即可。class Solution { int[] dirX = {0, 1, 0, -1, 1, 1, -1, -1}; int[] dirY = {1, 0, -1, 0, 1原创 2020-08-21 00:41:14 · 158 阅读 · 0 评论 -
647.回文子串
647.回文子串题解 计算回文串的个数,使用回文中心法时间复杂度会更优,即以当前字符为中心,向左右两边遍历,若不同则移动字符中心。可以发现每个长度为n的字符串,能且只能生成2n-1组回文组合,从0遍历到2n-2即可统一n为奇数和偶数的情况。class Solution { public int countSubstrings(String s) { int n = s.length(), ans = 0; for (int i = 0; i < 2 *原创 2020-08-19 23:32:52 · 157 阅读 · 0 评论 -
109.有序链表转换二叉搜索树
109.有序链表转换二叉搜索树题解 要达到左右平衡的目的,需要有序单链表当中找到中间节点作为树的根节点的值,这样两边的高度才能差不多。需要注意的是,当单链表的节点为偶数,位于中间的两个节点都可作为根节点的值,递归建树即可。class Solution { ListNode globalHead; public TreeNode sortedListToBST(ListNode head) { globalHead = head; int lengt原创 2020-08-18 22:25:57 · 119 阅读 · 0 评论 -
110.平衡二叉树
110.平衡二叉树题解 本题主要是求出二叉树左右子树高度,求出后递归比较即可。 public boolean isBalanced(TreeNode root) { if (root == null) { return true; } else { return Math.abs(height(root.left) - height(原创 2020-08-17 20:39:42 · 128 阅读 · 0 评论 -
733.图像渲染
733.图像渲染题解 后续的操作类似,使用递归算法,深度优先搜索。注意要保留原有颜色来递归。class Solution { int[] dx = {1, 0, 0, -1}; int[] dy = {0, 1, -1, 0}; public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { int currColor = image[sr][sc]; if (原创 2020-08-16 23:54:26 · 137 阅读 · 0 评论 -
546. 移除盒子
546. 移除盒子题解 本题可能的情况很多,显然要用dp动态规划。这里的状态转移方程并不好想,大致可分为两种情况。设f(l,r,k)为在区间(l,r)中,r右边与r处相同的元素有k个的最大积分。①将r及r右边相同的元素点爆,得到积分(k+1)^2,左边积分为f(l,r-1,0)②从最左边开始找和r处相同的元素,将该元素和r之间所有电灯泡点爆,若相同处为i,得积分f(i+1,r-1,0),剩余得积分f(l,r,k+1)class Solution { public int rem原创 2020-08-15 23:31:01 · 116 阅读 · 0 评论 -
20.有效的括号
20.有效的括号题解 本题需要匹配后进的符号,所以用到"后进先出"的栈,需要括号有效,则每当遇到)}],都需要栈顶元素为({[。符合则弹出栈顶元素,否则返回false即可。class Solution { public boolean isValid(String s) { int n = s.length(); if (n % 2 == 1) { return false; } Map<Cha原创 2020-08-14 22:11:14 · 143 阅读 · 0 评论 -
43. 字符串相乘
43. 字符串相乘题解 我们可以把字符串中的每一位,拿出来和另一个字符串的每一位相乘。存入数组中,再将超过10的数组元素向前进,保留个位。因为位数可能会很大,超出字符串本身的最大位数,所以我们用字符串拼接的方式输出。class Solution { public String multiply(String num1, String num2) { if (num1.equals("0") || num2.equals("0")) { return原创 2020-08-13 22:20:31 · 131 阅读 · 0 评论 -
130.被围绕的区域
130.被围绕的区域题解 从边界处的O出发,把所有与边界O相连的O都标记为A,方便后续将所有剩余的O替换成X,所有的A替换成O。class Solution { int n, m; public void solve(char[][] board) { n = board.length; if (n == 0) { return; } m = board[0].length;原创 2020-08-11 23:06:56 · 112 阅读 · 0 评论 -
696.计数二进制字串
696.计数二进制字串题解 本题有一个隐藏结论:由形如00111,或11100的字符串,符合要求的字串数量为Math.min(n,m),其中n,m为连续字符的个数,如000111111的n=3,m=6。而得到连续字符序列{1,3,2,3},表示字符串若为0开头,则是011100111,符合要求的字串数量为min(1,3)+min(3,2)+min(2,3)class Solution { public int countBinarySubstrings(String s) {原创 2020-08-10 20:35:01 · 115 阅读 · 0 评论 -
93.复原IP地址
93.复原IP地址题解 因为要找出所有可行的ip地址,我们需要选择个位数、十位数、小于255的百位数(十六进制的0XFF)分别遍历。因为后续操作十分类似,我们可以选择使用递归。当遍历到了字符串末尾,操作完成。当ip地址的四段都已确定,而字符串还未遍历完,操作完成。当下一字符为0,后一段ip只能为单一的0。当选择的数超过255,for循环中必须break。class Solution { List<String> res = new LinkedList<>原创 2020-08-09 21:34:34 · 162 阅读 · 1 评论 -
336.回文对
336.回文对题解 本来暴力可破,到了115/134个用例时超过了时间限制。本题可用字典树优化暴力算法。先把各个字符串倒序插入字典树,可分三种情况。①字典树中有当前字符串的翻转单词 符合题意②当前字符串是回文串,那么可以查找字典树中的空字符③普通情况 检查当前字符串前j个字符组成的字符串是不是回文串,若是则检索字典树时候存在后面部分的翻转即可。 同理可从后面开始检查,提高效率class Solution { public class Trie { Trie[] nex原创 2020-08-06 21:18:44 · 177 阅读 · 0 评论 -
207.课程表
207.课程表题解 用数组记录每个课程的入读,如果某课程的入读为0,把课程推进队列。将队列课程逐一推出,则将需要该课程的课程入度减一,若入读为0,则又将该课程推进队列。将当队列为空,若课程数等于推出数,则为true,否则为false。class Solution { List<List<Integer>> edges; int[] indeg; public boolean canFinish(int numCourses, int[][] pre原创 2020-08-04 21:56:11 · 120 阅读 · 0 评论 -
415.字符串相加
415.字符串相加题解 获取每一位的数字之和,保留个位,前面的十位若有进一,拼接字符串,最后返回反转的字符串。class Solution { public String addStrings(String num1, String num2) { int i =num1.length()-1, j = num2.length()-1, add = 0; StringBuffer ans = new StringBuffer();原创 2020-08-03 23:16:55 · 122 阅读 · 0 评论 -
114.二叉树展开为链表
114.二叉树展开为链表题解 展开后,单链表的访问顺序就是树的前序遍历顺序,所以先进行前序遍历保存在list中,再构建单链表,左节点都为空。/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { thi原创 2020-08-02 20:41:42 · 103 阅读 · 0 评论 -
144.二叉树的前序遍历
144.二叉树的前序遍历题解 每次迭代弹出栈顶元素,记录其根数值,按次序将其右孩子、左孩子压入栈中,/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */class Solution { publi原创 2020-08-02 20:41:11 · 125 阅读 · 0 评论 -
632.最小区间
632.最小区间题解 最小区间的最大值必定是全部序列的最小值中的最大值,遍历可得。最小区间的最小值必定来自于全部序列的最小值中的最小值的所在序列。将新序列最小值弹出,把所在序列的下一元素收入队列。为了缩小新序列长度直到求到最小区间,不断重复以上操作,直到新序列的最小值为所在序列的最大元素。class Solution { class NumGroup{ public NumGroup(int num, int grp){ this.num = num原创 2020-08-01 21:42:04 · 219 阅读 · 0 评论 -
343.整数拆分
343.整数拆分题解 我们并不知道这个数分成几个相乘会最大,所以要使用动态规划遍历计算所有的情况。一个数i,可以分为j和i-j,也可以把i-j继续细分。设f[i]为所求值,所以比较j*(i-j)和j*f[i-j]即可。其中1 <= j < i,f[0] = f[1] = 0代码class Solution { public int integerBreak(int n) { int[] f = new int[n+1]; int max = 0原创 2020-07-30 22:54:44 · 179 阅读 · 0 评论