Leetcode每日一题
文章平均质量分 50
自己刷leetcode每日一题的代码和思路
譕訫_
自学ing.....
展开
-
Leetcode--526优美的排列
emmm,原本感觉O(n!)O(n!)O(n!)的复杂度太大,会超时,就没有尝试,想了很久的dp也没啥思路,一看官方题解,O(n!)O(n!)O(n!)居然不会超时。。。在此记录一下该题,后期要加强dp和回溯的学习了,dp好难啊。。。class Solution { //回溯法 boolean vis[]; List<Integer> mask[]; int ans; public int countArrangement(int n) {转载 2021-08-16 11:06:07 · 180 阅读 · 0 评论 -
Leetcode---313.超级丑数
思路思路与丑数和丑数||中丑数||的思路完全一致,只不过原本的质数范围只是【2,3,5】,现在是一个最长为1000的数组,所以原本使用的三指针方法。直接转换为m指针方法就可以了。时间复杂度为O(nm)O(nm)O(nm),其中m为数组primes的长度。代码class Solution { public int nthSuperUglyNumber(int n, int[] primes) { //开始进行动态规划 int[] dp = new int[n+.原创 2021-08-09 10:49:08 · 96 阅读 · 0 评论 -
Leetcode---1818绝对差值和
1818绝对差值和思路拿到题首先简单分析一下:因为nums1和nums2的长度都是n,而1≤n≤1051\le n \le 10^51≤n≤105,所以最多只能使用O(nlogn)O(nlogn)O(nlogn)的算法;nums1中最多只能进行一次元素替换操作,可以不进行替换。因为求的是——进行最多一次替换后的最小绝对差值和,所以若原本的绝对差值和就是0,那就不用进行替换了;如果需要替换,又因为只能替换一次,那就需要找到可以最大程度减少绝对差值和的一次替换,然后在原本的绝对值和的基础上原创 2021-07-14 11:51:10 · 124 阅读 · 1 评论 -
Leetcode--218天际线问题
今天的困难题没啥思路,在此记录一下对官方题解的理解。题目思路利用扫描线来做本题,为了优化算法的时间复杂度,使用优先队列存储当前的最大高度。算法步骤:首先是对所有建筑的边界x坐标值进行存储和排序,得到升序列表bound_x;对bound_x中的元素i开始遍历,因为buildings中的数据是按照left的值非严格递增排列的,所以每次不用循环遍历buildings中所有的元素;将left小于i的buildings[indx]对应的right和height存入优先队列p中;如果i大于等于优先原创 2021-07-13 12:23:21 · 118 阅读 · 1 评论 -
Leetcode---1418点菜展示表
这一题主要考察的就是数据的存储和处理,思路其实很简单思路思路很简单,需要注意的是:第一行要手动添加“Table”列名;桌子编号是升序排列;菜名是按字母序排列;其他的就按部就班的处理即可。不知道具体是什么原因,在进行排序时,我最先使用的是优先队列进行排序(用的比较少,所以想多用一用),但是都没能达到想要的结果,白给两次。。。后面换成Collections.sort()对列表进行排序才AC;算法步骤:使用Set存储菜名,使用Map存储每桌的点菜信息;每当遇到一个菜名,判断其是否在原创 2021-07-06 14:14:07 · 102 阅读 · 0 评论 -
Leetcode---LCP 07传递信息
思路使用DFS进行处理,因为在计算过程中可能会设计多个元素重复出现,使用Map存储不合适,使用另一个队列存储对应元素的对应step。因为最终求的是step等于k的方案数量,所以当出现第一个step大于k的元素时证明后续的元素已经不存在可行的方案了,所以直接可以break。时间复杂度为O(nk)O(n^k)O(nk)代码class Solution { public int numWays(int n, int[][] relation, int k) { int ans .原创 2021-07-01 11:24:02 · 122 阅读 · 0 评论 -
Leetcode--168.Excel表列名称
思路虽然是简单题,但还是挖了坑。。其余的都很容易理解,需要注意的是类似52、701这种情况。遇到这个题第一反应就是转化为26进制进行解题,但是在实际操作过程中发现,如果按照处理2进制的方法处理,遇到52、701时,对应的答案为B @(2 0)、A@Y(1 0 25),与正确答案AZ、ZY根本对应不上。造成这种问题的根本原因是对于26进制而言,每一位的表示范围是0-25,而A-Z对应的是1-26,所以需要将A-Z的映射关系进行改变,同时因为改变映射关系之后A-0,…Z-25,所以每一次的值也要减1。.原创 2021-06-29 10:58:57 · 75 阅读 · 0 评论 -
Leetcode--773滑动谜题
芜湖,今天的困难题也做出来了!!!和昨天一样,缓存所有的可能,然后直接查询即可,查得到返回对应的值,查不到返回-1;思路因为从状态2到状态1需要的滑动次数和从状态1到状态2需要的滑动次数相等,所以从123450开始滑动,记录所有的可能性和对应的次数,然后每次查询即可。为了方便计算,将二维数组转化为字符串进行操作。试验得出共有359种可能,最大的移动次数为21次。算法步骤:首先把数组转为字符串;因为只有0的索引在0-2才可以向下移动、在3-5才可以向上、在不为0和3才可以向左、在不为2和5才原创 2021-06-26 18:55:38 · 69 阅读 · 0 评论 -
Leetcode---752打开转盘锁
芜湖~又是独立做出一次AC中等题一天,虽然时间开销和空间开销大了一些????思路利用Map模拟树的生成过程,key存储结点值,value存储结点的深度,问题最终转化为求target所位于的深度。如图,根节点为0000,在不考虑deadends的影响时,除了叶子节点外,每个节点最多有8个子节点。当考虑deadends的影响时,deadends中的元素不能存在于树中,且树中也不能含有其子树。代码class Solution { public int openLock(String[]原创 2021-06-25 11:45:31 · 82 阅读 · 1 评论 -
Leetcode---149直线上最多的点数
思路因为最多有300个点,所以最多可能存在299+298+…+1=44850条边,所以可以使用暴力方法对这些情况依次进行遍历,根据提示,可以利用HashMap保存之前的计算结果减少部分计算量。如何判断多个点是否在一个直线上?对于同一个点,如果存在n个点与其构成直线的斜率相同,则这n+1个点存在于同一条直线上;然后根据这个就可以得到代码了。最开始使用的是直接计算斜率,结果因为计算精度的问题卡在了倒数第二个测试用例上。。。只好改成了辗转相除法gcb。时间复杂度为O(n2∗log(m))O(n^2*l..原创 2021-06-24 13:59:18 · 98 阅读 · 2 评论 -
Leetcode--剑指offer 15二进制中1的个数
简单题,直接重拳出击。这个题主要涉及到java的位操作,这里记录一下三种方法。代码–内置函数使用java内置的函数进行计算,java.lang.Integer.bitCount(int n)可以返回整形变量二进制形式中1的个数。public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { return Integer.bitCo原创 2021-06-23 10:26:06 · 91 阅读 · 0 评论 -
Leetcode--剑指offer 38字符串的排列
今天的每日一题和昨天做的电话号码的字母组合都是使用回溯方法,通过做题,我也学习到了回溯法的基本模板套路,在此记录一下。剑指offer 38字符串的排列思路思路简单,就是排列组合,可以使用回溯法来模拟这个过程。需要注意的一点就是字符串s中可能存在重复的字符,因此对于类似"abcc"的输入,按照正常的排列组合会出现重复项,如abc1c2abc_1c_2abc1c2和abc2c1abc_2c_1abc2c1,但是两个看起来都是abccabccabcc,所以使用set存储来避免这种重复,其余的按照原创 2021-06-22 10:29:05 · 79 阅读 · 0 评论 -
Leetcode---17电话号码的字母组合
思路–暴力因为digit最长为4,所以直接进行模拟,可以得出最终的答案,时间和空间开销比较大,并且会有很多的代码–暴力class Solution { String[][] letter = new String[][]{ {"a","b","c"}, {"d","e","f"}, {"g","h","i"}, {"j","k","l"}, {"m","n","o"}, .原创 2021-06-21 10:29:52 · 65 阅读 · 0 评论 -
Leetcode---1239串联字符串的最大长度
今天的中等题,因为数据量不大,直接暴力。。暴力yyds1239 串联字符串的最大长度思路因为字符串s中的字符是不能重复的,所以在选择时要避免出现重复字符,所以首先对arr中的单个String进行去重——把单个String中含有重复字符的先去除掉;然后在选择放到s中的String时,避免与已存在s中的字符发生重复。因为数据量不大,所以直接暴力求解:对arr中的每个String中的元素进行遍历,如果发现其中存在重复元素,之直接弃用;否则存入新的List中备用;(为了判断单个String中是否存在原创 2021-06-19 16:14:59 · 75 阅读 · 0 评论 -
Leetcode---483最小好进制
今天又是困难题,不会做,在看官方题解和其他人的题解终于明白了,记录一下。483最小好进制思路做题前的分析:因为n的范围为 3≤n≤10183\le n \le 10^{18}3≤n≤1018,上限远远超过1e7,所以不能使用暴力方法;因为java中的long的范围最大为 263−12^{63}-1263−1 大于 101810^{18}1018 ,所以可以使用long类型的变量转存n,方便进行计算;由题意和示例可以分析得出,最终的答案k的值范围在2≤k≤(n−1)2\le k \le原创 2021-06-18 15:33:14 · 90 阅读 · 1 评论 -
leetcode---65有效数字
距离上一次独立做出困难题已经好长时间了。。。今天虽然做出来了,但是是通过不断试错做出来的,自己考虑问题还是不够全面,以后还要加油,代码比较复杂,但思路很简单,有时间再优化以下吧。65有效数字不断的试错,不断的发现自己没考虑全面的地方。。。思路只需要注意以下各点,即可模拟检测过程:字符串内只能存在以下字符+、-、.、数字0-9、e、E;字符.、e或E最多只能出现一次(最开始我只分析出.最多只能出现一次,没理解题意e或E也是最多只能出现一次,白给一次。。);字符串中至少包含一个数字0-9;原创 2021-06-17 22:08:59 · 99 阅读 · 1 评论 -
Leecode---279完全平方数+1449数位成本和为目标值的最大数字
279完全平方数思路这个题和零钱兑换问题很相似,都是完全背包问题(一个物品可以使用多次),所以可以在经过少量处理后,直接借用其代码。首先计算出完全平方数的范围,并将其存入一个数组nums内,形成我们熟悉的背包问题的形式;很显然,对于输入n,其范围内完全平方数最大为(n)2({\sqrt{n}})^2(n)2,因为n的范围在1-10000,故最多有100个互相独立的完全平方数;状态转移方程:dp[i]=Math.min(dp[i], dp[i-nums[j]]+1);代码class Sol原创 2021-06-12 18:03:14 · 154 阅读 · 0 评论 -
Leetcode--518零钱兑换||
做今天每日一题之前,先回顾以下零钱兑换1的解答:代码–322零钱兑换class Solution { public int coinChange(int[] coins, int amount) { int [] dp = new int[amount+1]; Arrays.fill(dp, amount+1); dp[0]=0; for (int i=1;i<=amount;i++){ for (int j=0原创 2021-06-10 12:49:25 · 118 阅读 · 2 评论 -
Leetcode---879 盈利计划+1049. 最后一块石头的重量 II+474. 一和零 动态规划背包问题专场
public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) { int len = group.length; int mod = (int)1e9+7; //三维分别表示可供选择的工作数量(可选择,也就是对于某些工作可做可不做)、投入多少人(不一定全部用光)、至少可以实现多少利润(大于等于0) int[] [] [] dp = new int[l原创 2021-06-09 19:02:25 · 112 阅读 · 0 评论 -
Leetcode---494目标和
emmm,做题的背包问题,没做出来,今天还是背包问题,dp还是不会,但是数据量比较小,可以直接暴力求解。思路因为数组长度最大为20,数组内的每个元素只有两种可能——加或减,所以最大只有2202^{20}220次,大约100万+,远远小于1e7,因此可以直接暴力求解。因为数组内的每个元素只能进行加或减的操作,所以直接遍历所有可能情况就能求解。代码class Solution { int count; public int findTargetSumWays(int[] nums,原创 2021-06-07 11:12:12 · 43 阅读 · 0 评论 -
Leetcode--160相交链表
思路–暴力–时间复杂度O(nm),原因是嵌套循环直接两个循环,找到第一个相同的位置,就返回。注意,要使用equals而不是==,因为i和j的类型是ListNode,此时的==比较的是内存地址,而equals比较的是内容。代码public ListNode getIntersectionNode(ListNode headA, ListNode headB) { for (ListNode i = headA;i!=null;i = i.next) for (.原创 2021-06-04 12:01:46 · 87 阅读 · 1 评论 -
Leetcode---523找出连续的子数组和
emmm,又是翻车的一天,以后做题要好好分析复杂度了,今天又超时了。。。思路前缀和好理解,之前已经说过很多次了,这次的重点是同余定理假设存在满足条件的区间[i,j],即(s[j]-s[i]) %k==0,也就意味着(s[j]-s[i-1]) \ k=n(n是整数),设a=s[j]%k,x=s[j] \ k,b=s[i-1]%k,y=s[i-1]\k,则s[j] = x*k + a,s[i-1] = y*k + b,如果此时a=b,意味着s[j]-s[i-1]= x*k + a-(y*k + b)=原创 2021-06-02 11:54:11 · 107 阅读 · 0 评论 -
Leetcode---1744你能在你最喜欢的那天吃到你最喜欢的糖果吗?
今天的每日一题理解起来比较简单,就是不知道为什么第一次提交的代码卡在了倒数第二个测试用例上。。。经过一番改进,最终还是AC了。思路根据题意可以发现,我们最终的目的是找到两个值——earlierDay和lastDay,如果对应的favoriteDay∈[earlierDay,lastDay]favoriteDay \in [earlierDay,lastDay]favoriteDay∈[earlierDay,lastDay],则是true,否则是false。问题就转换成如何找到这两个值了。对于l原创 2021-06-01 14:26:55 · 78 阅读 · 0 评论 -
Leetcode----304二维区域和检索+1074元素和为目标值的子矩阵数量
做今天每日一题之前,先做一下下面的题熟悉/回顾以下前缀和的相关知识。304二维区域和检索思路其余的详见代码,这里介绍以下怎么计算前缀和、怎么计算子区域的和。因为前缀和的计算就是计算索引(0,0)到当前索引位置(i,j)所框出的区域的元素和,所以前缀和的计算可以通过m[i][j] = m[i-1][j]+m[i][j-1]-m[i-1][j-1] + matrix[i-1][j-1];如要计算绿色框内的元素和,可以通过黄色+灰色区域和绿色+灰色区域,还有红色区域的值得到,因为黄色+灰色区域和绿色+原创 2021-05-29 17:19:48 · 55 阅读 · 0 评论 -
Leetcode--477汉明距离总和
每日一题,一看和昨天的类似,直接暴力,其中还做了一定的剪枝,果不其然超时,还要想想更简单的方法。超时代码class Solution { public int totalHammingDistance(int[] nums) { int res = 0; Map<Integer, Integer> map = new LinkedHashMap<>(); int len = nums.length;原创 2021-05-28 09:43:50 · 83 阅读 · 0 评论 -
Leetcode--461汉明距离
简单题!!!我又可以了 首先是自己写的解法,可以达到时间100% 空间69%左右,后面两个是学习的大佬的解法。之前的每日一题用过一次树状数组,也简单了解了以下lowbit,但还是想不起来用,可能这就是我和大佬之间存在的差距吧。思路–逐位比较因为题目说最大不超过2的31次方,所以i的上限为30,每次使用(x>>i)&1来获取x的当前位置是否为1,逐位比较直接得到大答案。时间复杂度O(C),C=31因为要比较31次。空间复杂度O(1)。代码1–自己写的,逐位比较 时间100% 内原创 2021-05-27 10:48:20 · 71 阅读 · 0 评论 -
Leetcode----1190反转每对括号间的子串
今天的是关于栈的中等题,直接重拳出击,一次ac,后来发现原来使用stack做过了,这次用的Deque做的,更方便操作和理解。思路题目的逻辑很简单,就是反转括号里面的内容,需要注意的是,要从最里面的括号开始反转,否则理解起来比较困难,也比较难实现。算法步骤:把String中的元素依次入栈,(也入栈;当遇到)时,证明已经到了最内部的括号内(注意,最内部的括号不止一个,可能是a(b(cd)e(fg)hi)jk这种类型,不过不影响操作),然后开始deque出栈、依次入栈到辅助栈中,直至遇到栈内的第一个原创 2021-05-26 11:14:58 · 83 阅读 · 0 评论 -
Leetcode--1787使所有区间的异或结果为零
连续几天都是困难,天天cv,都快自闭了,今天贴一个大佬的代码,因为他没有加注释,也怎么写思路,所以理解起来有些困难,这里按照自己的理解给代码加了注释,希望对大家有帮助。思路通过观察几个示例可以发现,最终的结果是k个元素一个周期进行循环,把该题可以理解为二维数组进行分析和解题。因为nums数组的长度不一定是k的整数倍,所以要对这种情况特别处理(只需要在每列的高度上注意即可)。因为我们最终的目的是找到最小的改变次数,而方式是把每一行(或者是当最后一行“不满”时,除最后一行外的所有行)的元素变成相同的原创 2021-05-25 11:39:31 · 160 阅读 · 0 评论 -
Leetcode--692前k个高频单词
没想到今天写的居然和官方题解的方法1很类似 哈哈,一会更新大佬们实验优先队列的方法,学习一下,之前用过优先队列,但是不熟练。。思路根据题目要求,我们首先统计词频,首先想到的就是map,因为其结构为<Object, Object>,可以利用这一点完成词频的统计,因此得到Map<String, Integer> map = new HashMap<>();;在获取词频时,一个非常有用的方法为map.getOrDefault(key, defaultValue),可原创 2021-05-20 10:39:34 · 62 阅读 · 0 评论 -
Leetcode---1738找出第k大的异或坐标值
今天的比较简单,先获取异或后的数组,然后找到对应的第k大的数即可。双84.85%有点神奇 哈哈哈代码class Solution { public int kthLargestValue(int[][] matrix, int k) { int col = matrix[0].length; int row = matrix.length;// System.out.println(w+" "+h); int [][] res原创 2021-05-19 13:30:34 · 62 阅读 · 0 评论 -
Leetcode--1442形成两个异或相等数组的三元组
这个题利用到前段时间学到的新知识——前缀异或和,即int [] s = new int[n+1];for(int i=1;i<=n;i++){ s[i] = s[i-1] ^ arr[i-1];}根据异或运算的性质——相等的数进行异或,结果为0,所以通过上面的代码我们可以得到数组内前n个元素的异或和(s[i]存储的是数组内前i个元素的异或和)。从题意中可以得出,我们所要求的是满足条件的三元组的数量,其中三元组的范围为0 <= i < j <= k < ar原创 2021-05-19 12:09:28 · 203 阅读 · 0 评论 -
Leetcode---421.数组中两个数的最大异或值
emmm,今天的题虽然明知道不能暴力,但还是使用暴力解法试了一下,虽然已经做了一定的剪枝,但还是超时了,还是好好学习一下字典树吧。新知识–字典树字典树具体的讲解可以在知乎等找到。这里不做详细叙述,主要讲一下代码的实现。解题思路根据题意,很容易可以得到该条信息——最后进行异或的两个数字中一定包含且只包含一个拥有数组元素中二进制位数最高的元素(数组元素中二进制位数最高的元素不一定唯一)。因为字典树的性质也是从最高位开始,所以使用字典树辅助进行计算。代码中有几个关键点:数组内元素依次存入字典树;原创 2021-05-16 17:27:56 · 108 阅读 · 0 评论 -
Leetcode--13罗马数字转整数
今天的每日一题和昨天的很类似,只不过反过来了,先贴一个自己写的代码,再贴两个大佬的代码学习一下。自己的代码就是简单的模拟,只不过自己写的比较复杂,和第二个大佬的代码思路是一样的。class Solution { public int romanToInt(String s) { int[] n = new int[]{1,4,5,9,10,40,50,90,100,400,500,900,1000}; String[] roman = new String[]原创 2021-05-15 13:46:40 · 65 阅读 · 0 评论 -
Leetcode--12整数转罗马数字
今天的每日一题还是很简单的,分情况分析就好,只不过我写的比较繁琐,一会看下大佬们的题解学习一下更好的方法,再来更新。思路因为是int数字转化为罗马字符,所以先对几种特殊情况进行处理:I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。把上述的情况存在roman2数组内,方便取用。然后把常规的罗马字符放在r原创 2021-05-14 13:55:21 · 69 阅读 · 0 评论 -
Leetcode--1310子数组异或查询
今天的每日一题比较简单,就是基本的异或操作,先放上自己的代码,开销有点大。一会更新下大佬们的代码,学习下新思路。思路使用暴力解法,根据queries二维数组内每个子数组所指定的区间,逐个得到对应的异或结果,然后存储到结果数组内。时间开销比较大,并且很容易超时。代码class Solution { public static int[] xorQueries(int[] arr, int[][] queries) { int len = queries.length;原创 2021-05-12 16:06:08 · 80 阅读 · 2 评论 -
Leetcode--1482制作m束花所需的最少天数
补一下前两天关于二分查找的每日一题,前几次做的总会出一些小错误,这次总算搞明白了。思路这个题和前几天每日一题在D天内运算包裹的能力类似,都是根据数组内连续元素的和进行解题。几个比较关键的点:1.关于二分查找边界的取值: 从题目给定的边界条件可知,最终的结果的范围在【1,1e9】之间或者-1,若是遍历数组bloomDay来获取数组的最大、最小值也可以,但是因为增加了循环,所以对于一些长度较大的数组blo原创 2021-05-11 13:46:52 · 60 阅读 · 0 评论 -
Leetcode--1734--解码异或后的排列
思路容易发现因为encoded[i]=p[i]⊕p[i+1]encoded[i]=p[i] \oplus p[i+1]encoded[i]=p[i]⊕p[i+1],所以使用下标为偶数和0的encoded即可得到p[0]⊕p[1]⊕...⊕p[n−1]p[0]\oplus p[1]\oplus ...\oplus p[n-1]p[0]⊕p[1]⊕...⊕p[n−1],其中没有p[n]。但是p数组是前n个正整数的排列,异或运算可以交换位置而值不改变,所以可以得到p[0]⊕p[1]⊕...⊕p[n]p[0.原创 2021-05-11 12:46:35 · 63 阅读 · 0 评论 -
Leetcode--872叶子相似的树
使用中序遍历,每当遍历的节点不存在子节点,则为叶子节点,利用list存储起来,最后对两个list的内容进行比较即可。class Solution { public boolean leafSimilar(TreeNode root1, TreeNode root2) { List<Integer> l1 = new ArrayList<>(); List<Integer> l2 = new ArrayList<>();原创 2021-05-10 13:07:20 · 47 阅读 · 0 评论 -
Leetcode---1723完成所有工作的最短时间
今天的每日一题比较难,看了很久没有什么思路,所以看了官方题解,好在看懂第一个方法了,下面放上代码和自己的理解。下午考完试再来研究dp的解法和其他大佬提出的解法。思路根据题目要求,是要在完成全部工作的前提下,找到工人最大工作时间的最小值,所以一个最先想到的方法就是不断枚举和尝试,把不同的工作分给不同的工人,然后在可以完成全部工作的方案中,找到每个方案最大值中的最小值(也就是把每个可以完成全部工作的方案中,工人最大工作时长拿出来进行比较,找到这些最大值中的最小值),此时,我们的目标变成了两个:找到所有原创 2021-05-08 13:41:32 · 262 阅读 · 0 评论 -
Leetcode---1486数组异或操作
今天的每天一题还是非常简单的,需要注意的一点是num[i]的值是start+2*i,start的值是不会变的(最开始没注意,让start的值也随着改变了。。。,还好只是测试时这样。。),代码如下:class Solution { public int xorOperation(int n, int start) { int res = start; for(int i=1;i<n;i++) res ^= (start + 2 * i..原创 2021-05-07 18:14:06 · 53 阅读 · 0 评论