贪心算法
新名字的故事
这个作者很懒,什么都没留下…
展开
-
605. 种花问题
题目描述:假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。解题思路一:动态规划,首先计算原有花团中的花,然后dp[i][0]表示当前位置i不种花到i位置可种花的最大值,dp[i][1]表示当前位置i种花到位置i为止可以种花的最大数目,代码如下:clas原创 2021-01-01 21:58:23 · 105 阅读 · 0 评论 -
435. 无重叠区间
题目描述:给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。注意:可以认为区间的终点总是大于它的起点。区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。解题思路:按照区间的左边界对集合进行排序,然后依次将每个区间压入栈中,如果当前区间的左边界小于栈顶区间的有边界,即发生了重合,需要移除区间,这个时候我们贪心的移除掉右边界更大的区间,因为这样和后面区间重合的可能性更小,代码如下:class Solution: def eraseOverlapInterv原创 2020-12-31 11:38:04 · 135 阅读 · 0 评论 -
330. 按要求补齐数组
题目描述:给定一个已排序的正整数数组 nums,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。解题思路:如果区间[1,x-1]的区间都被覆盖,如果数组中有x,那么区间[1,2x-1]也会被覆盖,如果不存在就补充x,代码如下:class Solution: def minPatches(self, nums: List[int], n: in原创 2020-12-29 13:49:51 · 74 阅读 · 0 评论 -
2020-12-11
题目描述:如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删原创 2020-12-11 11:35:04 · 70 阅读 · 0 评论 -
1665. 完成所有任务的最少初始能量
题目描述:给你一个任务数组 tasks ,其中 tasks[i] = [actuali, minimumi] :actuali 是完成第 i 个任务 需要耗费 的实际能量。minimumi 是开始第 i 个任务前需要达到的最低能量。比方说,如果任务为 [10, 12] 且你当前的能量为 11 ,那么你不能开始这个任务。如果你当前的能量为 13 ,你可以完成这个任务,且完成它后剩余能量为 3 。你可以按照 任意顺序 完成任务。请你返回完成所有任务的最少初始能量。解题思路:因为最小的能量是大于等于实际消耗的能原创 2020-11-23 11:42:51 · 332 阅读 · 0 评论 -
1605. 给定行和列的和求可行矩阵
题目描述:给你两个非负整数数组 rowSum 和 colSum ,其中 rowSum[i] 是二维矩阵中第 i 行元素的和, colSum[j] 是第 j 列元素的和。换言之你不知道矩阵里的每个元素,但是你知道每一行和每一列的和。请找到大小为 rowSum.length x colSum.length 的任意 非负整数 矩阵,且该矩阵满足 rowSum 和 colSum 的要求。请你返回任意一个满足题目要求的二维矩阵,题目保证存在 至少一个 可行矩阵。解题思路:先用零初始化要返回的矩阵,然后从左到右从上到原创 2020-11-23 10:34:46 · 272 阅读 · 0 评论 -
842. 将数组拆分成斐波那契序列
题目描述:给定一个数字字符串 S,比如 S = “123456579”,我们可以将它分成斐波那契式的序列 [123, 456, 579]。形式上,斐波那契式序列是一个非负整数列表 F,且满足:0 <= F[i] <= 2^31 - 1,(也就是说,每个整数都符合 32 位有符号整数类型);F.length >= 3;对于所有的0 <= i < F.length - 2,都有 F[i] + F[i+1] = F[i+2] 成立。另外,请注意,将字符串拆分成小块时,每个块的数字一定原创 2020-11-22 19:18:46 · 114 阅读 · 0 评论 -
1540. K 次操作转变字符串
题目描述:给你两个字符串 s 和 t ,你的目标是在 k 次操作以内把字符串 s 转变成 t 。在第 i 次操作时(1 <= i <= k),你可以选择进行如下操作:选择字符串 s 中满足 1 <= j <= s.length 且之前未被选过的任意下标 j (下标从 1 开始),并将此位置的字符切换 i 次。不进行任何操作。切换 1 次字符的意思是用字母表中该字母的下一个字母替换它(字母表环状接起来,所以 ‘z’ 切换后会变成 ‘a’)。请记住任意一个下标 j 最多只能被操作 1 次原创 2020-11-21 19:06:13 · 257 阅读 · 0 评论 -
1338. 数组大小减半
题目描述:给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。返回 至少能删除数组中的一半整数的整数集合的最小大小。解题思路:这道题思路非常简单,统计每个整数出现的次数,然后按出现次数降序对这些数进行排序,依次删除掉当前出现次数最多的数,直到已经达到原数组大小的一半即可返回,删除的过程只需要对删除的数出现的次数累积求和即可,无需真正的删除,代码如下:class Solution: def minSetSize(self, arr: List[int]) -&g原创 2020-11-21 11:29:35 · 228 阅读 · 0 评论 -
995. K 连续位的最小翻转次数
题目描述:在仅包含 0 和 1 的数组 A 中,一次 K 位翻转包括选择一个长度为 K 的(连续)子数组,同时将子数组中的每个 0 更改为 1,而每个 1 更改为 0。返回所需的 K 位翻转的次数,以便数组没有值为 0 的元素。如果不可能,返回 -1。解题思路一,因为0和1翻转只有两种情况,那么我们可以从头遍历,遇到0就翻转当前位置及以后的K个位置,这样复杂度为O(n*k),实现效率较低,代码如下:class Solution: def minKBitFlips(self, A: List[in原创 2020-11-20 11:19:44 · 111 阅读 · 0 评论 -
936. 戳印序列
题目描述:你想要用小写字母组成一个目标字符串 target。 开始的时候,序列由 target.length 个 ‘?’ 记号组成。而你有一个小写字母印章 stamp。在每个回合,你可以将印章放在序列上,并将序列中的每个字母替换为印章上的相应字母。你最多可以进行 10 * target.length 个回合。举个例子,如果初始序列为"???",而你的印章 stamp 是 “abc”,那么在第一回合,你可以得到 “abc??”、"?abc?"、"??abc"。(请注意,印章必须完全包含在序列的边界内才能盖下原创 2020-11-19 17:10:43 · 127 阅读 · 0 评论 -
1505. 最多 K 次交换相邻数位后得到的最小整数
题目描述:给你一个字符串 num 和一个整数 k 。其中,num 表示一个很大的整数,字符串中的每个字符依次对应整数上的各个 数位 。你可以交换这个整数相邻数位的数字 最多 k 次。请你返回你能得到的最小整数,并以字符串形式返回。解题思路:从高位到低位遍历每一个位置,每一次都贪心的让更小的数字占据更高的位置,过程中需要判断交换的次数是否在k(每次交换之后剩下的次数)之内,这里通过一个树状数组来维护从当前位置往后一共向前移动过多少个数字,用来得到最终交换到特定位置需要的次数,代码如下:class BIT(原创 2020-11-18 16:18:31 · 405 阅读 · 0 评论 -
2020-11-16
题目描述:在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。说明:如果题目有解,该答案即为唯一答案。输入数组均为非空数组,且长度相同。输入数组中的元素均为非负数。解题思路一:循环遍历每一个加油站,判断从当前出发是否可以回到出发点,判断依据就是判断沿路的累积的汽原创 2020-11-16 19:17:21 · 100 阅读 · 0 评论 -
1497. 检查数组对是否可以被 k 整除
题目描述:给你一个整数数组 arr 和一个整数 k ,其中数组长度是偶数,值为 n 。现在需要把数组恰好分成 n / 2 对,以使每对数字的和都能够被 k 整除。如果存在这样的分法,请返回 True ;否则,返回 False 。解题思路:如果x与y的和能被k整除,那说明x%k+y%k能被k整除,因此我们对arr数组中的每个数对k取模,用哈希表记录每个余数出现的次数,然后按照余数进行配对,如果余数为零,那么要求0出现的次数为偶数,对其他的余数t,要求k-t出现的次数和t出现次数相同,代码如下:class原创 2020-11-15 17:15:27 · 118 阅读 · 0 评论 -
1568. 使陆地分离的最少天数
题目描述:给你一个由若干 0 和 1 组成的二维网格 grid ,其中 0 表示水,而 1 表示陆地。岛屿由水平方向或竖直方向上相邻的 1 (陆地)连接形成。如果 恰好只有一座岛屿 ,则认为陆地是 连通的 ;否则,陆地就是 分离的 。一天内,可以将任何单个陆地单元(1)更改为水单元(0)。返回使陆地分离的最少天数。解题思路:该题最多的天数不可能超过2,加入该岛屿是联通的,那么对于角落的点,最多去掉与它相邻的点那么一定可以让它与其他点分离,所以我们只需要考虑0和1的情况,对于0的情况只需要判断当前网格原创 2020-10-22 13:41:59 · 207 阅读 · 0 评论 -
1383. 最大的团队表现值
题目描述:公司有编号为 1 到 n 的 n 个工程师,给你两个数组 speed 和 efficiency ,其中 speed[i] 和 efficiency[i]分别代表第 i 位工程师的速度和效率。请你返回由最多 k 个工程师组成的 最大团队表现值 ,由于答案可能很大,请你返回结果对 10^9 + 7 取余后的结果。团队表现值 的定义为:一个团队中「所有工程师速度的和」乘以他们「效率值中的最小值」。解题思路:因为最终团队的表现值取决于最下的效率值和所有工程师速度的和,那么我们可以遍历每一个原创 2020-10-18 15:14:02 · 218 阅读 · 0 评论 -
406. 根据身高重建队列
题目描述:假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。解题思路:先按照高度从高到低排序,相同的高度在按照k从低到高排序,然后依次将他们放在输出队列中与k值对应相等的索引位置上,因为矮个子的人对高个子来说是看不见的,所以后放置矮个子不会影响到高个子前面比他高的人的个数,代码如下:class Solution: def reconstructQueue(self, peopl原创 2020-10-13 20:03:18 · 102 阅读 · 0 评论 -
452. 用最少数量的箭引爆气球
写在前面:贪心算法一般用来解决需要 “找到要做某事的最小数量” 或 “找到在某些情况下适合的最大物品数量” 的问题,且提供的是无序的输入。题目描述:在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以y坐标并不重要,因此只要知道开始和结束的x坐标就足够了。开始坐标总是小于结束坐标。平面内最多存在104个气球。一支弓箭可以沿着x轴从不同点完全垂直地射出。在坐标x处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足原创 2020-10-10 11:52:54 · 125 阅读 · 0 评论 -
1578. 避免重复字母的最小删除成本
题目描述:给你一个字符串 s 和一个整数数组 cost ,其中 cost[i] 是从 s 中删除字符 i 的代价。返回使字符串任意相邻两个字母不相同的最小删除成本。请注意,删除一个字符后,删除其他字符的成本不会改变。解题思路:每次遇到相邻的重复字母,就贪心的删除当前代价更小的那一个,也许后面还有和当前字符重复的字符而且代价更小,但因为只要是重复的字母都会被删除,所以当前这个字符最终也会因为有比他代价更高的相同字符而被删除掉,用这种贪心的做法可以得到最小的删除代价,代码如下:class Solutio原创 2020-10-10 11:20:15 · 184 阅读 · 0 评论 -
392. 判断子序列
题目描述:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)解题思路:每次都贪心的将t中靠前的字符和s中的字符进行匹配,假设当前s中待匹配的字符为c,c在字符串t中出现的位置为x1,x2原创 2020-10-09 19:54:50 · 161 阅读 · 0 评论 -
1217. 玩筹码
题目描述:数轴上放置了一些筹码,每个筹码的位置存在数组 chips 当中。你可以对 任何筹码 执行下面两种操作之一(不限操作次数,0 次也可以):将第 i 个筹码向左或者右移动 2 个单位,代价为 0。将第 i 个筹码向左或者右移动 1 个单位,代价为 1。最开始的时候,同一位置上也可能放着两个或者更多的筹码。返回将所有筹码移动到同一位置(任意位置)上所需要的最小代价。解题思路:因为移动两个位置不需要付出代价,所以将所有奇数位置的砝码移到任意一个奇数位置,将所有偶数位置的砝码移到任意一个偶数位置原创 2020-10-09 18:59:35 · 100 阅读 · 0 评论 -
1403. 非递增顺序的最小子序列
题目描述:给你一个数组 nums,请你从中抽取一个子序列,满足该子序列的元素之和 严格 大于未包含在该子序列中的各元素之和。如果存在多个解决方案,只需返回 长度最小 的子序列。如果仍然有多个解决方案,则返回 元素之和最大 的子序列。解决思路:先对数组排序,依次加入数组中最大的数直到超过总和的一半,这道题放在贪心算法的标签下的理解,每次都贪心的取最大的数,这样才能取到长度最小的和大于总和一半的子数组class Solution: def minSubsequence(self, nums: Li原创 2020-10-08 22:07:17 · 115 阅读 · 0 评论