贪心
abant2
世界上最菜的arcem
展开
-
leetcode 2216 美化数组的最少删除数 dp&贪心两种做法
解法一:动态规划(dp)一般这类线性问题都可以用dp解决,我们定义 dp[i]dp[i]dp[i] 为前 iii 个元素组成美化数组的最少删除数。根据题目定义,如果是奇数个元素,那么就要删除一个元素,所以 dp[0]=1dp[0] = 1dp[0]=1。前两个元素可以根据相不相同来进行删除,如果两个相同必须全部删除,公式如下所示:dp[1]={2dp[0] == dp[1]0dp[0] != dp[1]dp[1]=\begin{cases}2& \.原创 2022-04-01 22:26:41 · 315 阅读 · 1 评论 -
leetcode 55 跳跃问题 贪心考虑最远距离
此题和1871题有些相似。对于这类跳跃问题,考虑最远距离往往是速度最快的解法。我们在每个地方贪心更新最大值,一次遍历即可完成。class Solution {public: bool canJump(vector<int>& nums) { int n = nums.size(); int mx = nums[0]; for(int i=1;i<n;i++) { if(mx &l.原创 2021-07-21 13:16:16 · 150 阅读 · 0 评论 -
leetcode 207 拓扑排序判断是否有环 回溯+bfs
解法一:dfs回溯法dfs解拓扑排序在无环情况下很方便,反向存边然后dfs即可。但要判断有没有环时,需要用回溯的思路:对每个点dfs,若无环,回溯时将这个点视为安全。具体操作时,存一个flag,dfs进入时让它为1,结束安全了变成-1.class Solution {map<int, vector<int>> m;map<int, int> F;public: int dfs(int n) { if(F[n] == -1)retu原创 2021-06-16 23:41:43 · 154 阅读 · 0 评论 -
leetcode 31 下一个排列 贪心(有难度)
这个题还是有难度的,不看题解挺难想。第一个重要的点是要找左边尽量靠右的元素和右边尽量小的元素交换,交换后对左边位置后面的元素排序/反转。这个是要自己找规律(很难找)第二个点就是,已知上面的算法,如何找到这两个点。这个方法就更妙了。首先要找尽量靠右的元素,尽量靠右,但要保证他右边还有比他更小的元素。所以我们要从右往左找,直至找到一个元素使得nums[i-1] < nums[i]这样就找到左元素。此时可以发现右边是一个降序序列,只要从右往左找,找到第一个比左元素大的元素就是右元素了(能满足尽量原创 2020-11-10 10:21:34 · 102 阅读 · 0 评论 -
leetcode 1658 将 x 减到 0 的最小操作数 双指针+前后缀和 全两种做法
这是京东周赛的第三题,没做出来也是不太高兴。这题我一开始想的是dp,其实是个锤子dp。大概我的做法就是右边每去除一个元素,左边都枚举一下,O(N^2)的复杂度,然后就无限超时。。还有种做法是双指针,左边固定,移动右边,满足条件就停或者移动左边,最坏也是N方的复杂度,但好像是能过的。最强的做法是O(N)的,即看到这类连续子序列求和问题,最好是存前缀和的。此题存一个左前缀和和一个右前缀和即可。对每一个左边序列,判断另一个在不在右前缀里。(这不是TwoSum吗。。。。太笨了)class Solution:原创 2020-11-15 14:57:17 · 315 阅读 · 0 评论 -
leetcode 134 加油站 前缀和变形
这一题是贪心思路,自己一开始应该就想到了最快最强的算法。(没看题解哦~)遍历一遍,从头开始累加。对于累加和,正的可以合并负的,因为一定要从正数开始,他早晚会遇到负的。如果负的遇到正的,就不能再继续累加了,因为下一个正的有可能是起点。上述方法做完后,只有最后一个元素有可能是正的,否则累加不会结束,前面都是负的。所以只需要判断最后一个是否为正数,并且数组和是否为正即可。class Solution: def canCompleteCircuit(self, gas: List[int], cost原创 2020-11-18 10:58:13 · 63 阅读 · 0 评论 -
leetcode 283 移动零 单指针方法
题解是双指针,但其实单指针就足够了。每次遍历把零元素存起来,这样交换后交换的零元素也在后面,一次遍历就可以结束。from collections import dequeclass Solution: def moveZeroes(self, nums: List[int]) -> None: """ Do not return anything, modify nums in-place instead. """ zeros原创 2020-11-19 09:49:54 · 76 阅读 · 0 评论 -
leetcode 452 区间贪心问题 两种解法
这题看起来是气球什么的,其实就是一个典型的区间问题。解法一:左元素优先排序一开始的做法是很典型的,先对元组从小到大排序(先排第一个数,再排第二个数)。然后开始遍历,保存最小的右边界,如果有左元素超出了最小右边界,就要开一枪,代码如下:class Solution: def findMinArrowShots(self, points: List[List[int]]) -> int: l = sorted(points, key=lambda x: (x[0], x[1]原创 2020-11-23 14:16:49 · 142 阅读 · 0 评论 -
leetcode 767 堆+贪心两种做法
解法一:堆这个做法真的很秒,把所有字符及其数量放入堆中,然后每次排出最大的两个元素,这样就不会有重复,真的惊了,太强的做法!这次用了python实现堆,学会了__lt__定义比较函数,python还是很香。from queue import PriorityQueueclass Solution: def reorganizeString(self, S: str) -> str: class node: def __init__(self, c,原创 2020-11-30 16:52:15 · 196 阅读 · 0 评论 -
leetcode 621 堆+贪心维护(767升级版)
解法一:贪心堆这是我自己想的解法,先把任务变成字典,每次取剩余最多的任务,然后放入冷却堆,待到时间后取出。若优先队列里没元素了,专门处理冷却堆就行,这里采用了一个个排出再加进去的方法,代码如下:from queue import PriorityQueue, Queueclass Solution: def leastInterval(self, tasks: List[str], n: int) -> int: class t: def __in原创 2020-12-05 20:57:05 · 107 阅读 · 0 评论 -
leetcode 738 贪心
这题要先找到最前面前一位比后面大的数字,这一位后面就都是9,这一位减一,前面的不变。class Solution: def monotoneIncreasingDigits(self, N: int) -> int: n = N power, ct = 1, -1 while N >= 10: num1 = N % 10 N //= 10 num2 = N % 10原创 2020-12-15 09:36:31 · 46 阅读 · 1 评论 -
leetcode135 两次遍历消除局部限制
解法一:一次遍历解法二:两次遍历class Solution: def candy(self, ratings: List[int]) -> int: rs1 = [1 for _ in range(len(ratings))] rs2 = [1 for _ in range(len(ratings))] for i in range(1, len(ratings)): if ratings[i] > rati原创 2021-03-17 14:17:25 · 123 阅读 · 0 评论 -
leetcode 665 非递减序列 贪心 逻辑
此题是有一定难度的,有点绕。只能改一次,第一个重要的点是只能有一次右边小于左边,不然不可能改好。第二个点是,当遇到这个点时,如何处理?遇到这个点时,要考虑左边右边要连接起来,然后交给右边考虑就行。如果较小的元素和左边相隔一个的元素能连起来,说明其左边的元素偏大,将它变小。如果连不起来,就把自己升高到和左边的元素一样大,不然左右无法连续。如果左边相隔一个没有元素,那就将左边的元素变小,可以更方便的连续。class Solution: def checkPossibility(self, nums:原创 2021-02-07 21:44:46 · 140 阅读 · 0 评论