LeetCode
Xiami2019
这个作者很懒,什么都没留下…
展开
-
每日一题 由斜杠划分区域 LeetCode959
并查集问题,把每个单元格看作是四个小三角形,然后对各个小三角形进行合并。// 每一个单元格可以分为四个小单元格,然后根据每个位置的字符进行单元格内合并或单元格间合并class UnionFind {public: UnionFind(int n): f(n), count(n) { for (int i = 0; i < n; ++i) { f[i] = i; } } int findf(int x) {原创 2021-01-25 10:41:52 · 151 阅读 · 0 评论 -
每日一题 连通网络的操作次数 LeetCode1319
裸并查集,并根据图论知识判断,如果边数大于等于顶点数减一,就一定可以改造成连通图。// 坚韧不拔,我命由我不由天!// 因为边可以任意移动,所以只要边数大于等于计算机数减一,就一定可以连通// 所需要的最小操作数等于连通分量数减一class UnionFind {public: UnionFind(int _n): f(_n), setSize(_n, 1), n(_n), setCount(_n) { for (int i = 0; i < n; ++i) {原创 2021-01-23 09:29:20 · 171 阅读 · 1 评论 -
01背包问题变式 分割等和子集
LeetCode 416 分割等和子集这道题可以看成是01背包问题,总和为m,则问题可以改写为是否能选出一些元素,恰好填满容量为m / 2的背包。状态定义:dp[i][j]: 表示使用第0到第i个物品能否填满容量为j的背包;状态转移方程:设第i个物品的体积为nums[i];if nums[i] == j:此时一定可以填满,dp[i][j] = true;if nums[i] < j:此时分装上i和不装上i两种情况:dp[i][j] = dp[i - 1][j] (不装i的情况) ||原创 2021-01-22 20:37:22 · 282 阅读 · 0 评论 -
每日一题 连接所有点的最小费用 LeetCode1584
由完全图构建最小生成树,主要有两种方法:1. Kruskal算法;2. Prim算法;Kruskal算法需要构建并查集检查每次新添加的边构不构成回路。// 本质是求解一个完全图的最小生成树;// 使用kruskal算法需要通过并查集判断连通性,使用Prim算法则不用;// 首先需要将所有边都提取到一个边集里面,然后对边长进行排序;// 每次选取最短的边,然后通过并查集判断连通性// lion is hungryclass DisjointSet {private: vector原创 2021-01-19 23:35:22 · 204 阅读 · 0 评论 -
经典DP 完全背包问题
完全背包是01背包的扩展,即每个物品是无限量供应的。LeetCode322 零钱兑换比较经典的完全背包问题。定义子问题:组成金额i所需要的最小硬币数状态:T(i) = 组成金额i所需要的最小硬币数,如果不能组成则用amount + 1表示,初始数组全部初始化成amount + 1T(i) = min(T(i - k) + 1) (k为不同面值的硬币)class Solution {public: int coinChange(vector<int>& coins,原创 2021-01-19 15:35:26 · 240 阅读 · 0 评论 -
每日一题 账户合并 LeetCode721
这个月LeetCode真的猛出并查集,学不会并查集谁也别想走。并查集方法最重要的方法就是对问题进行建模,使得问题用连通分量表示,并且转化为判断两点是否连通的问题。然后要思考在构建并查集的过程中要如何构建并查集。哈希表加并查集需要两个哈希表,分别将邮箱映射成index和映射到对应的用户的名字。把每个用户对应的邮箱地址看成是一个连通分量。构建连通分量时只需要把accounts数组中每个用户对应的邮箱地址合并起来就好。// 并查集class UnionFind {public: UnionF原创 2021-01-18 15:04:50 · 160 阅读 · 0 评论 -
经典DP问题:最长递增子序列和最长公共子序列
LIS问题:最长递增子序列(Longest Increasing Subsequence);LCS问题:最长公共子序列(Longest Common Subsequence);子序列(subsequence)和子串(substring)的概念:子序列不要求连续,而子串必须由连续的字符组成。LIS问题时间复杂度:O(n^2);空间复杂度:O(n);设置一个DP数组,维护每个位置的符号作为结尾的最小的序列长度;class Solution {public: int lengthOfLIS原创 2021-01-18 12:18:18 · 144 阅读 · 0 评论 -
每日一题 打砖块 LeetCode803
如何计算每次击碎砖块而消失的砖块数量和顶部相连的砖块不会掉落;击碎一个砖块,可能使得其它与之连接的砖块不再与顶部相连而消失;消失的砖块数量 = 击碎之前与顶部相连的砖块数量 - 击碎之后与顶部相连的砖块数量 - 1 (1就是直接被敲碎的那块砖)并查集的按秩优化的秩即可以指当前子树的高度rank,也可以指当前集合的结点总数size,此题按size优化很huochi如何使用并查集解决这个问题?消除一个砖块的效果是:一个连通分量被分成了两个连通分量;并查集的作用是:把两个连通分量合并成一个连通分原创 2021-01-16 23:29:14 · 133 阅读 · 0 评论 -
每日一题 移除最多的同行或同列石头 LeetCode947
这是一个图论问题,首先按照题意构建图。石头作为顶点。如果两个石头位于同一行或同一列,则认为这两个石头之间有一条边,即这两个石头位于同一个连通分支之内。由题中删除石头的规则可知,实际上就是不断删除连通分支之内的顶点。而每个连通分支最后都会剩下一个顶点。所以,可以移除的最大的石头数 = 石头总数 - 连通分支数。所以题目就转化为两步,首先要构建图,然后再计算图中的连通分支数。计算连通分支数一般有两类方法,一是使用DFS或BFS之类的搜索方法,二是使用并查集的方法。这里考虑并查集的方法并查集并查集回答原创 2021-01-15 11:28:55 · 164 阅读 · 0 评论 -
每日一题 冗余连接 LeetCode 684
基本是个裸并查集的题目,从edges数组中遍历每条边,并构造并查集。如果一条边的两个顶点,则这条边就是构成回路的最后一条边。又因为无向图是由一棵树加上一条额外的边所构成的,所以显然,这样的回路只存在一个,则这样的一条边就是所求。// 并查集class Solution {public: int findf(vector<int> &f, int nodes) { if (f[nodes] != nodes) { int father原创 2021-01-13 22:09:32 · 152 阅读 · 1 评论 -
每日一题 滑动窗口最大值 LeetCode239
虽然是个做过的题,但是早上心烦意乱,基本还是纯抄leetcode题解。法一:优先队列要维护一个滑动窗口内的最大值,可以使用优先队列法,即使用一个最大堆来维护。为了判定当前最大值是否还存在于滑动窗口内,可以同时存储value和index,这样当每次向优先队列加入新元素时,可以将堆顶所有不属于当前窗口的元素都弹出,保证优先队列维持的最大元素是在滑动窗口中的元素。class Solution {public: vector<int> maxSlidingWindow(vector<原创 2021-01-12 14:31:06 · 122 阅读 · 0 评论 -
每日一题 旋转数组 LeetCode189
408牛逼数组翻转先翻转前k个,再翻转后面的,然后再整个翻转。核心就是翻转数组元素的函数。有个点要注意,要用k模一下数组长度n。class Solution {public: void reverseArray(vector<int>& nums, int start, int end) { // 对数组进行翻转 if (start >= end || start < 0 || end < 0) return; for (原创 2021-01-08 16:41:07 · 165 阅读 · 0 评论 -
每日一题 省份数量 LeetCode 547
这题的本质就是求联通分支。上一题刚刚用了并查集,再一看这题不就是一个裸并查集么。法一:并查集// 法一 并查集class Solution {public: int findf(vector<int>& f, int x) { //找一个结点的父结点; if (f[x] != x) { int father = findf(f, f[x]); f[x] = father; }原创 2021-01-08 16:18:27 · 110 阅读 · 0 评论 -
每日一题 除法求值 LeetCode 399
这道题的本质是个图论问题,应该将问题建模为一个有向图,将除法表达式的变量看作是图的顶点,除法与被除数通过弧的方向来表示,除法表达式的值看作是边的权值,所以只需判断除法表达式的两点在图中是否存在路径,并且路径上每段距离的乘积就是最终表达式的结果。法一:广度优先搜索先构造图的表达形式,这里采用临接表来存储图,然后进行广度优先搜索,如果从起点出发搜到了终点,则表示这两个点之间存在路径,则把每段路径的乘积计算出来即可。class Solution {public: vector<double&原创 2021-01-08 14:46:12 · 150 阅读 · 0 评论 -
每日一题:正则表达式匹配
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*‘的正则表达式匹配。‘.’ 匹配任意单个字符‘*’ 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。说明:s 可能为空,且只包含从 a-z 的小写字母。p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。示例1:输入:s = “aa”p = “a”输出: false解释: “a” 无法匹配 “aa” 整个字符串。示例2:s = “aa”p .原创 2020-06-20 11:46:48 · 367 阅读 · 0 评论 -
斐波那契数列问题总结
n比较小的时候,可以直接使用递归法来求解,不做任何记忆化操作,时间复杂度是O(2^n),存在很多冗余计算;一般情况下,可以使用“记忆化搜索”(即动态规划)或者迭代的方法,实现这个转移方程,时间复杂度和空间复杂度都可以做到O(n);为了优化空间复杂度,可以不保存f(x-2)之前的项,我们只用两个变量来维护f(x-1)和f(x-2),这样就可以把时间复杂度优化到O(1);随着n的不断增大,O(n)可能已经不能满足我们的需要了,我们可以用“矩阵快速幂”的方法把算法加速到O(logn);也可以利用斐波那契.原创 2020-06-15 16:35:45 · 283 阅读 · 0 评论 -
每日一题:和可被K整除的子数组
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。示例:输入:A = [4,5,0,-2,-3,1], K = 5输出:7解释:有 7 个子数组满足其元素之和可被 K = 5 整除:[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]遇见子数组和的相关问题,优先考虑前缀和的做法。这里因为是整除的问题,所以前缀和需要用求模后的结果表示。class Solu.原创 2020-05-28 10:02:56 · 416 阅读 · 0 评论 -
每日一题:解码字符串
给定一个经过编码的字符串,返回它解码后的字符串。编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。示例1:s = “3[a]2[bc]”, 返回 “aaabcbc”.s = “3[a2[c.原创 2020-05-28 09:25:02 · 283 阅读 · 0 评论 -
每日一题:寻找重复数
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。示例1:输入: [1,3,4,2,2]输出: 2示例2:输入: [3,1,3,4,2]输出: 3说明:不能更改原数组;时间复杂度小于O(n^2);空间复杂度为O(1);数组中只有一个重复数字,但它可能不只重复出现一次;将index和nums[index]之间连一条边,即从index可以转移到nums[ind.原创 2020-05-26 15:34:19 · 362 阅读 · 0 评论 -
每日一题:验证回文字符串
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。示例1:输入: “aba”输出: True示例2:输入: “abca”输出: True解释: 你可以删除c字符。注意:字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。使用贪心算法。设置两个指针分别指向字符串头和字符串尾,向中间判断是否是回文。如果第一次出现不相等,因为可以删除一个字符,所以可以再次判断[low+1, high]和[low, high - 1]这两个区间是不是回文字符串。# 贪.原创 2020-05-19 12:25:06 · 297 阅读 · 0 评论 -
每日一题:和为K的子数组
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。示例1:输入:nums = [1,1,1], k = 2输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。说明:数组的长度为 [1, 20,000]。数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。采用前缀和的方法,依次计算每个位置的前缀和,并判断是否有减去k的前缀和出现,然后加上对应的前缀和出现的次数。class Solution {publi.原创 2020-05-15 16:04:57 · 321 阅读 · 0 评论 -
每日一题:快速幂
实现 pow(x, n) ,即计算 x 的 n 次幂函数。快速幂的基本思想就是,将指数转换成二进制形式,然后计算每一位1的贡献。class Solution {public: double quickMul(double x, long long N) { double ans = 1.0; // 贡献的初始值为x double xContribute = x; // 在对N进行二进制拆分的同时计算答案 whi.原创 2020-05-12 09:52:51 · 115 阅读 · 0 评论 -
每日一题:山脉数组中查找目标值
示例1:输入:array = [1,2,3,4,5,3,1], target = 3输出:2解释:3 在数组中出现了两次,下标分别为 2 和 5,我们返回最小的下标 2。示例2:输入:array = [0,1,2,4,2,1], target = 3输出:-1解释:3 在数组中没有出现,返回 -1。二分查找因为山脉数组由一个递增序列和一个递减序列两个单调序列组成,所以先使用二...原创 2020-04-29 11:28:48 · 173 阅读 · 0 评论 -
每日一题:数组中数字出现的次数
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。示例1:输入:nums = [4,1,4,6]输出:[1,6] 或 [6,1]示例2:输入:nums = [1,2,10,4,1,4,3,3]输出:[2,10] 或 [10,2]限制:2 <= nums <= 100...原创 2020-04-28 11:17:35 · 112 阅读 · 0 评论 -
每日一题:硬币
硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)示例1:输入: n = 5输出:2解释: 有两种方式可以凑成总金额:5=55=1+1+1+1+1示例2:输入: n = 10输出:4解释: 有四种方式可以凑成总金额:10=1010=5+510=5+1+1+1+1+110...原创 2020-04-23 12:04:30 · 251 阅读 · 0 评论 -
字节跳动高频:缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。示例1:输入: [1,2,0]输出: 3示例2:输入: [3,4,-1,1]输出: 2示例3:输入: [7,8,9,11,12]输出: 1提示:算法的时间复杂度应该为O(n),并且只能用常数级别的额外空间。寂寞围绕这电视,垂死坚持,在两点半消失索引作为哈希键值易证,缺失的最小正数一定小于或等于n+1...原创 2020-04-20 21:47:36 · 237 阅读 · 0 评论 -
每日一题:岛屿数量
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。示例1:输入:11110110101100000000输出: 1示例2:输入:11000110000010000011输出: 3解释: 每座岛屿只能由水...原创 2020-04-20 11:00:16 · 330 阅读 · 0 评论 -
每日一题:统计重复个数
由 n 个连接的字符串 s 组成字符串 S,记作 S = [s,n]。例如,[“abc”,3]=“abcabcabc”。如果我们可以从 s2 中删除某些字符使其变为 s1,则称字符串 s1 可以从字符串 s2 获得。例如,根据定义,“abc” 可以从 “abdbec” 获得,但不能从 “acbbe” 获得。现在给你两个非空字符串 s1 和 s2(每个最多 100 个字符长)和两个整数 0...原创 2020-04-19 15:41:36 · 140 阅读 · 0 评论 -
LeetCode笔记:最长有效括号
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。示例1:输入: “(()”输出: 2解释: 最长有效括号子串为 “()”示例2:输入: “)()())”输出: 4解释: 最长有效括号子串为 “()()”法一:动态规划这个问题可以通过动态规划解决。定义一个dp数组,其中第i个元素表示以下标为i的字符结尾的最长有效子字符串的长度。将dp数...原创 2020-04-18 12:09:04 · 200 阅读 · 0 评论 -
二叉树的前、中、后序遍历(递归与迭代写法)
二叉树的前序遍历二叉树的前序遍历指先访问头结点,再访问左子树,再访问右子树。递归写法class Solution { vector<int> ans; void preorder(TreeNode* root) { if (root == NULL) return; ans.emplace_back(root->val); ...原创 2020-04-17 14:25:17 · 450 阅读 · 0 评论 -
每日一题:Jump Game
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个位置。示例1:输入: [2,3,1,1,4]输出: true解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。示例2:输入: [3,2,1,0,4]输出: false解释: 无论怎样,你总会到...原创 2020-04-17 11:49:38 · 162 阅读 · 0 评论 -
每日一题:矩阵
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。两个相邻元素间的距离为 1 。示例1:输入:0 0 00 1 00 0 0输出:0 0 00 1 00 0 0/*方法一:多源广度优先搜索对于矩阵中的每一个元素,如果它的值为0,那么离它最近的0就是它自己。如果它的值为1,那么我们就需要找出离它最近的0,并且返回这个距离值。可以从0的位置...原创 2020-04-15 13:27:23 · 525 阅读 · 0 评论 -
面试题:字典序的第K小数字
给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字。注意:1 ≤ k ≤ n ≤ 109。示例1:输入:n: 13 k: 2输出:10解释:字典序的排列是 [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9],所以第二小的数字是 10。号称是字节跳动最爱考的题之一,得好好学学。字典序:就是根据字符串的前缀进行排序。...原创 2020-04-14 16:36:39 · 562 阅读 · 0 评论 -
每日一题:两数之和(链表版)
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。你可以假设除了数字 0 之外,这两个数字都不会以零开头。进阶:如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。示例:输入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)输出:...原创 2020-04-14 11:34:24 · 341 阅读 · 0 评论 -
每日一题:求两线段的交点
给定两条线段(表示为起点start = {X1, Y1}和终点end = {X2, Y2}),如果它们有交点,请计算其交点,没有交点则返回空值。要求浮点型误差不超过10^-6。若有多个交点(线段重叠)则返回 X 值最小的点,X 坐标相同则返回 Y 值最小的点。示例1:输入:line1 = {0, 0}, {1, 0}line2 = {1, 1}, {0, -1}输出: {0.5, ...原创 2020-04-14 11:30:00 · 425 阅读 · 0 评论 -
每日一题:鸡蛋掉落
你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X &...原创 2020-04-11 16:35:17 · 158 阅读 · 0 评论 -
每日一题:翻转字符串里的单词
给定一个字符串,逐个翻转字符串中的每个单词。示例1:输入: “the sky is blue”输出: “blue is sky the”示例2:输入: " hello world! "输出: “world! hello”解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。示例3:输入: “a good example”输出: “exam...原创 2020-04-11 10:47:38 · 183 阅读 · 0 评论 -
每日一题:括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。示例:输入:n = 3输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”]方法一:暴力枚举枚举出括号的所有排列。为了生成所有的序列,可以使用递归的方法。长度为n的序列就是在长度为n-1的序列后面加一个“(”或“)”。class S...原创 2020-04-09 16:14:17 · 482 阅读 · 0 评论 -
每日一题:机器人的运动范围
剑指Offer上的原题地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19...原创 2020-04-08 16:58:32 · 259 阅读 · 0 评论 -
合并K个排序链表
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。示例1:输入:[1->4->5,1->3->4,2->6]输出: 1->1->2->3->4->4->5->6方法一:K阶归并/*方法1:k阶归并*/class Solution {public: ListNode* ...原创 2020-04-07 20:01:56 · 96 阅读 · 0 评论