贪心
leetcode总结的贪心题
重you小垃
这个作者很懒,什么都没留下…
展开
-
贪心_杂题_思考
题目:给出属于1…10 的n个盒子,用最多能装n的卡车装,最少装多少车?错误1:从小到大排序,然后贪心,尽量能装到前一辆车。错误样例:1 2 3 7 8 9 把小的都装在一起会浪费大量空间,大的找不到小的装,此时不是最优。正解:从大到小排序,然后贪心,尽量装到能放下该盒子已经装最多的卡车上,如果找不到,就把该盒子放到一个新的车上。............原创 2022-03-27 17:50:42 · 462 阅读 · 0 评论 -
leetcode6112.6112. 装满杯子需要的最短总时长(简单,周赛)
思路一:贪心具体思路:尽量让产生0最晚,这样就一直有正整数可以选,因此每次选最大的两个思路二:数学思想思路三:暴力dfs+记忆化原创 2022-07-10 15:54:05 · 145 阅读 · 0 评论 -
NC147.主持人调度(中等)
区间类型的第5类题型 (区间分组)思路:先按照左边界从小到大排列,然后判断之前组别的最小值是否小于该元素左边界,如果小于,则更新。否则成立新的组。细节实现:用小根堆维护组的最小值。class Solution {public: int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) { priority_queue<int, vector<..原创 2021-12-22 20:06:47 · 492 阅读 · 0 评论 -
常见的区间问题 leetcode56. 435. 452. 1024 NC147.
思路:保存前一个区间的左右端点。if 当前区间的左端点<=前一个区间的右端点,则对右端点进行更新。else 将前一个区间放入ans,然后更新左右端点的值。class Solution {public: vector<vector<int>> merge(vector<vector<int>>& intervals) { vector<vector<int>> ans..原创 2021-10-08 21:02:07 · 166 阅读 · 0 评论 -
leetcode1974. 使用特殊打字机键入单词的最少时间(简单)
class Solution {public: int minTimeToType(string word) { int ans = 0; char pre = 'a'; for (auto& ch : word) { ans += min(abs(ch - pre), 26 - abs(ch - pre)); ans++; pre = ch; }...原创 2022-04-28 21:04:15 · 281 阅读 · 0 评论 -
leetcode135.分发糖果(困难)
思想:贪心实现细节:step1:都初始化为1,从左向右遍历保证比左边的糖果多(比左边评分高的话)。比如评分数:3 4 2 1,这样的话2和1都是1个糖果step2:为了保证比右边的糖果多(比右边评分高的话),还要从右向左遍历取值取max(dp[i+1]+1, dp[i])class Solution {public: int candy(vector<int>& ratings) { int n = ratings.size(); ..原创 2022-04-17 21:55:48 · 143 阅读 · 0 评论 -
leetcode1024.视频拼接(中等)
区间题型的第四类题。思路一:贪心。细节:先按照起点排序,在能够覆盖起点的区间内找右端点的最大值。class Solution {public: int videoStitching(vector<vector<int>>& clips, int time) { vector<pair<int, int>> v; for (auto& each : clips) { ...原创 2021-12-22 19:59:53 · 935 阅读 · 0 评论 -
leetcode945.使数组唯一的最小增量(中等)
思路一:并查集 O(n),并查集复杂度接近O(1)findfather(i)为i-1要变到的数字,将i修改为findfather(i)后,将father[i]和father[i]+1进行合并。class Solution {public: int father[1000005]; int findfather(int n) { if (father[n] == n) return n; return father[n] = findfather(fa..原创 2022-04-17 16:18:54 · 195 阅读 · 0 评论 -
leetcode767.重构字符串(中等)
思路:画表格具体细节:先统计出每个字符出现的个数,设最大数目为_max ,如果 n - _max <_max - 1直接return false。否则在行为_max的表格按照字符出现的个数由多到少一列一列填即可。class Solution {public: bool cmp(const pair<char, int> &p1, const pair<char, int> &p2) { return p1.second > .原创 2022-04-17 16:07:32 · 188 阅读 · 0 评论 -
leetcode678.有效的括号字符串(中等)
思路一:维护左括号的_min和_max括号匹配的原则?左右括号总个数相等,前缀没有右括号大于左括号的情况_min维护左边多余左括号的最少个数,_max维护左边多余左括号的最多个数(均>=0)当遍历到左括号时:_min++;_max++;当遍历到右括号时:if (_max <1) return false_max- -;if (_min > 0) _min- -; 防止变为负数当遍历到 星号’*'时:由于‘*’可能是右括号,所以if (_min > 0) ..原创 2022-04-17 15:54:48 · 159 阅读 · 0 评论 -
leetcode969.煎饼排序(中等)
思路:一个一个放到最终位置也就是,先把最大的放到最终位置,然后把次大的放到最终位置,持续n次即把所有的放好放某一个值的方法:先找到该值的下标i,如果就在最终位置则不动,否则把[0…i]翻转,然后把[0…n-1]翻转。class Solution {public: vector<int> pancakeSort(vector<int>& arr) { vector<int> ans; int n ..原创 2022-04-17 15:43:56 · 168 阅读 · 0 评论 -
leetcode397.整数替换(中等)
思路一:dfs (时间复杂度:O(logn),即n二进制中1的个数)奇数有两个分支,对于偶数只有两个分支。class Solution {public: unordered_map<int, int> umap; int integerReplacement(int n) { if (n == 1) return 0; if (umap.count(n)) return umap[n]; if (n % 2) { ..原创 2022-04-16 12:05:14 · 639 阅读 · 0 评论 -
leetcode881.救生艇(中等)
思想:贪心尽量让载2人的船最多,由大到小排序,最大的尽量和最小的坐一艘船,此时对于最小重量来说是最优的class Solution {public: int numRescueBoats(vector<int>& people, int limit) { int n = people.size(); sort(people.begin(), people.end(), greater<int>()); ..原创 2022-04-12 18:50:17 · 189 阅读 · 0 评论 -
leetcode621.任务调度器(中等)
自己的思路:贪心先把每个字符的个数统计出来,按照个数从大到小排序。先放个数最多的,中间间隔n+1个位置,然后下标从小到大,依次放每个元素。这种思路是错的!比如样例:[“A”,“A”,“A”,“B”,“B”,“B”, “C”,“C”,“C”, “D”, “D”, “E”]2按我自己的方法做的话,调度的顺序为:ABCABCABCDE空DABCABCABCDE空D实际上更优的调度顺序是:ABCDEABCDABC 或者 ABCDABCDEABCABCDEABCDABC或者:A...原创 2021-12-02 22:22:02 · 682 阅读 · 0 评论 -
leetcode53.最大子数组和(简单)
解法一:dpdp[i]表示以 nums[i] 结尾的连续子数组的最大值。dp[i] = (dp[i - 1] + nums[i], nums[i])ans: dp数组中的最大值class Solution {public: int maxSubArray(vector<int>& nums) { int n = nums.size(); int dp = nums[0]; int ans = nums[0]; ...原创 2022-04-12 12:45:29 · 133 阅读 · 0 评论 -
leetcode316.去除重复字母(中等)
贪心的思想类似于:leetcode402.移掉 K 位数字(中等)https://blog.csdn.net/zhangjiaji111/article/details/123979083上面那道题的限制条件是:删除k位数字,这道题的限制是删掉重复的字母具体思想:维护一个分段单调递增栈。从左向右遍历,遍历到一个元素时,如果栈顶元素大于该元素且栈顶元素在后面还有(last 数组记录每个字符最后出现的位置),则把它出栈,重复这个过程,直到不满足前面栈顶元素大于该元素且栈顶元素在后面还有的条件将该元素.原创 2022-04-11 21:42:49 · 152 阅读 · 0 评论 -
leetcode738. 单调递增的数字(中等)
思路:贪心实现细节:从左到右遍历,遇到第一个将要下降的数字[i]将其减少1,右侧的都改成9即可,如果遍历到末尾了则直接return这样可能出现的问题:减1之后,可能[i-1]>[i](即[i-1]和[i]刚开始相等),此时i-1需要减1,直到前面的都满足递增,从最左边-1处右边都改成’9’class Solution {public: int monotoneIncreasingDigits(int m) { string s = to_string(m); ..原创 2022-04-11 21:08:20 · 208 阅读 · 0 评论 -
leetcode1702.修改后的最大二进制字符串(中等)
思路:移动的贪心题之后记住几个结论:如果规定:10->01(反转) 即规定了所有的0可以向左移动,但是不能向右移动如果规定:01->10(反转) 即规定了所有的0可以向右移动,但是不能向左移动如果规定:00->10 即0…0可以转化为0…1的形式这道题的思路:step1:如果s中0的个数小于2则returnstep2:由于该题中0只能向左移动,此时s中0的个数大于2,后面的0都移动到第一组0的后面,然后把最后的0改为1即可。class Solution {publi..原创 2022-04-10 20:58:33 · 214 阅读 · 0 评论 -
leetcode714.买卖股票的最佳时机含手续费(中等)
思路:贪心。手续费和买股票的价格放在一起考虑,第一次付了手续费,相当于下次就能免费买股票了,并且prices[i]为买的费用。代码细节:遍历,如果比自己当前付出的钱 多,则卖出并且免手续费买了这支股票,否则更新手里的钱(即以更低的价格买股票)class Solution {public: int maxProfit(vector<int>& prices, int fee) { int ans = 0; int buy = price..原创 2022-04-08 22:03:25 · 204 阅读 · 0 评论 -
leetcode781.森林中的兔子(中等)
思路:贪心具体思路:将answer[i]相等的兔子放在一类(同一种颜色的兔子回答肯定一样),尽量让这些兔子使用的颜色数量最少,某颜色的兔子有x个,回答的是y个兔子跟自己一样。则x/(y+1)向上取整为组数z,z*(y+1)为最少的个数,把所有的类加起来即可。class Solution {public: int numRabbits(vector<int>& answers) { unordered_map<int, int> ha..原创 2022-04-06 22:32:03 · 316 阅读 · 0 评论 -
leetcode650.只有两个键的键盘(中等)
思路:贪心具体思路:最后一次粘贴的是n的最大公因数,往前一直递推,直到遇到一个质数,该质数只能由一个一个粘贴得到。下面是代码上的优化:class Solution {public: int minSteps(int n) { int ans = 0; if (n == 1) return 0; int flag = true; // while (flag) { int i = n..原创 2022-04-06 22:29:27 · 198 阅读 · 0 评论 -
leetcode402.移掉 K 位数字(中等)
思路:贪心。具体细节:删除第k次的操作为:从num中从左向右遍历,遇到第一个下降的位置时,就删除左边这个数字,重复k次即可,这样是k×n的复杂度,超时。优化方式:单调栈,维护一个单调递增的栈即可,每次从栈顶删掉左边的数字,遍历完后形成的栈删除个数<k的话,需要从上面删够k个,因为是一个单调递增的栈。class Solution {public: string removeKdigits(string num, int k) { int n = num..原创 2022-04-05 22:38:01 · 353 阅读 · 0 评论 -
leetcode376.摆动序列(中等)
思路:flag的正负来表示上一次的状态,当“峰”遇到下降时ans++,当“谷”遇到上升时ans++。class Solution {public: int wiggleMaxLength(vector<int>& nums) { int n = nums.size(); if (n < 2) return n; int flag = nums[1] - nums[0], ans = (nums[1]...原创 2022-04-05 21:12:19 · 690 阅读 · 0 评论 -
leetcode581.最短无序连续子数组(中等)
思路一:排序,排完序后找不一致的左端点和右端点class Solution {public: int findUnsortedSubarray(vector<int>& nums) { int n = nums.size(); vector<int> tmp(nums); sort(tmp.begin(), tmp.end()); int left = 0, right = n - 1; ...原创 2021-12-12 22:29:46 · 392 阅读 · 0 评论 -
leetcode179.最大数(中等)
错误思路:转化为字符串后由大到小排序,对于最高位一样的情况,这种方法不适用。比如:4 5 42 应该是5442正确思路:两个元素两两比较,如果xy 比 yx大,则把x放到y前面,满足传递性。class Solution {public: string largestNumber(vector<int>& nums) { int n = nums.size(); sort(nums.begin(), nums.end(), [](int ..原创 2022-04-05 17:52:56 · 310 阅读 · 0 评论 -
Offer45.把数组排成最小的数(中等)
错误思路:按照每个数字由小到大排序来做的话,对于第一个数字相同的不适用。比如:57 58 5 6正解思路:使用传递性,将整个数组排序,如果ab比ba小,则把a放在b的前面,最后将整个数组合并即可。class Solution {public: string minNumber(vector<int>& nums) { int n = nums.size(); sort(nums.begin(), nums.end(), [](int a..原创 2022-04-05 17:46:35 · 310 阅读 · 0 评论 -
leetcode406.根据身高重建队列(中等)
自己没思路。。。解法:排序 + 挨个找位置。具体思路:将people按照h从小到大,h相同按照k从大到小排列。从下标0开始遍历,一个一个找对应位置(第k+1个空位置)。h从小到大的理由:因为h代表的是前面有多少个大于等于h的个数,所以比它小的先放并不会影响到它h相同按照k从大到小排列的理由:h相同k较大的先放不影响较小的放的位置class Solution {public: vector<vector<int>> reconstructQueue(vecto...原创 2021-12-31 17:27:11 · 569 阅读 · 0 评论 -
leetcode452.用最少的箭引爆气球(中等)
属于区间题型的第三类题。思路:贪心,按照右端点升序,每次尽量射右端点的位置class Solution {public: static bool cmp(pair<int, int> p1, pair<int, int> p2) { return p1.second < p2.second; } int findMinArrowShots(vector<vector<int>>& points)...原创 2021-12-22 19:45:03 · 334 阅读 · 0 评论 -
leetcode435.无重叠区间(中等)
属于区间问题的第二类题。思路:贪心class Solution {public: static bool cmp(pair<int, int> p1, pair<int, int> p2) { return p1.second < p2.second; } int eraseOverlapIntervals(vector<vector<int>>& intervals) { //...原创 2021-12-22 19:35:31 · 365 阅读 · 0 评论 -
leetcode134.加油站(中等)
思路:贪心step1: 想走完全全程的前提:gas的汽油量大于等于cost的消耗量,不满足直接return -1问题一:为什么gas的汽油量大于等于cost的消耗量一定可以走完全程?我们从起点0开始,累加每个站点的gas[i]−cost[i],即left(i)当站i累加完left(i)后,如果小于0,则站0到站i都不是起点,[0,i]段的sum(left)<0我们将i+1作为新的起点,重新累加每个站点的left(i)当站j累加完left(j),如果小于0,则站i+1到站j都不是起点。...原创 2022-04-02 21:16:10 · 191 阅读 · 0 评论 -
leetcode45.跳跃游戏Ⅱ(中等)
leetcode55.跳跃游戏:https://blog.csdn.net/zhangjiaji111/article/details/120659495方法一:贪心具体思路:当前的位置跳的位置为:下下次可以跳得更远的位置。 通过局部最优得到全局最优解。class Solution {public: int jump(vector<int>& nums) { int n = nums.size(), index = 0, ans = ..原创 2021-12-12 23:03:06 · 1785 阅读 · 0 评论 -
leetcode122.买股票的最佳时机II(中等)
思路一:贪心(长期的过程转化为每一步)实现细节:(1) 连续上升时:nums[j]-nums[i]=(nums[i+1]-nums[i])+(nums[i+2]-nums[i+1])+…+(nums[j]-nums[j-1]) 将连续的上升过程转化为小段的上升过程,即如果nums[i]>nums[i-1]即在nums[i]进行买卖(2) 连续下降时:转化为小段的下降过程,此时不买不卖class Solution {public: int maxProfit(vector&l...原创 2022-04-02 15:41:36 · 105 阅读 · 0 评论 -
leetcode763.划分字母区间(中等)
思想:贪心。让第一个片段尽量短。类似于:跳跃游戏,https://blog.csdn.net/zhangjiaji111/article/details/120659495 遍历的过程中不断更新最远。class Solution {public: vector<int> partitionLabels(string s) { int n = s.size(); char last[26]; vector<in.原创 2022-04-02 14:55:53 · 4005 阅读 · 0 评论 -
leetcode55.跳跃游戏(中等)
思路:如果某一个作为起跳点的格子可以跳跃的距离是3,那么表示后面3个格子都可以作为起跳点,可以对每一个能作为起跳点的格子都尝试跳一次,把能跳到最远的距离不断更新,如果可以一直跳到最后,就成功了class Solution {public: bool canJump(vector<int>& nums) { int n = nums.size(); if (n == 1) return true; int index = ..原创 2021-10-08 20:42:46 · 514 阅读 · 0 评论 -
leetcode11.盛最多水的容器(中等,双指针)
思路: 使用双指针,L开始一个指向最左端高度h1 R指向最右端高度h2,当前可容纳的水量为: min(h1,h2)*(n-1-0),然后移动高度小的指针(因为如果移动高度大的指针,min将会<=之前的min,而且指针之间的距离也会缩短此时容的水量一定在变小),直到L==R为止。注意:1.高度到最左边第一个大于等于它 ,最右边第一个大于等于它的位置2.单调栈在这里没用!!!class Solution {public: int maxArea(vector<int>..原创 2021-09-14 22:50:11 · 96 阅读 · 0 评论 -
leetcode2027. 转换字符串的最少操作次数(简单)
思路:贪心;跳格子问题。class Solution {public: int minimumMoves(string s) { //X:跳三格 int n = s.size(); int i = 0, ans = 0; while (i < n) { if (s[i] == 'X') { ans++; i += ...原创 2022-04-01 15:19:59 · 269 阅读 · 0 评论 -
leetcode1005.K次取反后最大化的数组和(简单)
思路:先把所有的负数反转(先反转最小的负数),然后如果k为偶数则返回sum 否则sum减去2倍的最小值思路简单,代码需要简洁一些:class Solution {public: int largestSumAfterKNegations(vector<int>& nums, int k) { sort(nums.begin(), nums.end()); int sum = 0; for (auto& each ..原创 2022-04-01 15:13:14 · 657 阅读 · 0 评论 -
leetcode LCS01.下载插件(简单)
思路:贪心。先加倍最后再下载的时间是最短的,下载的次数为1-n,找到需要加倍到的最小值,枚举1-n即可。class Solution {public: int leastMinutes(int n) { int ans = INT_MAX; for (int i = 1; i <= n; ++i) { int j = ceil((double)n / i); ans = min(ans, i + (int)..原创 2022-03-31 19:42:45 · 200 阅读 · 0 评论 -
leetcode LCP33.蓄水(简单)
思路:贪心+枚举具体思路:对于任意一个水桶来看,要么升级水桶要么蓄水,如果蓄水之后再升级水桶之后可以满足,那么先升级水桶再蓄水一定满足,因为倒的水更多了,水缸更会倒满,因此我们可以先升级水桶,最后再蓄水。细节:i枚举蓄水次数,取值范围是1->max(水缸容量),则满足i的最小水桶容量为 ceil(水缸大小/i) ,需要升级的次数为 ceil(水缸大小/i)-水桶容量,所有的水缸加起来即可所有的升级次数,加i即为总的次数,ans取i循环中的最小值即可。class Solution {pub...原创 2022-03-30 20:51:08 · 359 阅读 · 0 评论 -
leetcode300.最长递增子序列(中等)
解法一:dp 时间复杂度O(n^2)class Solution {public: int lengthOfLIS(vector<int>& nums) { int n = nums.size(); vector<int> dp(n, 1); int ans = 1; for (int i = 1; i < n; ++i) { for (int j = 0; j...原创 2022-01-26 14:34:19 · 243 阅读 · 0 评论