自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(136)
  • 收藏
  • 关注

原创 每日一练:贪心算法-将数组和减半的最少操作次数

nums 的和减小了 31 - 14.5 = 16.5 ,减小的部分超过了初始数组和的一半, 16.5 >= 31/2 = 15.5。减少一半的最少次数,所以减少到小于sum的一半也可以,很容易想到每次都让最大值减少一半(每次减少最多的数值),这样的次数应该是最小的。这是因为如果减去最大数字的一半都不能至少减去一半的sum,那么减去其他数字的一半一定不能至少减去一半的sum;如果减去最大数字的一半都能至少减去一半的sum,那么减去其他数字的一半只是可能至少减去一半的sum;

2024-10-18 23:14:45 68

原创 每日一练:贪心-柠檬水找零

(2)支付10块,只能找5块钱,如果找不开就返回false,找得开就少一张5块,多一张10块;所以当顾客支付20块时,优先使用一张5块和一张10块,尽可能多留5块才能应对更多的情况。但是一张10块不能完全替代两张5块,需要找5块时两张5块可以拿一张出来。一张10块可以由两张5块代替,当需要找5块时,10块就派不上用场;对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。顾客排队购买你的产品,(按账单。

2024-10-18 22:06:41 121

原创 每日一练:不同的二叉搜索树

dp[i]+=dp[j-1]*dp[i-j](dp[i]存放当n==i时的二叉搜索树的种数)。返回满足题意的二叉搜索树的种数。个节点组成且节点值从。

2024-10-17 22:09:26 138

原创 每日一练:组合总和Ⅳ

这种方法的本质就是得到一个数i(i<=target)的排列次数,在它后面加上一个数,使新的i更接近target。这个题似乎是一个完全背包问题,但是它求的是排列次数,而不是组合次数,完全背包只能解决组合问题。数组中的数字可以在一次排列中出现任意次,但是顺序不同的序列被视作不同的组合。对于这种问题,需要先根据题目要求找到子问题,然后根据子问题写出状态转移方程。题目数据保证答案符合 32 位整数范围。请注意,顺序不同的序列被视作不同的组合。

2024-10-17 22:00:29 257

原创 每日一练:盈利计划

这个题需要同时维护员工数量n和盈利profit,所以创建一个三维dp表,dp[z][i][j]存放从第0到i个计划中选择,需要的人数不超过i,盈利不小于j的所有选择的数量。有 7 种可能的计划:(0),(1),(2),(0,1),(0,2),(1,2),以及 (0,1,2)。至少产生 3 的利润,该集团可以完成工作 0 和工作 1 ,或仅完成工作 1。至少产生 5 的利润,只要完成其中一种工作就行,所以该集团可以完成任何工作。名员工,他们可以完成各种各样的工作创造利润。总的来说,有两种计划。

2024-10-17 18:23:42 201

原创 每日一练:一和零

首先将strs转化成熟知的二维数组nums,nums的每个元素空间只有2,一一存放strs中的'0'和'1'的数量,nums[i][0]存放strs[i]中'0'的数量,nums[i][1]存放strs[i]中'1'的数量。其他满足题意但较小的子集包括 {"0001","1"} 和 {"10","1","0"}。最多有 5 个 0 和 3 个 1 的最大子集是 {"10","0001","1","0"} ,因此答案是 4。最大的子集是 {"0", "1"} ,所以答案是 2。状态转移方程的推导就和。

2024-10-16 20:47:43 231

原创 每日一练:零钱兑换Ⅱ

将dp[i][j-coins[i]]按上面展开,它的值就等于上述选择coins[i]的情况的总和。请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回。题目数据保证结果符合 32 位带符号整数。只用面额 2 的硬币不能凑成总金额 3。表示不同面额的硬币,另给一个整数。假设每一种面额的硬币有无限个。

2024-10-16 18:47:23 312

原创 每日一练:【模板】完全背包

问题(2)的状态转移方程的推导与(1)十分类似,可以自己试试看,但是记得规定一个值(-1)代表不存在这种情况。实际上,不选nums[i]的情况也可以归到选择nums[i]的情况中,只是选择零个nums[i]。对于问题(1),dp[i][j]保存nums的区间[0,i]的物品,重量不超过 j 的最大价值。可以装5号物品2个,达到最大价值298*2=596,若要求恰好装满,只能装1个1号物品,价值为189.现在有n种物品,每种物品有任意多个,第i种物品的体积为vivi​ ,价值为wiwi​。

2024-10-15 23:13:34 372

原创 每日一练:最后一块石头的重量 II

填表完成后从右到左遍历dp[n],第一个true的 j 就是最接近sum/2的a,sum-2*j就是stones丢失的总质量,就是也就是石头的最小质量,如果没有true说明此时已经没有石头了,返回0。设a为(1)的总质量,b为(2)之前的总质量,那么(2)现在的总质量就是b-a,所有石头的总质量sum=a+b。题目说如果不剩下石头就返回0,说明x的值可以是0,所以问题转化成了从数组中选几个元素,它们的和最接近但是不超过sum/2的情况就是最后的石头的最小质量。,然后将它们一起粉碎。(2)不完全粉碎的石头。

2024-10-15 21:56:43 353

原创 每日一练:目标和

创建一个二维dp表,dp[i][j]保存从nums的区间[0,i]中选择一些元素,之和等于j总共有多少种选法。(2)选择nums[i],dp[i-1][j-nums[i]],判断j-nums[i]的合法性。使用虚拟位,当i==0时,除了j==0,选不出元素能等于j,所以dp[0][0]初始化为1;即dp[i][j] = dp[i-1][j]+dp[i-1][j-nums[i]];设nums的某个子序列的和为a,其他元素构成另一个子序列,和为b。(1)不选择nums[i],dp[i-1][j];

2024-10-15 20:54:29 406

原创 每日一练:分割等和子集

其次,如果只使用一个数组,那么它本来的位置就以及等于它的上面个位置了(相当于dp[i][j]天生等于dp[i-1][j]),此时只需要判断 j>=nums[i-1],然后dp[i][j] = dp[i][j] || dp[i][j-nums[i-1]],所以第二层循环的判断条件可以改成 j>=nums[i-1]。又因为使用了一个滚动数组,所以实际上是dp[j] = dp[j] || dp[j-nums[i-1]]。用sum保存nums的和,如果nums是奇数,则不可能得到相等的子集,直接返回false;

2024-10-14 22:34:28 416

原创 每日一练:【模板】01背包

(2)包含arr[i]:dp[i][j-arr[i].first]+arr[i].second;(2)包含arr[i]:dp[i][j-arr[i].first]+arr[i].second;创建一个二维dp表,dp[i][j]存储arr的区间[0,i],总重量不超过 j 的最大价值。创建一个二维dp表,dp[i][j]存储arr的区间[0,i],总重量等于 j 的最大价值。(1)不包含arr[i]:dp[i-1][j];(1)不包含arr[i]:dp[i-1][j];

2024-10-14 19:52:31 889

原创 每日一练:最长重复子数组

dp[i][j]存储以n1[i]和n2[j]为结尾的两个字符串的最大公共子数组长度,若n1[i]==n2[j],dp[i][j]==dp[i-1][j-1]+1。长度最长的公共子数组是 [3,2,1]。、长度最长的子数组的长度。

2024-10-12 17:20:22 99

原创 每日一练:两个字符串的最小ASCLL删除和

在 "leet" 中删除 "e" 将 101[e] 加入总和。如果改为将两个字符串转换为 "lee" 或 "eet",我们会得到 433 或 417 的结果,比答案更大。结束时,两个字符串都等于 "let",结果即为 100+101+101+101 = 403。在 "sea" 中删除 "s" 并将 "s" 的值(115)加入总和。在 "delete" 中删除 "dee" 字符串变成 "let",在 "eat" 中删除 "t" 并将 116 加入总和。使两个字符串相等所需删除字符的。

2024-10-12 17:07:13 269

原创 每日一练:交错字符串

如果s2[j]==s3[i+j] && s1[i]==s3[i+j],dp[i][j] = dp[i-1][j] || dp[i][j-1];创建一个二维dp表,其中dp[i][j]保存s1的区间[0,i]和s2的区间[0,j]能不能交错成s3的区间[0,i+j];如果s1[i]==s3[i+j],那么dp[i-1][j]为true,dp[i][j]就为true;如果s2[j]==s3[i+j],那么dp[i][j-1]为true,dp[i][j]就为true;

2024-10-12 16:23:16 409

原创 每日一练:通配符匹配

如果p有前缀*,例如:**a**,a之前的*和**能匹配所有字符串,所以要对dp[1][0]、dp[2][0]置true保证后续填表正确。使用虚拟位,dp[0][0]表示p、s都取空区间,即空串,它们必然可以匹配,初始化为true;' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。判定匹配成功的充要条件是:字符模式必须能够。"a" 无法匹配 "aa" 整个字符串。输入字符串(而不是部分匹配)。'*' 可以匹配任意字符串。) ,请你实现一个支持。给你一个输入字符串 () 和一个字符模式 (

2024-10-12 08:55:56 319

原创 每日一练:不同的子序列

dp[i][j]存放s的区间[0,i]的子序列包含t的区间[0,j]的个数。是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。题目数据保证答案符合 32 位带符号整数范围。如下图所示, 有 3 种可以从 s 中得到。如下图所示, 有 5 种可以从 s 中得到。

2024-10-11 08:17:25 244

原创 每日一练:最长公共子序列

t2[j],则此时的最长公共子序列一定不会同时以t1[i]、t2[j]为结尾,取dp[i][j-1]、dp[i][j-1]的最大值即可,即:dp[i][j] = max(dp[i-1][j],dp[i][j-1]);若t1[i] == t2[j],则此时的最长公共子序列一定以t1[i]和t2[j]为结尾,用前一个区间的长度+1即可,即:dp[i][j] = dp[i-1][j-1]+1;创建一个二维dp表,dp[i][j]存放数组1的[0,i]区间、数组2的[0,j]区间的最长公共子序列;

2024-10-10 17:41:10 307

原创 每日一练:让字符串成为回文串的最少插入次数

如果i > j+1 && s[i]==s[j],中间相隔了字符,因为一个回文串两端加上相同的字符,那它还是一个回文串,所以它只需要中间区间的插入次数即可,没有额外增加次数,即dp[i-1][j+1];=s [j],找到区间[j,i-1]、[j+1,i]的最少次数,然后+1表示在最少次数的区间加上另一边(i或者j)的相同字符,它也能构成回文。如果i == j+1 && s[i]==s[j],两个相同字符,已经是回文,次数是0;如果i == j && s[i]==s[j],只有一个字符,已经是回文,次数是0;

2024-10-10 16:15:49 394

原创 每日一练:最长回文子序列

如果i > j+1 && s[i]==s[j],中间相隔了字符,因为一个回文串两端加上相同的字符,那它还是一个回文串,所以长度为中间的最长回文串+2,即dp[i-1][j+1]+2;这个题要得到字符串s的最长回文子序列,那么我们就可用创建一个二维dp表,dp[i][j]存放区间[j,i]内的最长回文子序列的长度。如果i == j+1 && s[i]==s[j],两个相同字符,长度为2;如果i == j && s[i]==s[j],只有一个字符,长度为1;,找出其中最长的回文子序列,并返回该序列的长度。

2024-10-10 15:55:40 256

原创 每日一练:分割回文串Ⅱ

这个题需要使用两个dp表,dp[i][j]存储以s[i]为结尾、s[j]为开头的字符串是不是回文;f[i]存储以s[0]开始、s[i]结尾的字符串全部分割成回文的最少分割次数。(2)[0,i]不是回文,遍历j = [1,i],如果dp[i][j]==true,则f[i]=min(f[i],f[i-1]+1)。(1)[0,i]是回文,f[i] = 0;分割成 ["aa","b"] 这样两个回文子串。分割成一些子串,使每个子串都是回文串。只需一次分割就可将 s。

2024-10-09 21:26:25 313

原创 每日一练:分割回文串Ⅳ

填完表后,遍历dp表,只要某个dp[i][j]符合:dp[i][j] && dp[n-1][i+1] && dp[j-1][0],那么就返回true,遍历完之后还没有返回true,说明它不能分割成三个回文子串,就返回false。只要s[j]到s[i]是回文串,并且s[0]到s[j-1]、s[i+1]到s[n-1]也是回文串,那它就可以分割成三个回文串。这个题也需要创建一个二维dp表,dp[i][j]存放以s[j]为开头,以s[i]为结尾的子串是不是回文串,填表方法与。回文子字符串,那么返回。

2024-10-09 19:30:00 334

原创 每日一练:最长回文子串

"aba" 同样是符合题意的答案。中最长的 回文子串。

2024-10-09 18:52:50 137

原创 每日一练:最长回文串

实际上只要某个字符有偶数个,那么它一定可以加入回文串中(对称),如果有奇数个,多的一个字符如果居于回文串正中间就可以加入回文串中,否则只能加偶数个某个字符。使用一个hash表,字符的ascll作为键,数量作为值,把s中的字符添加进哈希表后遍历哈希表;然后让字符数量/2,舍去余数就可用让奇数、偶数数量的字符都只加偶数的数量到回文串中。遍历时,如果首先遇到奇数的某个字符,ret+1,之后不再+1;我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。可以构造的最长回文串是"a",它的长度是 1。

2024-10-09 18:47:23 177

原创 每日一练:回文子串

(3)并且j < i-1 && dp[i-1][j+1],它们中间有字符,且中间的子串也是回文,则一定是回文。= s[i],则必不会是回文,dp[i][j] = false;具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。6个回文子串: "a", "a", "a", "aa", "aa", "aaa"(2)并且j == i-1,两个相同字母也一定是回文;(1)并且i==j,只有一个字母一定是回文;三个回文子串: "a", "b", "c"

2024-10-09 11:19:29 221

原创 每日一练:等差数列划分Ⅱ

先找是否存在元素的值等于nums[j]-(nums[i]-nums[j]),如果有,就找以nums[j]-(nums[i]-nums[j])、nums[j]结尾的等差数量的数量,dp[i][j]就加上这个数量+1;创建一个二维dp表,dp[i][j]保存以nums[j]、nums[i]为结尾的等差数列的数量;数组中的子序列是从数组中删除一些元素(也可能不删除)得到的一个序列。,并且任意两个相邻元素之差相同,则称该序列为等差序列。注意:因为涉及int类型的计算,且。数组中的任意子序列都是等差子序列。

2024-10-08 21:38:00 305

原创 每日一练:最长等差数列

这个题需要创建一个二维dp表,因为 nums[i] 可能与它之前的任何数字构成等差数列,所以用dp[i][j]保存以nums[j]、nums[i]为结尾的最长等差数列的长度;因为nums中可能有重复元素,所以哈希表的值必须是一个数组,存储这个键的所有下标;除此之外,还需要一个哈希表存放nums中的值的下标,否则直接遍历dp表时会超时;找到符合条件的倒数第三个元素后,还需要这个元素的下标小于倒数第二个元素才行。因为nums的长度最小是3,所以最短的等差数列的长度肯定是2;整个数组是公差为 3 的等差数列。

2024-10-08 20:53:53 232

原创 每日一练:最长的斐波那契子序列的长度

将每个元素预设为子序列的第一个元素,它之后的每个元素预设为子序列的第二个元素,只要哈希表中能找到:arr[i]+arr[j],就继续找下去,得到这个子序列的长度后,如果大于之前的长度,更新返回值。: 最长的斐波那契式子序列有 [1,11,12]、[3,11,14] 以及 [7,11,18]。中删掉任意数量的元素(也可以不删),而不改变其余元素的顺序。中最长的斐波那契式的子序列的长度。最长的斐波那契式子序列为 [1,2,3,5,8]。(回想一下,子序列是从原序列。满足下列条件,就说它是。

2024-10-08 20:17:02 243

原创 每日一练:最长定差子序列

既然要求最长定差子序列,那么可以创建一个dp表,dp[i]存放以arr[i]结尾的最长定差子序列的长度,对于每个dp[ i ]先遍历arr[ j ](0<=j<i)是否有arr[i]-arr[j]==difference,如果有,那么dp[i] = max(dp[i],dp[j]+1);如果都没有,那么dp[i] = 1(arr[i]本身)。其次,即使没有符合条件的,哈希表也会自动生成一个键为arr[i]-difference,值为0的键值对,此时hash[arr[i]]的值应该是1,上面的式子也符合。

2024-10-07 23:14:45 374

原创 每日一练:最长数对链

链子后端小于链子前端才能连接成同一个数对链,那么我们可以先对原数组,根据每个pairs[i]的前端进行升序排列,这样才能保证连接顺序必然是从左往右(可能跳过中间的pairs[i])。接下来就可以使用熟悉的动态规划了。你不需要用到所有的数对,你可以以任何顺序选择其中的一些数对来构造。最长的数对链是 [1,2] -> [4,5] -> [7,8]。最长的数对链是 [1,2] -> [3,4]。我们用这种形式来构造。个数对组成的数对数组。找出并返回能够形成的。

2024-10-07 22:28:00 345

原创 每日一练:最长递增子序列的个数

既然要找最长的递增子序列的个数,那么我们可以创建一个dp表: f ,存放以nums[i]为结尾的最长递增子序列的长度,然后用变量MAX记录这个长度;再创建一个dp表:g 保存以nums[i]为结尾的最长递增子序列的数量。有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。最后变量两个dp表,只要f[i] == MAX,就累加g[i]。最长递增子序列的长度是1,并且存在5个子序列的长度为1,因此输出5。给定一个未排序的整数数组。返回最长递增子序列的个数。

2024-10-07 20:46:29 142

原创 每日一练:摆动序列

所以当 nums[i]-nums[j]>0(0<= j <i) 时:f[ i ] = g[ j ]+1,g[i] = 1;其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8)。当 nums[i]-nums[j]>0时:g[ i ] = f[ j ]+1,f[i] = 1;当 nums[i]-nums[j]==0时:g[ i ]=f[ i ]=1;f[i] 保存以nums[i]结尾的,最后一个差为正数的最长子序列长度;

2024-10-07 19:57:29 266

原创 每日一练:最长递增子序列

很容易想到用一个dp表存储以 i 位置为结尾的最长子序列的长度,只要nums[i]能作为前面子序列的尾(nums[j] < nums[i]),并且这个子序列的长度不能比已经匹配的长度还要短,那就可以令:f[i] = f[j]+1;是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。最长递增子序列是 [2,3,7,101],因此长度为 4。,找到其中最长严格递增子序列的长度。

2024-10-07 19:35:03 240

原创 每日一练:环绕字符串中唯一的子字符串

字符串 s 有六个子字符串 ("z", "a", "b", "za", "ab", and "zab") 在 base 中出现。与前面构成:dp[i] = dp[i-1]+1;这个题也可以使用动态规划,创建一个dp表,其中dp[i]保存以s[i]为结尾的子串数量。与前面不构成:dp[i] = 1;字符串 s 有两个子字符串 ("a", "c") 在 base 中出现。字符串 s 的子字符串 "a" 在 base 中出现。无限环绕的字符串,所以。

2024-10-07 15:39:27 244

原创 每日一练:单词拆分

返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。因为存在dp[j-1],且j的最小值是0,所以需要一个虚拟位,将它初始化成true。返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。如果可以利用字典中出现的一个或多个单词拼接出。注意,你可以重复使用字典中的单词。

2024-10-06 20:04:52 234

原创 每日一练:最长湍流子数组

类似,nums[i] 能否与前面的数组构成湍流数组取决于nums[i]与nums[i]的大小关系,具体是大于还是小于又取决于nums[i-1]与nums[i-2]的大小关系,所以dp表需要初始化前两个位置。如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是。满足仅满足下列条件时,我们称其为。

2024-10-06 19:52:47 303

原创 每日一练:等差数列划分

创建一个dp表,存放以 i 为结尾的最长等差数列的长度,只要nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2];然后nums[i]与nums[i-1]必然构成一个长度为2的等差数列,所以f[i]赋值为2即可。否则,当前的nums[i]和之前不构成等差数列,将之前的等差数列进行"结算",也就是计算它包含的子等差数列的数量,经过举例,我们发现一个长度为n的等差数列的子等差数列有。,并且任意两个相邻元素之差相同,则称该数列为等差数列。是数组中的一个连续序列。

