贪心算法
455. 分发饼干
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
我的思路是小饼干优先满足小胃口,还有一种是大饼干优先满足大胃口。
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int child = 0;
int cookie = 0;
while (child < g.size() && cookie < s.size()) {
if (g[child] <= s[cookie]) {
child++;
cookie++;
} else {
cookie++;
}
}
return child;
}
};
376. 摆动序 列
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.empty()) {
return 0;
}
if (nums.size() == 1) {
return 1;
}
bool hasDiff = false;
int last = 0; // -1 0 1
int length = 1;
for (int i = 1; i < nums.size(); i++) {
int currDiff = nums[i] - nums[i - 1];
if (!hasDiff && currDiff != 0) {
hasDiff = true;
}
int curr = currDiff == 0 ? 0 :
(currDiff > 0 ? 1 : -1);
if (curr != 0 && curr != last) {
length++;
}
last = curr != 0 ? curr : last;
}
return length;
}
};
53. 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
试着用了 DP,貌似还有 的解法?
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> sums(nums.size(), 0);
sums[0] = nums[0];
int maxSum = nums[0];
for (int i = 1; i < nums.size(); i++) {
sums[i] = max(sums[i - 1] + nums[i], nums[i]);
if (sums[i] > maxSum) {
maxSum = sums[i];
}
}
return maxSum;
}
};
122. 买卖股票的最佳时机 II
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
好多事情,暂时先用 DP 糊了
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<pair<int, int>> dp(prices.size());
dp[0] = {0, -prices[0]};
for (int i = 1; i < prices.size(); i++) {
dp[i].second = max(dp[i - 1].second, dp[i - 1].first - prices[i]);
dp[i].first = max(dp[i - 1].first, dp[i - 1].second + prices[i]);
}
return max(dp[prices.size() - 1].first, dp[prices.size() - 1].second);
}
};
55. 跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
我想的是从后往前数,时间复杂度应该是 ,还可以用覆盖范围
class Solution {
public:
bool canJump(vector<int>& nums) {
bool result = true;
int i = nums.size() - 2;
while (i >= 0) {
if (nums[i] == 0) {
result = false;
int j = i - 1;
while (j >= 0) {
if (nums[j] > i - j) {
result = true;
i = j;
break;
}
j--;
}
if (!result) {
return false;
}
}
i--;
}
return result;
}
};
45. 跳跃游戏 II
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使 用最少的跳跃次数到达数组的最后一个位置。
class Solution {
public:
int jump(vector<int>& nums) {
int currIndex = 0;
int range = 0;
int ans = 0;
for (int i = 0; i < nums.size() - 1; i++) {
range = max(range, i + nums[i]);
if (i == currIndex) {
currIndex = range;
ans++;
}
}
return ans;
}
};
1005. K 次取反后最大化的数组和
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i]
替换为 -A[i]
,然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)
以这种方式修改数组后,返回数组可能的最大和。
温习了一下 Lamda 应该怎么写
class Solution {
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(), nums.end(), [](int a, int b){return a < b;});
int minAbs = INT_MAX;
int ans = 0;
for (int i = 0; i < nums.size(); i++) {
minAbs = min(minAbs, abs(nums[i]));
if (k > 0 && nums[i] < 0) {
ans += -nums[i];
k--;
} else {
ans += nums[i];
}
}
if (k % 2 != 0) {
ans -= 2 * minAbs;
}
return ans;
}
};