贪心
455. Assign Cookies (Easy)
分配饼干:每个孩子都有一个满足度 grid,每个饼干都有一个大小 size,只有饼干的大小大于等于一个孩子的满足度,该孩子才会获得满足。求解最多可以获得满足的孩子数量。
- 给一个孩子的饼干应当尽量小并且又能满足该孩子,这样大饼干才能拿来给满足度比较大的孩子。
- 因为满足度最小的孩子最容易得到满足,所以先满足满足度最小的孩子。
435. Non-overlapping Intervals (Medium)
计算让一组区间不重叠所需要移除的区间个数。
每次选择结尾最小,并且和前一个区间不重叠的区间。
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0)
return 0;
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
int cnt = 1;
int end = intervals[0][1];
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] < end)
continue;
end = intervals[i][1];
cnt++;
}
return intervals.length - cnt;
}
}
尤其记一下这个comparator的写法
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
452. Minimum Number of Arrows to Burst Balloons (Medium)
和上一题没什么区别
class Solution {
public int findMinArrowShots(int[][] points) {
int length = points.length;
if (length == 0)
return 0;
Arrays.sort(points, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
int cnt = 1;
int end = points[0][1];
for (int i = 1; i < length; i++) {
if (points[i][0] <= end)
continue;
end = points[i][1];
cnt++;
}
return cnt;
}
}
406. Queue Reconstruction by Height(Medium)
官方题解讲的超级好
因为个子矮的人相对于个子高的人是 “看不见” 的,所以可以先安排个子高的人。
所以首先身高降序排
相同身高的人再按照k升序排
在排序好的这些人中,从前往后(也就是从高到低)往另一个数组里加,把人放在自己下标所在的位置即可(因为比自己矮的人看不见,比自己高的人已经放好了,和自己一样高的人下标比自己小也已经放好了)
(感觉有点只可意会不可言传怎么回事)
class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0];
}
});
List<int[]> output = new LinkedList<>();
for(int[] p : people){
output.add(p[1], p);
}
int n = people.length;
return output.toArray(new int[n][2]);
}
}
121.Best Time to Buy and Sell Stock (Easy)
买卖股票最大的收益
有n天,有每一天股票的价格,问怎么买能使得最后的利润最大
用一个min来记录当前出现的最低价格,然后今天的价格-min就是今天买入的利润,选出最大的利润即可
class Solution {
public int maxProfit(int[] prices) {
int length = prices.length;
if (length == 0)
return 0;
int min = Integer.MAX_VALUE;
int ans = -1;
for (int i : prices) {
min = Math.min(min, i);
ans = Math.max(ans, i - min);
}
return ans;
}
}
122. Best Time to Buy and Sell Stock II (Easy)
在上一题的基础上,可以进行多笔交易
至今还是不明白为什么这样可以得到最优解👇
class Solution {
public int maxProfit(int[] prices) {
int length = prices.length;
if (length == 0)
return 0;
int ans = 0;
for (int i = 1; i < length; i++) {
if (prices[i] > prices[i - 1])
ans += prices[i] - prices[i - 1];
}
return ans;
}
}
605. Can Place Flowers (Easy)
flowerbed 数组中 1 表示已经种下了花朵。花朵之间至少需要一个单位的间隔,求解是否能种下 n 朵花。
从前往后扫即可,注意各种边界情况
class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int length = flowerbed.length;
int cnt = 0;
if (length == 0)
return false;
for (int i = 0; i < length; i++) {
if (flowerbed[i] == 0) {
if (length == 1 && flowerbed[i] == 0)
cnt++;
else if (i == 0 && i + 1 < length && flowerbed[i + 1] == 0)
cnt++;
else if (i == length - 1 && i - 1 > 0 && flowerbed[i - 1] == 0)
cnt++;
else if (i - 1 > 0 && flowerbed[i - 1] == 0 && i + 1 < length && flowerbed[i + 1] == 0) {
flowerbed[i] = 1;
cnt++;
}
}
}
return cnt >= n;
}
}
392. Is Subsequence (Medium)
判断是不是子序列
用 Java自带的indexof方法即可
public boolean isSubsequence(String s, String t) {
int index = -1;
for (char c : s.toCharArray()) {
index = t.indexOf(c, index + 1);
if (index == -1) {
return false;
}
}
return true;
}
665.Non-decreasing Array (Easy)
修改一个数使数组成为非递减数
判断nums[i]和nums[i-1]的大小关系
-
nums[i] >= nums[i-1] : continue
-
nums[i] < nums[i-1]
此时是需要修改一个值使得nums[i] >= nums[i-1]
问题是令nums[i] = nums[i-1]. 还是 令 nums[i-1] = nums[i]
两种情况:
-
nums[i] >= nums[i-2],如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SBHVkk5H-1580452605907)(/Users/dylan/Library/Application Support/typora-user-images/image-20200131134903167.png)]
此时修改nums[i-1] = nums[i],如下图
这样不会对后续的数字有影响,如果把nums[i]改大了,有可能比后面的数还要大,所以修改nums[i-1][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pG4qv86t-1580452605909)(/Users/dylan/Library/Application Support/typora-user-images/image-20200131135007603.png)]
-
如果nums[i] < nums[i-2],如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3EyAKldV-1580452605910)(/Users/dylan/Library/Application Support/typora-user-images/image-20200131135238680.png)]
就修改nums[i] = nums[i-1]:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avCsPISF-1580452605911)(/Users/dylan/Library/Application Support/typora-user-images/image-20200131135459434.png)]
-
代码:
class Solution {
public boolean checkPossibility(int[] nums) {
int length = nums.length;
int cnt = 0;
for (int i = 1; i < length && cnt < 2; i++) {
if (nums[i] >= nums[i - 1])
continue;
cnt++;
if (i - 2 >= 0 && nums[i] < nums[i - 2]) {
nums[i] = nums[i - 1];
} else {
nums[i - 1] = nums[i];
}
}
return cnt <= 1;
}
}
53. Maximum Subarray (Easy)
子数组最大的和
我用dp做的没用贪心(小声
class Solution {
public int maxSubArray(int[] nums) {
int length = nums.length;
if (length == 0)
return 0;
int[] dp = new int[length];
dp[0] = nums[0];
int max = nums[0];
for (int i = 1; i < length; i++) {
dp[i] = dp[i - 1] > 0 ? dp[i - 1] + nums[i] : nums[i];
max = Math.max(max, dp[i]);
}
return max;
}
}
763. Partition Labels (Medium)
字符串 S
由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。
首先记录每一个字母出现的最后位置
d e g d e h i g j
字母 | d | e | g | d | e | h | i | g | j | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
字母 | d | e | g | i | j | h |
---|---|---|---|---|---|---|
最后出现的位置 | 3 | 4 | 7 | 6 | 8 | 5 |
遍历的时候不断更新当前段字母出现的最后位置,这个最后的位置就是这个段的结束位置
遍历到的字母 | 下标 | 最后出现的位置 | 当前段的下标 | 下标==当前段的下标? |
---|---|---|---|---|
未开始 | - | - | 0 | |
d | 0 | 3 | 3 | |
e | 1 | 4 | 4 | |
g | 2 | 7 | 7 | |
d | 3 | 3 | 7 | |
e | 4 | 4 | 7 | |
h | 5 | 5 | 7 | |
i | 6 | 6 | 7 | |
g | 7 | 7 | 7 | 嗯! |
(差不多就是这么个意思,列表好麻烦就酱了)
代码:
class Solution {
public List<Integer> partitionLabels(String string) {
int length = string.length();
List<Integer> list = new ArrayList<>();
if (length == 0)
return list;
int[] right = new int[26];
for (int i = 0; i < length; i++) {
right[string.charAt(i) - 'a'] = i;
}
int max = 0;
int lastIndex = 0;
for (int i = 0; i < length; i++) {
max = Math.max(max, right[string.charAt(i) - 'a']);
if (i == max) {
list.add(i - lastIndex + 1);
lastIndex = i + 1;
}
}
return list;
}
}