2024-10-06 17:41:05 442

原创 每日一练:乘积为正数的最长子数组长度

这个题需要求长度,还要求子数组的乘积是正数,我们知道正数乘负数等于负数,负数乘负数等于正数,那么我们可以用两个dp表:f、g,分别存储以 i 为结尾,乘积分别为正数、负数时的最大长度。反之第一个元素是负数,g[1]可以等于g[0]+1,但是f[1]不能等于g[0]+1,因为此时还没有正数,f[i]、g[i] 的各种乘积必然包含nums[i];乘积为正数的最长子数组是 [-1,-2] 或者 [-2,-3]。最长乘积为正数的子数组为 [1,-2,-3] ,乘积为 6。数组本身乘积就是正数,值为 24。

2024-10-06 14:35:07 377

原创 每日一练:乘积最大子数组

但是有一个问题,假如nums[i]是一个负数,而dp[i-1]是一个正数,得到的最大值也会是一个负数,之后如果又遇到负数,再乘负数它就会变成正数,但是此前dp[i]存储了nums[i],而把潜在的更大的子数组乘积丢掉了。所以还需要一个dp表存储以第 i 位尾结尾的字串的最小乘积,只要遇到负数,用最小乘积乘以负数得到的就是可能的最大的数。(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。结果不能为 2, 因为 [-2,-1] 不是子数组。子数组 [2,3] 有最大乘积 6。测试用例的答案是一个。

2024-10-06 13:54:55 290

原创 每日一练:环形子数组的最大和

"连续"子数组和:可以求连续子数组和的最小值,然后用整个数组的和sum减去这个最小值,得到的就是"连续"子数组和的最大值。的变形,除了要求连续子数组和外,还要求首位相接的"连续"子数组和。从子数组 [3] 和 [3,-2,2] 都可以得到最大和 3。从子数组 [5,5] 得到最大和 5 + 5 = 10。意味着数组的末端将会与开头相连呈环状。从子数组 [3] 得到最大和 3。中的方法一样,这里不再赘述。最多只能包含固定缓冲区。

2024-10-06 09:46:03 365

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除