01 2023 档案
摘要:题目链接 26. 删除有序数组中的重复项 思路 设定两个指针 i 和 j,使用 j 遍历数组,将与前项不相等的元素放到 i 的位置。 代码 、class Solution { public int removeDuplicates(int[] nums) { int i = 1; int j = 1
阅读全文
摘要:题目链接 283. 移动零 思路 设定两个指针 i 和 j,使用 j 遍历数组,将非零元素送到 i 的位置后 i++。经过第一次循环后所有的非零数都被送到了数字前面,只需要将剩余的位置变为 0 即可。 代码 class Solution { public void moveZeroes(int[]
阅读全文
摘要:题目链接 11. 盛最多水的容器 思路 在每个状态下,无论长板或短板向中间收窄一格,都会导致水槽底边宽度−1: 若向内移动短板,则 可能变大,因此下个水槽的面积可能增大 。 若向内移动长板,则 不变或变小,因此下个水槽的面积一定减小
阅读全文
摘要:题目链接 18. 四数之和 思路 与 【双指针】LeetCode 15. 三数之和 思路相似,但是要注意测试用例可能溢出,需要转换为 long 代码 class Solution { public List<List<Integer>> fourSum(int[] nums, int target)
阅读全文
摘要:题目链接 16. 最接近的三数之和 思路 借鉴 【双指针】LeetCode 15. 三数之和 的思路,只不过把0换成 target 代码 class Solution { public int threeSumClosest(int[] nums, int target) { Arrays.sort
阅读全文
摘要:题目链接 15. 三数之和 思路 可以借鉴 【双指针】LeetCode 167. 两数之和 II - 输入有序数组 的思路,将 nums[i] 作为 target,不断移动 j 和 k 来达到目标。 去重的方法:通过判断 nums[j] == nums[j + 1] 和 nums[k] == num
阅读全文
摘要:题目链接 167. 两数之和 II - 输入有序数组 思路 本思路来自 一张图告诉你 O(n) 的双指针解法的本质原理(C++/Java) 下图是白色部分初始的搜索空间,即 A[0] + A[7] 假如 target > A[0] + A[7],此时 A[7]已经是搜索空间中最大的数了,所以应该让
阅读全文
摘要:题目链接 647. 回文子串 思路 使用中心扩散法解决,在 【双指针】LeetCode 5. 最长回文子串 的代码上稍作修改即可。 代码 class Solution { public int countSubstrings(String s) { int result = 0; for(int i
阅读全文
摘要:题目链接 5. 最长回文子串 思路1:中心扩散法 遍历字符串 s,对于每个字符都以它为中心向两边扩散,测得最长回文子串。 注意:在扩散的过程中要分回文串长度奇偶进行扩散,因为长度为偶数的回文串中心是两个字母 时间复杂度: 空间复杂度: 代码1 class Solution
阅读全文
摘要:题目链接 680. 验证回文串 II 思路 题目允许删除一个字符,那么当我们判断到一对字符不相等时,可以分别判断区间 和区间 是否能构成回文串,只要有一个能构成回文串,则合法。 代码 class Solution { p
阅读全文
摘要:题目链接 125. 验证回文串 思路 简单双指针应用 代码 class Solution { public boolean isPalindrome(String s) { StringBuffer sgood = new StringBuffer(); int length = s.length(
阅读全文
摘要:题目链接 772. 基本计算器 III 实现一个基本的计算器来计算简单的表达式字符串。 表达式字符串只包含非负整数,算符 +、-、、/ ,左括号 ( 和右括号 ) 。整数除法需要 向下截断 。 你可以假定给定的表达式总是有效的。所有的中间结果的范围均满足 [-231, 231 - 1] 注意:你不能
阅读全文
摘要:题目链接 227. 基本计算器 II 思路 代码 class Solution { // 使用 map 维护一个运算符优先级 // 这里的优先级划分按照「数学」进行划分即可 Map<Character, Integer> map = new HashMap<Character, Integer>()
阅读全文
摘要:题目链接 224. 基本计算器 思路 代码 class Solution { public int calculate(String s) { // 存放所有的数字 Deque<Integer> nums = new ArrayDeque<>(); // 为了防止第一个数为负数,先往 nums 加个
阅读全文
摘要:题目链接 281. 锯齿迭代器 给出两个一维的向量,请你实现一个迭代器,交替返回它们中间的元素。 示例: 输入: v1 = [1,2] v2 = [3,4,5,6] 输出: [1,3,2,4,5,6] 解析: 通过连续调用 next 函数直到 hasNext 函数返回 false, next 函数返
阅读全文
摘要:题目链接 346. 数据流中的移动平均值 给定一个整数数据流和一个窗口大小,根据该滑动窗口的大小,计算其所有整数的移动平均值。 实现 MovingAverage 类: MovingAverage(int size) 用窗口大小 size 初始化对象。 double next(int val) 计算并
阅读全文
摘要:题目链接 409. 最长回文串 思路 遍历字符串过程中统计字符出现个数,如果达到2则说明可以放到回文串的两端,需要 result += 2。 遍历完之后的回文串如果长度小于 s,说明 s 中存在奇数字符,则返回 result + 1。因为放两个奇数字符会破坏回文性。 代码 class Solutio
阅读全文
摘要:题目链接 951. 翻转等价二叉树 思路 如果二叉树 root1,root2 根节点值相等,那么只需要检查他们的孩子是不是相等就可以了。 如果 root1 或者 root2 是 null,那么只有在他们都为 null 的情况下这两个二叉树才等价。 如果 root1,root2 的值不相等,那这两个二
阅读全文
摘要:题目链接 101. 对称二叉树 思路 DFS 递归解决 代码 class Solution { public boolean isSymmetric(TreeNode root) { if(root == null){ return true; } return dfs(root.left, roo
阅读全文
摘要:题目链接 226. 翻转二叉树 思路 将左右子树抽象为两个结点,直接进行交换。然后再递归左右子树。 代码 class Solution { public TreeNode invertTree(TreeNode root) { if(root == null){ return null; } Tre
阅读全文
摘要:题目链接 543. 二叉树的直径 思路 创建全局变量 diameter 以记录左子树高度加右子树高度,并在 DFS 过程中维护此变量。 代码 class Solution { int diameter; public int diameterOfBinaryTree(TreeNode root) {
阅读全文
摘要:题目链接 210. 课程表 II 思路 在 BFS 过程中将所有入度为0的点放入结果集中,如果最终结果集中点的数目和课程数一样,则说明这个结果集可行。 代码 class Solution { public int[] findOrder(int numCourses, int[][] prerequ
阅读全文
摘要:原文地址:List (或ArrayList) 转换为int[]数组 终于搞懂了 import java.util.ArrayList; import java.util.List; //list转为数组 public class Main { public static void main(Stri
阅读全文
摘要:题目链接 207. 课程表 思路 参考Krahets大佬的思路 代码 class Solution { public boolean canFinish(int numCourses, int[][] prerequisites) { int[] indegrees = new int[numCou
阅读全文
摘要:题目链接 417. 太平洋大西洋水流问题 思路 问题可以转换成从四个边界出发,能和内部哪些点连通。 因为涉及到两个可达性问题,所以用两个 boolean 类型矩阵分别记录一个点到太平洋和大西洋的可达性。 代码 class Solution { public List<List<Integer>> p
阅读全文
摘要:题目链接 542. 01 矩阵 思路 题目让求1到0的距离,其实可以转换成求0到1的距离,将所有的0作为源结点放入队列进行BFS。 BFS本质上就是从源点开始的搜索算法,本题只不过是所有的0都是源点,即多源点,将所有源点放入队列就行。 如果0的旁边没有1,则不会对其周围进行访问;如果0的周围有1,则
阅读全文
摘要:BFS 单向BFS 不记录层数 while queue 不空: cur = queue.pop() for 节点 in cur的所有相邻节点: if 该节点有效且未访问过: queue.push(该节点) 作者:负雪明烛 链接:https://leetcode.cn/problems/01-matr
阅读全文
摘要:题目链接 1091. 二进制矩阵中的最短路径 思路 BFS 找最短路模板题 代码 class Solution { public int shortestPathBinaryMatrix(int[][] grid) { if(grid[0][0] == 1 || grid[grid.length -
阅读全文
摘要:题目链接 752. 打开转盘锁 思路 双向BFS,详见宫水三叶大佬题解。 与拓展题目的思路异曲同工。 代码 class Solution { public int openLock(String[] deadends, String target) { String beginNumber = "0
阅读全文
摘要:题目链接 127. 单词接龙 思路 参考宫水三叶大佬的题解 本题最朴素的解法是运用 BFS 求解,从 beginWord 出发,枚举所有替换一个字符的方案,如果方案存在于 wordList 中,则加入队列中,这样队列中就存在所有替换次数为 1 的单词。然后从队列中取出元素,继续这个过程,直到遇到 e
阅读全文
摘要:题目链接 130. 被围绕的区域 思路 BFS 模板的简单变换。 分析题目可以知道,如果一片 O 想要存活,则这一片 O 必然与边界接触。我们可以遍历四个边界,找到所有与边界接触的 O,则剩下的就是需要变为 X 的 O。 代码 class Solution { void bfs(int i, int
阅读全文
摘要:题目链接 133. 克隆图 思路 通过 HashMap 存储原结点与克隆结点的对应关系,这样在 BFS 遍历图的过程中,能够很方便找到该结点对应的克隆结点,并修改克隆结点的邻接表。 代码 class Solution { public Node cloneGraph(Node node) { if(
阅读全文
摘要:题目链接 200. 岛屿数量 思路 BFS在图上的简单应用 代码 class Solution { private void bfs(int i, int j, boolean[][] visit, char[][] grid) { int[] dx = new int[]{1, 0, -1, 0}
阅读全文
摘要:题目链接 297. 二叉树的序列化与反序列化 思路 使用BFS的方法进行序列化及反序列化 序列化 运用BFS遍历树的所有结点,不论是否为null都放进队列中。 如果结点不为 null,则把结点数据转为字符串放入结果字符串中。 如果结点为 null,则把 "X" 放入结果字符串中。 所有结点都以 ",
阅读全文
摘要:题目链接 103. 二叉树的锯齿形层序遍历 思路1 额外加一个栈来使得访问节点的顺序是逆序的 代码1 class Solution { public List<List<Integer>> zigzagLevelOrder(TreeNode root) { if(root == null){ ret
阅读全文
摘要:题目链接 102. 二叉树的层序遍历 思路 树的层次遍历模板题,需要使用一个变量来记录每一层的结点个数 代码 class Solution { public List<List<Integer>> levelOrder(TreeNode root) { if(root == null){ retur
阅读全文
摘要:题目链接 34. 在排序数组中查找元素的第一个和最后一个位置 思路 转自:林小鹿的题解 两套二分查找模板,分别用来查找左边界和右边界 int bsearch_1(int l, int r) { while (l < r) { int mid = (l + r)/2; if (check(mid))
阅读全文
摘要:题目链接 295. 数据流的中位数 思路 维护两个优先队列,分别装载排序后数据流左边的数和数据流右边的数,其中 left 为大顶堆,right 为小顶堆。如果元素个数是奇数,则把中位数放到 left 中。 代码 class MedianFinder { PriorityQueue<Integer>
阅读全文
摘要:题目链接 692. 前K个高频单词 思路 还是与前k大问题一样,只不过需要注意一下字典序的问题。 代码 class Solution{ public List<String> topKFrequent(String[] words, int k){ HashMap<String, Integer>
阅读全文
摘要:题目链接 23. 合并K个升序链表 思路 把全部结点放入优先队列中,然后再依次组成新链表 代码 class Solution { public ListNode mergeKLists(ListNode[] lists) { PriorityQueue<Integer> listNodePriori
阅读全文
摘要:题目链接 347. 前 K 个高频元素 思路 前k大模板题 代码 class Solution{ public int[] topKFrequent(int[] nums, int k){ PriorityQueue<Map.Entry<Integer, Integer>> priorityQueu
阅读全文
摘要:题目链接 973. 最接近原点的 K 个点 思路 使用优先队列处理前k大问题 代码 class Solution { class Node{ int x; int y; double distance; } public int[][] kClosest(int[][] points, int k)
阅读全文
摘要:题目链接 299. 猜数字游戏 思路 建立两个哈希表分别存储 secret 和 guess 中不是bulls的数字出现次数。 代码 class Solution{ public String getHint(String secret, String guess){ int[] secretAlph
阅读全文
摘要:题目链接 350. 两个数组的交集 II 思路 建立两个哈希表分别统计 nums1 和 nums2 中每个数字出现的个数,然后同时遍历两个哈希表,对两个对位元素取其最小值 count,将 count 数量的数字放入结果数组中。 代码 class Solution { public int[] int
阅读全文
摘要:题目链接 49. 字母异位词分组 思路 如果一对字符串是字母异位词,那么他们经过排序之后,应该是相等的。 利用这一特点,我们通过哈希表建立排序后字符串到原字符串列表的映射,不断把 strs 中的字符串加入到合适的链表中。 最后遍历哈希表,可以得到最终结果。 代码 class Solution{ pu
阅读全文
摘要:题目链接 380. O(1) 时间插入、删除和获取随机元素 思路 下面引用宫水三叶大佬的题解 insert 操作:使用哈希表判断 val 是否存在,存在的话返回 false,否则将其添加到 nums,更新 idx,同时更新哈希表; remove 操作:使用哈希表判断 val 是否存在,不存在的话返回
阅读全文
摘要:题目链接 73. 矩阵置零 思路1 遍历矩阵,分别使用集合 row 和 column 记录值为0的行和列。最后将 row 和 column所记录的行和列置为零。 空间复杂度: 代码1 class Solution { public void setZeroes(int[][]
阅读全文
摘要:题目链接 128. 最长连续序列 思路 题目要求找连续序列,且时间复杂度读要求 O(n),可以使用集合进行实现。 代码 class Solution{ public int longestConsecutive(int[] nums){ Set<Integer> numSet = new HashS
阅读全文
摘要:题目链接 146. LRU 缓存 思路 使用Java中的 LinkedHashMap 类型,其数据结构示意图如下图所示。 因为该数据结构中最近添加的元素都在链表尾部,所以要让某个元素变为最近使用的状态,需要将它先删除,然后再插入。表头存储的就是最少使用的元素,使用 this.cache.keySet
阅读全文
摘要:题目链接 1. 两数之和 思路 使用 HashMap 来存储每个元素的下标及其所需要加和的数,遍历数组,检查每个数是否在 HashMap 中有对应的加和数,如果没有则把该数也加入 HashMap 中。 代码 class Solution{ public int[] twoSum(int[] nums
阅读全文
摘要:题目链接 735. 行星碰撞 思路 当分支情况太多的时候,使用 bool 变量来判断是否应该压入栈 代码 class Solution{ public int[] asteroidCollision(int[] asteroids){ Stack<Integer> stack = new Stack
阅读全文
摘要:题目链接 1249. 移除无效的括号 思路 定义数组 valid 来记录每个字符的合法性,定义栈 stack 来存储每个左括号的下标。遍历数组。 碰到字母直接 valid[i] = true。 碰到左括号则将索引压栈,valid[i] = true。 碰到右括号进行判断 如果栈不为空,则弹出栈顶元素
阅读全文
摘要:题目链接 1209. 删除字符串中的所有相邻重复项 II 思路 用栈存储 Pair<Character, Integer> ,整数表示该字符连续出现的次数。遍历字符串 s 将其中的字符 c 依次压入栈顶并判断: c 和栈顶元素相同,则其整数部分=栈顶整数部分+1,此时如果 c 的整数部分为 k 则进
阅读全文
摘要:题目链接 1472. 设计浏览器历史记录 思路 用栈 history 模拟网页的前进后退操作,用栈 temp 来暂时存储后退所退出的网页。 代码 class BrowserHistory{ Stack<String> history; Stack<String> temp; public Brows
阅读全文
摘要:题目链接 20. 有效的括号 思路 碰见左括号就入栈,碰见右括号就和检查栈顶括号是否配队。遍历完后还要检查栈是否为空,确定括号数量是合法的。 代码 class Solution{ public boolean isValid(String s){ Stack<Character> stack = n
阅读全文
摘要:题目链接 150. 逆波兰表达式求值 思路 从左到右遍历 tokens 遇到数字便放入栈中,遇到运算符便弹出栈顶的两个数字进行运算。 代码 class Solution{ public int evalRPN(String[] tokens){ Stack<Integer> numbers = ne
阅读全文
摘要:题目链接 155. 最小栈 思路 让栈中的每个结点都额外存储自己入栈时的栈中最小值。这样无论何时,永远能从栈顶元素取出当前栈中的最小值。 代码 class MinStack{ // key means the number, value means the minimal number Stack<
阅读全文
摘要:题目链接 54. 螺旋矩阵 思路 通过维护上下左右四个边界变量来控制循环。 代码 class Solution { public List<Integer> spiralOrder(int[][] matrix) { int firstRow = 0; int lastColumn = matrix
阅读全文
摘要:题目链接 232. 用栈实现队列 思路 设置一个主栈 mainStack 和一个辅助栈 assistantStack,在进行入队的时候,将 mainStack 中的元素全部放入 assistantStack 中,再将 x 入队,然后再将 assistantStack 的元素放入 mainStack
阅读全文
摘要:题目链接 225. 用队列实现栈 思路 设置一个主队列 mainQueue 和一个辅助队列 assistantQueue,在进行压栈的时候,将 mainQueue 中的元素全部放入 assistantQueue 中,再将 x 压栈,然后再将 assistantQueue 的元素放入 mainQueu
阅读全文
摘要:题目链接 328. 奇偶链表 思路 根据题意,我们只需要将扫描到的索引为奇数的结点不断插入到正确位置。 比如 1->2->3->4->5 ==》 1->3->2->4->5 ==》 1->3->5->2->4 在扫描过程中需要维护四个变量: lastOdd 表示已经到正确位置的最后一个奇数,在上方例
阅读全文
摘要:题目链接 92. 反转链表 II 思路 和【链表】LeetCode 206. 反转链表的思路一样,只不过需要调整一下realHead头结点的位置,同时原题中的null在本题中为rightNode的下一个结点。 注意: 如果left == 1则说明head结点也需要被反转,此时反转后的首结点为righ
阅读全文
摘要:题目链接 142. 环形链表 II 思路 代码 class Solution { public ListNode detectCycle(ListNode head) { if(head == null){ return null; } ListNode slow = head; ListNode
阅读全文
摘要:题目链接 141. 环形链表 思路 设置fast指针和slow指针,分别走两步和一步,如果链表有环的话,那么两个指针一定会在某一时刻相遇。 可以想象成速度不同的两个人跑圈,只要时间足够,速度慢的人一定会被速度快的人套圈。 代码 class Solution { public boolean hasC
阅读全文
摘要:题目链接 160. 相交链表 思路1 先测量两个链表的长度,记录差值k=abs(n1 - n2),然后让短的链表先走k步,这样就能保证剩下的长度是一样的,再同步遍历即可。 代码1 class Solution { public: ListNode *getIntersectionNode(ListN
阅读全文
摘要:题目链接 876.链表的中间结点 思路 定义两个指针fast和slow,快的指针一次走两步,慢的指针一次走一步,这样当快的指针走到底的时候,慢指针正好在中间。 以下两幅图说明了偶数结点下,不同循环条件对慢指针结束位置的影响。 代码 class Solution { public ListNode m
阅读全文
摘要:==排序过程中,对尚未确定最终位置的元素进行一遍处理,叫做“一趟”== 内部排序的比较 插入排序 思想: 如果自己前面的元素比自己大,那么开始比较更前面的元素,放在合适的位置。 void insertSort(int a[],int n){ int i, j; for(i = 1; i < n; +
阅读全文
摘要:题目链接 215. 数组中的第K个最大元素 思路 对于给定数组,求解第 大元素,且要求线性复杂度,正解为使用「快速选择」做法。 基本思路与「快速排序」一致,每次敲定一个基准值 ,根据当前与 的大小关系,将范围在 的 划分为到两边。 同时利用,
阅读全文
摘要:题目链接 75.颜色分类 思路 题目要求按0、1、2的顺序排序,因为数量有限,所以通过两次遍历,分别将0和1交换到合适的位置,这样两次遍历之后,剩下的2就都在尾部了。 circle 代表这一次要对哪个数字进行重置位置,所以它的取值就限定在0、1,因为当我们确定好0和1位置之后,2的位置也就确定好了。
阅读全文
摘要:题目链接 179. 最大数 思路 转自宫水三叶大佬的题解 对于 nums 中的任意两个值 a 和 b,我们无法直接从常规角度上确定其大小/先后关系。 但我们可以根据「结果」来决定 a 和 b 的排序关系: 如果拼接结果 ab 要比 ba 好,那么我们会认为a应该放在b前面。 代码 class Sol
阅读全文