【LeetCode】贪心 greedy(共38题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica }

【44】Wildcard Matching

【45】Jump Game II (2018年11月28日,算法群衍生题)

题目背景和 55 一样的,问我能到达最后一个index的话,最少走几步。

题解:

【55】Jump Game (2018年11月27日,算法群)

给了一个数组nums,nums[i] = k 代表站在第 i 个位置的情况下, 我最多能往前走 k 个单位。问我能不能到达最后一个 index。

题解:虽然是贪心分类,我还是用dp解了。dp[i] 代表我能不能到达第 i 个位置。

 1 class Solution {
 2 public:
 3     bool canJump(vector<int>& nums) {
 4         const int n = nums.size();
 5         if (n == 0) {return false;}
 6         vector<int> f(n, 0); //f[i] 代表第i个index是不是可达
 7         f[0] = 1;
 8         for (int i = 0; i < n; ++i) {
 9             if (f[i]) {
10                 const int k = nums[i];
11                 for (int j = 1; j <= k; ++j) {
12                     if (i+j >= n) {break;}
13                     f[i+j] = 1;
14                 }
15             }
16         }
17         return f[n-1] == 1;
18     }
19 };

【122】Best Time to Buy and Sell Stock II (2018年11月26日,算法群)

这个题目股票系列里面说了,这里不重复写了。股票系列:https://www.cnblogs.com/zhangwanying/p/9360841.html

【134】Gas Station (2019年1月27日,谷歌tag)

一个圆形的跑道,上面有 N 个加油站,每个加油站能加的油是 gas[i],假设你的车能加无限的油量,从第 i 个加油站跑到第 i+1 个加油站所消耗的油是 cost[i], 返回从第几个加油站能够顺时针跑完一圈,如果从任意一个都不能跑完的话,就返回-1

题解:本题似乎用到了一个数学定理/方法。就是如果能跑完一圈的话,必定存在从一个点开始,任意的点上的油量都不会为负数。

 1 class Solution {
 2 public:
 3     int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
 4         int total = 0;
 5         int sum = 0;
 6         int ans = 0;
 7         for(int i = 0; i < gas.size(); ++i){
 8             sum += gas[i] - cost[i];
 9             total += gas[i] - cost[i];
10             if(sum < 0){
11                 ans = i+1;
12                 sum = 0;
13             }
14         }
15         return total < 0? -1 : ans;
16     }
17 };

【135】Candy (2019年1月27日,谷歌tag)

每个小孩有一个 rating,你要给这些小孩发糖果,满足两条规则:规则1. 每个小孩至少一个糖果; 规则2. 如果一个小孩的rating比它的邻居高,那么他的糖果数量要比邻居多。问发完所有小孩的最少糖果数量。

题解:设置两个数组,一个front,从前往后应该发的糖果数量。一个back,表示从后往前应该发的糖果数量。final[i] = max(front[i], back[i]); O(N) with 2 pass

 1 //每个小孩至少一个糖果,
 2 //如果当前小孩的rating比它前一个小孩大的话,就是它前一个小孩的糖果数量+1
 3 //如果当前小孩的rating比它后一个小孩大的话,就是它后一个小孩的糖果数量+1
 4 class Solution {
 5 public:
 6     int candy(vector<int>& ratings) {
 7         const int n = ratings.size();
 8         vector<int> front(n , 1), back(n, 1);
 9         for (int i = 1; i < n; ++i) {
10             front[i] = ratings[i-1] < ratings[i] ? front[i-1] + 1 : 1;
11         }
12         int res = max(front[n-1], back[n-1]);
13         for (int i = n - 2; i >= 0; --i) {
14             back[i] = ratings[i] > ratings[i+1] ? back[i+1] + 1 : 1;
15             res += max(front[i], back[i]);
16         }
17         return res;
18     }
19 };

【253】Meeting Rooms II

题意是252的升级版,给了一个数组,数组里面的每个元素代表一个会议的开始时间和结束时间,问想安排下所有的会议,至少需要多少个会议室。

