LeetCode
文章平均质量分 50
记录刷题。
Yawn__
“就像热爱漫无边际。”
展开
-
Leetcode——从英文中重建数字
1. 从英文中重建数字2 题解首先我们可以统计每个字母分别在哪些数字中出现:然后根据「英文单词中的字符唯一性」确定构建的顺序,最后再对答案进行排序即可。zero 中的 z 在其余所有单词中都没出现过,我们可以先统计 zero 的出现次数,并构建 0;然后观察剩余数字,其中 eight 中的 g 具有唯一性,构建 8;再发现 six 中的 x 具有唯一性,构建 6;发现 three 中的 h 具有唯一性(利用在此之前 eight 已经被删除干净,词频中仅存在 three 对应的 h),构建原创 2021-11-29 14:00:09 · 3418 阅读 · 0 评论 -
Leetcode——最长定差子序列
1. 接雨水2(1)原创 2021-11-05 15:41:40 · 117 阅读 · 0 评论 -
Leetcode——路径交叉
1. 路径交叉(1)模拟时间复杂度:O(n)O(n)。空间复杂度:O(1)O(1)。不想交总共有三种情况:(1)外卷:dist[i] > dist[i-2] 就一直不会相遇(2)内卷:dist[i] < dist[i-2]就一直不会相遇外卷 卷 内卷:如下图所示,这种分情况讨论,只有出现下面这种情况才不会相交,而我们只要在外卷内卷交界处做一个特殊处理就可以转换成上面两种情况,即 dist[i] > dist[i-2] - dist[i-4] 时,从 i-1原创 2021-10-29 11:04:07 · 3530 阅读 · 0 评论 -
Leetcode——重新排序得到 2 的幂
1. 重新排序得到 2 的幂(1)DFS对 n 进行重排,然后检查重排后的数值是否属于 2 的幂。由于 2 的幂数固定,我们可以先通过「打表」将范围落在 [1, 1e9] 以内的 2 的幂预处理出来,这样我们可以在 O(1)的复杂度内判断某个数是否为 22 的幂。class Solution { static Set<Integer> set = new HashSet<>(); static { for (int i = 1; i <原创 2021-10-28 11:33:14 · 151 阅读 · 0 评论 -
Leetcode——最小操作次数使数组元素相等
1.最小操作次数使数组元素相等(1)朴素很重要的一点,n-1增加1,相当于剩下的那个减1。等价于使 n - 1 个元素增加 1,这个操作实际上可以等价于使1个元素减少1要保证数组中最小的元素不要再减小,对其他的元素使用这个操作,最终所有元素都减至最小值就可以结束了。进行两次遍历,第一次遍历找出最小值,第二次遍历求每个元素与最小值的差值,也就是操作次数,最后对操作次数求和就是我们的答案class Solution { public int minMoves(int[] nums) {原创 2021-10-20 13:09:47 · 330 阅读 · 0 评论 -
Leetcode——整数转换英文表示
1. 整数转换英文表示(1)字符串模拟英文中数字表示是每三位一组进行的,x>=100:此时首先需要表示成 ??? hundred,表示完后考虑更小的位数;x >= 20:此时需要表示成 ??? XXX-ty 的形式,表示完后考虑更小的位数;x < 20:直接描述成具体的单词。class Solution { private static int BILLION = (int)Math.pow(10, 9); private static int MILLION原创 2021-10-12 10:42:26 · 264 阅读 · 0 评论 -
Leetcode——将数据流变为多个不相交区间
1. 将数据流变为多个不相交区间(1)模拟假设当前第一次加入一个值为 val 的元素,那么只有四种情况:(1)数据流中已经被加入了 val - 1 和 val + 1 两个元素,但因为 val 第一次被加入,所以当前数据流的区间列表中,一定存在两个区间,一个以 val - 1 结尾,另一个以 val + 1 开头。那么,加入 val 后,这两个区间就可以被合并为一个区间。(2)数据流中已经被加入了 val - 1,但没有 val + 1。此时,区间列表中一定存在一个区间,以 val - 1 结尾原创 2021-10-09 11:30:54 · 110 阅读 · 0 评论 -
Leetcode——重复的DNA序列
1. 重复的DNA序列(1)滑动窗口 + 哈希表从左到右处理字符串 ss,使用滑动窗口得到每个以 s[i]为结尾且长度为 10 的子串,同时使用哈希表记录每个子串的出现次数,如果该子串出现次数超过一次,则加入答案。为了防止相同的子串被重复添加到答案,而又不使用常数较大的 Set 结构。我们可以规定:当且仅当该子串在之前出现过一次(加上本次,当前出现次数为两次)时,将子串加入答案class Solution { public List<String> findRepeated原创 2021-10-09 11:05:01 · 411 阅读 · 0 评论 -
Leetcode——栈的压入、弹出序列
1. 栈的压入、弹出序列(1)模拟给定一个压入序列 pushedpushed 和弹出序列 poppedpopped ,则压入 / 弹出操作的顺序(即排列)是 唯一确定 的。如下图所示,栈的数据操作具有 先入后出 的特性,因此某些弹出序列是无法实现的。考虑借用一个辅助栈 stack,模拟 压入 / 弹出操作的排列。根据是否模拟成功,即可得到结果。入栈操作: 按照压栈序列的顺序执行。出栈操作: 每次入栈后,循环判断 “栈顶元素 == 弹出序列的当前元素” 是否成立,将符合弹出序列顺序的栈顶元原创 2021-09-30 16:33:06 · 334 阅读 · 0 评论 -
Leetcode——正则表达式匹配
1. 正则表达式匹配(1)递归以字符串"aaa"和模式串"abac*a"为例:这里有两种匹配方式:(1)单个匹配,如果两个字符相同,或者模式串当前是万能字符.,则匹配成功,然后继续递归比较 s[i + 1:] 和p[i + 1:](2)如果模式串后面跟了"*",这又分为两种情况:1.如果s[i]和p[i]不等(比如aa和b*这种情况),则将b *忽略掉,也就是继续递归比较s和p[i + 2:]2.如果p[i]和s[i]相等(比如aa和a*这种情况),我们可以选择忽略a * ,也就是执行原创 2021-09-30 16:08:54 · 395 阅读 · 0 评论 -
Leetcode——扁平化多级双向链表
1. 扁平化多级双向链表多级双向链表中,除了指向下一个节点和前一个节点指针之外,它还有一个子链表指针,可能指向单独的双向链表。这些子列表也可能会有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。给你位于列表第一级的头节点,请你扁平化列表,使所有结点出现在单级双链表中。示例 1:输入:head = [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]输出:[1,2,3,7,8,11,12,9,10,4,5,6]解释:输原创 2021-09-26 16:09:54 · 120 阅读 · 0 评论 -
Leetcode——两整数之和
1. 两整数之和(1)位运算对于二进制的加法运算,若不考虑进位,与异或运算类似1+1=01+0=10+1=10+0=0再来考虑进位,不难发现,此方法与异或运算&类似,所以加法可用异或来实现,然后考虑进位0+0 进位为 01+0 进位为 10+1 进位为 01+1 进位为 1加法运算可以这样实现:异或替代不进位加法如果进位不为0, 说明有进位 , 结果 = 异或的结果 + 进位在异或前收集进位, 异或后判断是否要加进位先来看一个例子 7 + 1的过程:【原创 2021-09-26 14:53:27 · 196 阅读 · 0 评论 -
Leetcode——文本左右对齐
1. 文本左右对齐(1)暴力模拟如果当前行只有一个单词,特殊处理为左对齐;如果当前行为最后一行,特殊处理为左对齐;其余为一般情况,分别计算「当前行单词总长度」、「当前行空格总长度」和「往下取整后的单位空格长度」,然后依次进行拼接。当空格无法均分时,每次往靠左的间隙多添加一个空格,直到剩余的空格能够被后面的间隙所均分。class Solution { public List<String> fullJustify(String[] words, int maxWid原创 2021-09-16 17:24:06 · 234 阅读 · 1 评论 -
Leetcode——找到需要补充粉笔的学生编号
1. 找到需要补充粉笔的学生编号(1)暴力class Solution { public int chalkReplacer(int[] chalk, int k) { int len = chalk.length; for (int i = 0; i <= len; i++) { //到最后一个值,开启下一轮循环 if (i == len) { i = 0;原创 2021-09-16 16:30:06 · 132 阅读 · 0 评论 -
Leetcode——不含连续1的非负整数(数位DP,打家劫舍,理解不够深)
1. 不含连续1的非负整数(1)递归(参考打家劫舍)这道题其实有点类似 打家劫舍: 不能包含相邻的1class Solution { HashMap<Integer, Integer> dp = new HashMap<>(); public int findIntegers(int n) { // 特殊情况:0,1,10,11,100 if(n < 4) return n < 3 ? n原创 2021-09-15 16:41:09 · 117 阅读 · 0 评论 -
Leetcode——回旋镖
1. 回旋镖(1)Hash表class Solution { public int numberOfBoomerangs(int[][] points) { int n = points.length; int ans = 0; for (int i = 0; i < n; i++) { Map<Integer, Integer> map = new HashMap<>();原创 2021-09-13 20:37:49 · 139 阅读 · 0 评论 -
Leetcode—— IPO(最大化投资资金)
1. IPO(1)贪心 + 优先队列每完成一个任务都会使得总资金 w 增加或不变。因此对于所选的第 i 个任务而言,应该在所有未被选择且启动资金不超过 w 的所有任务里面选利润最大的。每次决策前,将启动资金不超过当前总资金的任务加入集合,再在里面取利润最大的任务取最大的过程可以使用优先队列(根据利润排序的大根堆),而将启动资金不超过当前总资金的任务加入集合的操作,可以利用总资金在整个处理过程递增,而先对所有任务进行预处理排序来实现。具体步骤1.根据 profits 和 capital原创 2021-09-08 15:34:27 · 223 阅读 · 0 评论 -
Leetcode——比较版本号
1. 比较版本号(1)字符串模拟对字符串进行分割,诸位比较「修订号」大小即可。对于缺省的修订号位置,使用 00 进行代指。时间复杂度:令 v1 长度为 n,v2 长度为 m。整体复杂度为O(max(n,m))空间复杂度:O(n + m)O(n+m)class Solution { //对字符串进行分割,诸位比较「修订号」大小即可。 //对于缺省的修订号位置,使用 00 进行代指。 public int compareVersion(String v1, String原创 2021-09-01 11:45:22 · 542 阅读 · 0 评论 -
Leetcode——矩阵置零
1. 矩阵置零(1)朴素(Set)思路:第一次循环,存储存在元素为0的行数和列数第二次循环,将存在元素0的行列全部置0时间复杂度O(m*n)空间复杂度O(m+n)class Solution { public void setZeroes(int[][] matrix) { Set<Integer> row = new HashSet<>(); Set<Integer> col = new HashSet<原创 2021-08-30 17:29:46 · 167 阅读 · 0 评论 -
Leetcode——检查数组对是否可以被 k 整除
1. 检查数组对是否可以被 k 整除(1)双指针(暴力超时)把数组中的元素每两个分为一组,总共分为n/2组,然后确保每组都能被k整除,这样结果才会返回true,否则返回false。每个元素都必须有另外一个元素与他相匹配才行,只要有一个不匹配就返回false其实这里面有个数学问题,假如有两组数据(a,b)和(c,d)他们都能被k整除,也就是说(a+b)%k=0,并且(c+d)%k=0;如果(a+c)%k=0,那么(b+d)%k=0肯定也是成立的。(这里的所有字母都是整数)举个例子,比如(3,5)原创 2021-08-30 11:55:14 · 463 阅读 · 0 评论 -
Leetcode——按权重随机选择
1. 按权重随机选择(1)朴素思路容易想到的思路就是将每个下标复制其权重份,然后随机选取一个:如上图所示,下标 0 处权重为 2,那么我们就往一个数组中存入 2 个值为 0(对应下标值) 的节点;同理,我们存入 1 个值为 1 的节点,和 4 个值为 2 的节点(2)前缀和优化但是,根据题目给出的数据范围,最坏情况下要存入109个节点,说明该解法是不行的!但是,我们可以参考这个暴力的思路,来进行一定的优化。上面思路的原理是,将数组分为 n 份,每份的权重为 w[i],如下图所示:那么,原创 2021-08-30 10:00:54 · 683 阅读 · 0 评论 -
Leetcode——完成任务的最少工作时间段(回溯)
1. 完成任务的最少工作时间段(1)回溯class Solution { int res; int maxSessionTime; int[] tasks; int[] sessions; public int minSessions(int[] tasks, int sessionTime) { this.res = tasks.length; this.maxSessionTime = sessionTime;原创 2021-08-29 15:17:12 · 696 阅读 · 0 评论 -
Leetcode——找出数组中的第 K 大整数(字符串中数字排序)
1. 找出数组中的第 K 大整数直接排序要不得,比如:2,21,12,1如使用Arrays.sort排序,会得到:1,12,2,21的序列,因为字符串按照第一位开始排序(1)转化为数字后排序可直接转为数字后再排序,但是如传入字符串数字过大,会报错class Solution { public String kthLargestNumber(String[] nums, int k) { int[] arr = new int[nums.length];原创 2021-08-29 11:31:22 · 222 阅读 · 0 评论 -
Leetcode——所有奇数长度子数组的和(前缀和)
1. 所有奇数长度子数组的和(1)暴力三重循环class Solution { public int sumOddLengthSubarrays(int[] arr) { int sum = 0; int len = arr.length; // i 用于控制子数组长度 for (int i = 1; i <= len; i+= 2) { //j用于控制子数组起点 for原创 2021-08-29 10:45:35 · 144 阅读 · 0 评论 -
Leetcode——区域和检索 - 数组不可变 / 二维区域和检索 - 矩阵不可变 (前缀和)
1. 区域和检索 - 数组不可变(1)前缀和由于涉及 -1 操作,为了减少一些边界处理,我们可以使前缀和数组下标从 1 开始记录,然后在进行答案计算的时候,根据源数组下标是否从 1 开始决定是否产生相应的偏移:class NumArray { int[] sum; public NumArray(int[] nums) { int n = nums.length; //前缀和数组下标从 1 开始,因此设定长度为 n + 1(模板部分)原创 2021-08-28 16:05:21 · 105 阅读 · 0 评论 -
Leetcode——零钱兑换1,2
1. 零钱兑换1(1)贪心 + DFS贪心想要总硬币数最少,肯定是优先用大面值硬币,所以对 coins 按从大到小排序先丢大硬币,再丢会超过总额时,就可以递归下一层丢的是稍小面值的硬币乘法对加法的加速:优先丢大硬币进去尝试,也没必要一个一个丢,可以用乘法算一下最多能丢几个k = amount / coins[c_index] 计算最大能投几个amount - k * coins[c_index] 减去扔了 k 个硬币count + k 加 k 个硬币最先找到的并不是最优解:原创 2021-08-26 12:10:47 · 278 阅读 · 0 评论 -
Leetcode——根据身高重建队列 / 游戏中弱角色的数量 (排序,compare)
1. 根据身高重建队列(1)先排序再插队套路:一般这种数对,还涉及排序的,根据第一个元素正向排序,根据第二个元素反向排序,或者根据第一个元素反向排序,根据第二个元素正向排序,往往能够简化解题过程。在本题:首先对数对进行排序,按照数对的元素 1 降序排序,按照数对的元素 2 升序排序。原因是,按照元素 1 进行降序排序,对于每个元素,在其之前的元素的个数,就是大于等于他的元素的数量,而按照第二个元素正向排序,我们希望 k 大的尽量在后面,减少插入操作的次数。class原创 2021-08-26 11:36:39 · 97 阅读 · 0 评论 -
Leetcode——分割等和子集 / 目标和 (01背包 / DP)
1. 分割等和子集(0)背包问题与494. 目标和 类似,属于01背包问题,可以把问题抽象为“给定一个数组和一个容量为x的背包,求有多少种方式让背包装满(有多少种子集能让子集之和等于背包容量"附上01背包问题的模版://01背包for (int i = 0; i < n; i++) { for (int j = m; j >= V[i]; j--) { f[j] = max(f[j], f[j-V[i]] + W[i]); }}//完全背包for原创 2021-08-26 10:22:14 · 127 阅读 · 0 评论 -
Leetcode——重叠区间(会议室1,2) / 合并区间 / 插入区间
1. 会议室 (重叠区间)给定一个会议时间安排的数组 intervals ,每个会议时间都会包括开始和结束的时间 intervals[i] = [starti, endi] ,请你判断一个人是否能够参加这里面的全部会议。示例 1::输入: intervals = [[0,30],[5,10],[15,20]]输出: false解释: 存在重叠区间,一个人在同一时刻只能参加一个会议。示例 2::输入: intervals = [[7,10],[2,4]]输出: true解释: 不存在重原创 2021-08-24 18:11:27 · 1095 阅读 · 0 评论 -
Leetcode——判断子序列 / 判断子串 / 找子序列 / 找子串
1. 判断子序列(1)双指针使用两个指针分别指向两个字符串的起始索引,每次循环判断两个指针指向的字符是否相等,相等则两个指针向右移动,不相等则只移动 s 的指针。最后如果 t 指针移动到末尾,则 t 是为 s 的子序列。class Solution { public boolean isSubsequence(String t, String s) { int indext = 0, indexs = 0; while (indext < t.leng原创 2021-08-24 16:08:39 · 1383 阅读 · 0 评论 -
Leetcode——通过删除字母匹配到字典里最长单词(子序列)
1. 通过删除字母匹配到字典里最长单词要从字符串数组 d 中,找到一个可以从字符串 s 中,删除某些字符来得到的字符串(本文中把这种符合要求的字符串称为 s 的子序列,这个字符串要长度最长且字典序最小。我们的主要思路就是先找到字符串数组中,所有的字符串 s 的子序列,然后比较其长度和字典序。首先:判断子序列需要注意的是 “ace” 是 “abcde” 的一个子序列,而 “aec” 不是。这是因为这里的子序列是通过删除得到(1)双指针使用两个指针分别指向两个字符串的起始索引,每次循环判原创 2021-08-24 16:05:51 · 94 阅读 · 0 评论 -
Leetcode——重构字符串(相邻不同 / 奇偶交叉)
1. 重构字符串(1)奇偶交叉插入参照 169. 多数元素 和 229. 求众数 II 的解题思路,先求出出现次数最多的字符,然后再判断是否可以使得两相邻的字符不同(1)如果要使得两相邻的字符不同,那么出现次数最多的那个数的数量必须满足下面条件,如下图所示,比如下面的a是出现次数最多的这个时候a的数量已经达到了临界值,如果再多一个 a ,那么至少有两个 a 是相邻的。所以这里出现次数最多的那个字符数量的临界值是threshold = (length + 1) >> 1(其中 leng原创 2021-08-24 10:19:31 · 1440 阅读 · 0 评论 -
Leetcode——求众数1,2(多数元素)n/2, n/3
1. 求众数(1)HashMap时间:O(N)空间:O(N)接定义一个哈希表。遍历所有元素,统计其频率。之后再遍历哈希表中所有数到频率的映射对,如果频率大于N/3,则加入结果res。最后返回res即可。class Solution { public List<Integer> majorityElement(int[] nums) { List<Integer> res = new ArrayList<>(); int原创 2021-08-24 10:08:05 · 143 阅读 · 0 评论 -
Leetcode——寻找峰值
1. 寻找峰值(1)一次遍历(O(n))首先要考虑:nums[-1] 和 nums[n] 等于多少存不存在nums[i] != nums[i+1],存在二分就可能找不到由题意可知因为 nums[-1] = nums[n] = -oo所以,只要找到 nums[i] > nums[i + 1],即找到峰值class Solution { public int findPeakElement(int[] nums) { for (int i = 0; i &原创 2021-08-23 23:51:05 · 197 阅读 · 0 评论 -
Leetcode——最小的K个数(快排)
1. 最小的K个数(1)快排class Solution { public int[] getLeastNumbers(int[] arr, int k) { quickSort(arr, 0, arr.length - 1); return Arrays.copyOf(arr, k); } private void quickSort(int[] arr, int left, int right) { // 子数组长度为 1 时原创 2021-08-23 21:40:47 · 188 阅读 · 0 评论 -
Leetcode——最长重复数组(最长公共子串) / 最长重复子串
1. 最长重复数组(1)暴力跟最长公共子串一个解法,没有变化class Solution { public int findLength(int[] nums1, int[] nums2) { if (nums1 == null || nums2 == null) { return 0; } int l1 = nums1.length; int l2 = nums2.length; int原创 2021-08-23 21:11:43 · 745 阅读 · 0 评论 -
Leetcode——最长公共子序列 / 最长公共子串
1. 最长公共子序列(1)DP单个数组或者字符串要用动态规划时,可以把动态规划 dp[i] 定义为 nums[0:i] 中想要求的结果当两个数组或者字符串要用动态规划时,可以把动态规划定义成两维的 dp[i][j] ,其含义是在 A[0:i] 与 B[0:j] 之间匹配得到的想要的结果本题可以定义 dp[i][j] 表示 text1[0:i-1] 和 text2[0:j-1] 的最长公共子序列。注:text1[0:i-1] 表示的是 text1 的 第 0 个元素到第 i - 1 个元素,两端原创 2021-08-23 20:41:17 · 5672 阅读 · 0 评论 -
Leetcode——安卓系统手势解锁(九宫格)
1. 安卓系统手势解锁(1)回溯(模版方法)// 至少 需要经过 m 个点,但是 不超过 n 个点的。class Solution { int count = 0; public int numberOfPatterns(int m, int n) { if (m > n) return 0; //对于每个路径长度进行回溯 for (int i = m; i <= n; i++) {原创 2021-08-23 16:31:02 · 634 阅读 · 0 评论 -
Leetcode—— 求根节点到叶节点数字之和
1. 求根节点到叶节点数字之和(1)DFS特例处理:root为空返回0递归从根节点开始,递归时包含两个参数,一个是当前节点node,一个是到当前节点为止的数字和num如果node的左节点存在,进入左节点的递归;如果node的右节点存在,进入右节点的递归如果node的左节点和右节点都不存在,也就是当前节点是叶子节点,把num加到结果中返回resclass Solution { int res; public int sumNumbers(TreeNode root) {原创 2021-08-21 23:03:52 · 85 阅读 · 0 评论 -
Leetcode——每日温度(更高)
1. 每日温度(1)暴力(从左往右)class Solution { public int[] dailyTemperatures(int[] temperatures) { int len = temperatures.length; int[] res = new int[len]; int index = 0; //其实没必要用index计数,只是为了更加清晰 for (int i = 0; i < len; i++原创 2021-08-21 22:59:41 · 136 阅读 · 0 评论