贪心思想:保证每次操作都是局部最优的,并且最后得到的结果是全局最优的。
455. Assign Cookies
给一个孩子的饼干应当尽量小又能满足该孩子,这样大饼干就能拿来给满足度比较大的孩子。因为最小的孩子最容易得到满足,所以先满足最小的孩子。
class Solution {
public:
int findContentChildren(vector& g, vector& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int gi = 0, si = 0;
int count = 0;
while (gi < g.size() && si < s.size())
{
if (g[gi] <= s[si])
{
++gi;
++si;
++count;
}
else
++si;
}
return count;
}
};
435. Non-overlapping Intervals
先计算最多能组成的不重叠区间个数,然后用区间总个数减去不重叠区间的个数。
在每次选择中,区间的结尾最为重要,选择的区间结尾越小,留给后面的区间的空间越大,那么后面能够选择的区间个数也就越大。按区间的结尾进行排序,每次选择结尾最小,并且和前一个区间不重叠的区间。
class Solution {
public:
int eraseOverlapIntervals(vector>& intervals) {
//按照第二个坐标的升序进行排序
int n = intervals.size();
if (n == 0)
return 0;
sort(intervals.begin(), intervals.end(), cmp);
int count = 1;
int pre = 0; //记录当前访问的前驱
for (int i = 1; i < n; ++i)
{
//当前访问的点的第一个坐标大于等于前驱结点的第二个坐标
if (intervals[i][0] >= intervals[pre][1])
{
pre = i;
++count;
}
}
return n - count;
}
private:
static bool cmp(vector&lhs, vector&rhs)
{
if (lhs[1] == rhs[1])
return lhs[0] < rhs[0];
return lhs[1] < rhs[1];
}
};
452. Minimum Number of Arrows to Burst Balloons
也是计算不重叠的区间个数,不过和上题的区别在于:[1, 2] 和 [2, 3] 在本题中算是重叠区间。
class Solution {
public:
int findMinArrowShots(vector>& points) {
//按照第二个坐标的升序进行排序
int n = points.size();
if (n == 0)
return 0;
sort(points.begin(), points.end(), cmp);
int count = 1;
int pre = 0; //记录当前访问的前驱
for (int i = 1; i < n; ++i)
//当前访问的点的第一个坐标大于等于前驱结点的第二个坐标
if (points[i][0] > points[pre][1])
{
pre = i;
++count;
}
}
return count;
}
private:
static bool cmp(vector&lhs, vector&rhs)
{
if (lhs[1] == rhs[1])
return lhs[0] < rhs[0];
return lhs[1] < rhs[1];
}
};
为了使插入操作不影响后续的操作,身高较高的学生应该先做插入操作,否则身高较小的学生原先正确插入的第 k 个位置可能会变成第 k+1 个位置。h降序、k 值升序,然后按排好序的顺序插入队列的第 k 个位置中。
406. Queue Reconstruction by Height
class Solution {
public:
vector> reconstructQueue(vector>& people) {
vector>res;
int n = people.size();
if (n == 0)
return res;
sort(people.begin(), people.end(), cmp);
for (int i = 0; i < n; ++i)
{
if (i == 0)
res.push_back(people[i]);
else
{
res.insert(res.begin() + people[i][1], people[i]);
}
}
return res;
}
private:
static bool cmp(vector lhs, vector rhs)
{
if (lhs[0] == rhs[0])
return lhs[1] < rhs[1];
return lhs[0] > rhs[0];
}
};
763. Partition Labels
class Solution {
public:
vector partitionLabels(string S) {
vector lastPos(26); //保存每个字符最后一次出现的位置
int len = S.size();
for (int i = 0; i < len; ++i)
lastPos[S[i] - 'a'] = i;
int start = 0; //start表示每个子串的起始位置
int end = 0; //end表示每个子串的终止位置
vector res;
while(start end)
end = lastPos[S[s] - 'a'];
}
res.push_back(end - start + 1);
start = s;
}
return res;
}
};
605. Can Place Flowers
class Solution {
public:
bool canPlaceFlowers(vector& flowerbed, int n) {
int len = flowerbed.size();
int cnt = 0;
for (int i = 0; i < len; ++i)
{
if (flowerbed[i])
continue;
int pre = i == 0 ? 0 : flowerbed[i - 1];
int suc = i == len - 1 ? 0 : flowerbed[i + 1];
if (!pre&& !suc)
{
++cnt;
flowerbed[i] = 1;
}
}
return cnt >= n;
}
};
392. Is Subsequence
递归解法(LeetCode提交超内存)
class Solution {
public:
bool isSubsequence(string s, string t) {
int sLen = s.length();
int tLen = t.length();
if (sLen == 0)
return true;
if (tLen == 0)
return false;
return solveCore(s, 0, t, 0);
}
private:
bool solveCore(string s, int ss, string t, int ts)
{
if (ss >= s.length())
return true;
if (ts >= t.length())
return false;
if (s[ss] == t[ts])
return solveCore(s, ss + 1, t, ts + 1);
return solveCore(s, ss, t, ts + 1);
}
};
迭代解法
class Solution {
public:
bool isSubsequence(string s, string t) {
int sLen = s.length();
int tLen = t.length();
if (sLen == 0)
return true;
if (tLen == 0)
return false;
int i = 0, j = 0;
while (i < sLen&& j < tLen)
{
if (s[i] == t[j])
{
++i;
++j;
}
else
++j;
}
if (i == sLen)
return true;
return false;
}
};
665. Non-decreasing Array
在出现nums[i] < nums[i - 1]时,需要考虑的是应该修改数组的哪个数,使得本次修改能使i之前的数组成为非递减数组,并且不影响后续的操作。优先考虑令 nums[i - 1] = nums[i],因为如果修改 nums[i] = nums[i - 1] 的话,那么 nums[i] 这个数会变大,就有可能比 nums[i + 1] 大,从而影响了后续操作。还有一个比较特别的情况就是nums[i] < nums[i - 2],只修改 nums[i - 1] = nums[i] 不能使数组成为非递减数组,只能修改 nums[i] = nums[i -1]。
class Solution {
public:
bool checkPossibility(vector& nums) {
int n = nums.size();
int cnt = 0;
for (int i = 1; i < nums.size() && cnt < 2; ++i)
{
if (nums[i] >= nums[i - 1])
continue;
++cnt;
if (i - 2 >= 0 && nums[i - 2] > nums[i])
nums[i] = nums[i - 1];
else
nums[i - 1] = nums[i];
}
return cnt <= 1;
}
};