题解:这个题目在 sort 的分类里面说过,链接:https://www.cnblogs.com/zhangwanying/p/9914941.html

【316】Remove Duplicate Letters

【321】Create Maximum Number

【330】Patching Array

【358】Rearrange String k Distance Apart

【376】Wiggle Subsequence

【392】Is Subsequence

【402】Remove K Digits

【406】Queue Reconstruction by Height(2018年11月26日)

给了一个 people 的数组,数组里面每个元素是一个 pair (h, k) 代表 这个人身高是 h, 在排序好的队列中前面有 k 个人的升高大于等于 h。返回这个排序好的队列。

题解:有点类似于插入排序。我们先把people排序,排序按照身高降序,身高相同就按照 k 递增排序。然后做插入排序。对于排序好的people的每个元素 people[i],直接插入ret数组中的 people[i].second = k 这个位置上。

 1 class Solution {
 2 public:
 3     vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {
 4         const int n = people.size();
 5         if (n == 0) {return people;}
 6         sort(people.begin(), people.end(), cmp);
 7         vector<pair<int, int>> ret;
 8         for (int i = 0; i < people.size(); ++i) {
 9             ret.insert(ret.begin() + people[i].second, people[i]);
10         }
11         return ret;
12     }
13     static bool cmp(const pair<int, int>& p1, const pair<int, int>& p2) {
14         if (p1.first == p2.first) {
15             return p1.second < p2.second;
16         }
17         return p1.first > p2.first;
18     }
19 };

【435】Non-overlapping Intervals (2018年11月26日)

这题应该见过了orz,莫名的熟悉。题意就是给了一堆线段,问这些线段在不重叠的前提下,最少要剔除几条满足这个线段不重叠的条件。

题解:最少剔除几条才能让所有线段不重叠,其实翻译过来,就是这些线段最多多少条不重叠。我们想这条直线上放尽可能多的线段,需要什么样的策略呢?就是第一条线段的末端的数值尽可能的小,这样后面能选择的空间才比较大。

所以先排序,按照线段末端从从小到大排序。然后贪心一个一个处理。(唯一一个注意点是线段的头尾都有可能是负数。)

 1 /**
 2  * Definition for an interval.
 3  * struct Interval {
 4  *     int start;
 5  *     int end;
 6  *     Interval() : start(0), end(0) {}
 7  *     Interval(int s, int e) : start(s), end(e) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     int eraseOverlapIntervals(vector<Interval>& intervals) {
13         const int n = intervals.size();
14         if (n == 0) {return n;}
15         sort(intervals.begin(), intervals.end(), cmp);
16         int cnt = 0;
17         int b = intervals[0].start;
18         for (auto inter : intervals) {
19             if (inter.start >= b) {
20                 ++cnt;
21                 b = inter.end;
22             }
23         }
24         return n - cnt;
25     }
26     static bool cmp(const Interval& p1, const Interval& p2) {
27         if (p1.end == p2.end) {
28             return p1.start > p2.start;
29         }
30         return p1.end < p2.end;
31     }
32 };

【452】Minimum Number of Arrows to Burst Balloons

【455】Assign Cookies

【484】Find Permutation

【502】IPO

【621】Task Scheduler

【630】Course Schedule III

【649】Dota2 Senate

【651】4 Keys Keyboard

【659】Split Array into Consecutive Subsequences

【714】Best Time to Buy and Sell Stock with Transaction Fee

【738】Monotone Increasing Digits

【757】Set Intersection Size At Least Two

【759】Employee Free Time

【763】Partition Labels (2018年11月27日)(这题第一遍的时候不会写,看了答案才会写。)

给了一个只含有小写字母的字符串,求这个字符串的能变成 partition label 的所有子串的长度(partition的越多越好)。能变成 partition label 的条件是,一个label里面含有的字母不能在其他label里面含有。

题解:我们用一个 map 记录每个字母最后一次出现的下标。然后用两个变量, start 和 end 表示当前 label 的开始和截止位置。遍历整个字符串,更新 end = max(mp[S[i]], end), 当我们发现 i == end 的时候,这个时候就是这个 label 结束了。

 1 //本题第一遍的时候不会做看了答案。
 2 class Solution {
 3 public:
 4     vector<int> partitionLabels(string S) {
 5         const int n = S.size();
 6         unordered_map<char, int> mp; //record the last pos of c appear in S
 7         for (int i = 0; i < n; ++i) {
 8             mp[S[i]] = i;
 9         }
10         int start = 0, end = 0;
11         vector<int> ret;
12         for (int i = 0; i < n; ++i) {
13             end = max(mp[S[i]], end);
14             if (end == i) {
15                 ret.push_back(end - start + 1);
16                 start = i + 1;
17             }
18         }
19         return ret;
20     }
21 };

【765】Couples Holding Hands

【767】Reorganize String

【842】Split Array into Fibonacci Sequence

【860】Lemonade Change

【861】Score After Flipping Matrix

【870】Advantage Shuffle

【874】Walking Robot Simulation

【881】Boats to Save People

原文地址:https://www.cnblogs.com/zhangwanying/p/9886719.html

时间: 2024-11-07 10:24:57

【LeetCode】贪心 greedy(共38题)的相关文章

【LeetCode】设计题 design(共38题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [146]LRU Cache [155]Min Stack [170]Two Sum III - Data structure design [173]Binary Search Tree Iterator [208]Implement Trie (Prefix Tree) [211]Add and Search Word - Data structure desig

LeetCode OJ Linked List: 138题、109题和191题

138题:Copy List with Random Pointer 题目分析: 本题思路1:第一步,你需要遍历一下链表,对于每个结点,你都new出一个连接在其后面.第二步,调整random指针.第三步,把复制的链表与原链表断开.时间复杂度O(N),空间复杂度O(1). 本题思路2:第一步,仍需要遍历一下链表,对于每个结点都new出一个节点,但不连接在其后面,把这种旧节点到新结点的映射关系,存储在map中.第二步,调整random指针.时间复杂度O(N),空间复杂度O(N). 本题思路3:第一步

Leetcode 贪心 Best Time to Buy and Sell StockII

l and dished out an assist in the Blackhawks' 5-3 win over the Nashville Predators.Shaw said just playing with the Blackhawks was enough motivation for him."Positive, I'm playing in the NHL," Shaw said after Sunday's win. "What can't you be

Leetcode 贪心 Best Time to Buy and Sell Stock

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie Best Time to Buy and Sell Stock Total Accepted: 13234 Total Submissions: 43145 Say you have an array for which the ith element is the price of a given stock on day i. If you were only permitted to

HDU1009_FatMouse&amp;#39; Trade【贪心】【水题】

FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 44470    Accepted Submission(s): 14872 Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats g

HDU1009_FatMouse&#39; Trade【贪心】【水题】

FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 44470    Accepted Submission(s): 14872 Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats g

剑指offer 面试38题

面试38题: 题:字符串的排列 题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 解题思路:把字符串看成两部分:第一部分是它的第一个字符:第二部分是后面的所有字符. 递归 解题代码: # -*- coding:utf-8 -*- class Solution: def Permutation(self, ss): # write code here if not s

【leetcode 简单】第十七题 二进制求和

实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 输出: 2 示例 2: 输入: 8 输出: 2 说明: 8 的平方根是 2.82842...,   由于返回类型是整数,小数部分将被舍去. #define PF(w) ((w)*(w)) int mySqrt(int x) { int start = 0; int end = x; double mid = 0; i

【leetcode 简单】 第九十一题 找不同

给定两个字符串 s 和 t,它们只包含小写字母. 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母. 请找出在 t 中被添加的字母. 示例: 输入: s = "abcd" t = "abcde" 输出: e 解释: 'e' 是那个被添加的字母. class Solution(object): def findTheDifference(self, s, t): """ :type s: str :type t: str :