贪心贪心 我们喜欢你
贪心
局部最优推全局最优
贪心没有什么套路,就是要多练啊啊啊
了解相关场景和题型
1.分发饼干 455. 分发饼干 - 力扣(LeetCode)
java
class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int i=0;
for(int sNum:s)
{
//依次喂饱胃口小的
if(i<g.length&&g[i]<=sNum)
{
i++;
}
}
return i;
}
}
2.摆动序列 376. 摆动序列 - 力扣(LeetCode)
//就是找峰值 找到局部最大值和局部最小值
java
class Solution {
public int wiggleMaxLength(int[] nums) {
if(nums.length<=1)
return nums.length;
int count=1;//记录初始长度
Boolean flag=null;
for(int j=1;j<nums.length;j++)
{
int cur=nums[j]-nums[j-1];
if(cur==0)
{
continue;
}
boolean curDiff=cur>0;
if(flag==null||flag!=curDiff)
{
count++;
}
flag=curDiff;
}
return count;
}
}
3.最大子序和 53. 最大子数组和 - 力扣(LeetCode)
当当前的数大于之前的值的时候就重新开始
java
class Solution {
public int maxSubArray(int[] nums) {
// 初始值:将ans和cur都设为数组第一个元素(避免全负数场景错误)
int ans = nums[0];
int cur = nums[0];
// 从第二个元素开始遍历
for (int i = 1; i < nums.length; i++) {
int num = nums[i];
// 核心逻辑:cur选择「只取当前数」或「当前数+之前累加和」的较大值
// 这一步保证cur始终是「以当前元素结尾的最大子数组和」
cur = Math.max(num, cur + num);
// 更新全局最大和
ans = Math.max(ans, cur);
}
return ans;
}
}
4.买卖股票最佳时机 122. 买卖股票的最佳时机 II - 力扣(LeetCode)
java
class Solution {
public int maxProfit(int[] prices) {
//算出和前一天利润的差 因为隔两天的利润就相当于差值相加
//所以我们要求的就是收集正利润 得到最好的收益
int[] profits=new int[prices.length];
for(int i=1;i<prices.length;i++)
{
profits[i-1]=prices[i]-prices[i-1];
}
int ans=0;
for(int profit:profits)
{
if(profit>0)
{
ans+=profit;
}
}
return ans;
}
}
5.跳跃游戏 55. 跳跃游戏 - 力扣(LeetCode)
java
class Solution {
public boolean canJump(int[] nums) {
//就是看往后的覆盖范围能到哪 然后覆盖范围里有没有到最终结果的
int j=0;
int i=0;
while(i<=j)
{
j=Math.max(i+nums[i],j);
if(j>=nums.length-1)
{
return true;
}
i++;
}
return false;
}
}
6.跳跃游戏Ⅱ 45. 跳跃游戏 II - 力扣(LeetCode)
java
class Solution {
public int jump(int[] nums) {
int n = nums.length;
if (n < 2) return 0; // 边界:无需跳跃
int steps = 0; // 最小步数
int currentEnd = 0; // 当前步数能到达的最远边界
int maxReach = 0; // 遍历过程中能到达的最远位置
// 遍历到倒数第二个元素即可(到最后一个就不用跳了)
for (int i = 0; i < n - 1; i++) {
maxReach = Math.max(maxReach, i + nums[i]); // 更新最远可达位置
// 到达当前步数的边界,需要跳一步,更新边界
if (i == currentEnd) {
steps++;
currentEnd = maxReach;
// 提前终止:当前能到末尾,无需继续遍历
if (currentEnd >= n - 1) break;
}
}
return steps;
}
}
7.K次数取反后最大化的数组和 1005. K 次取反后最大化的数组和 - 力扣(LeetCode)
java
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
//先让负的全部变成正的 再排序 让最小的进行变号
Arrays.sort(nums);
for(int i=0;i<nums.length&&nums[i]<0&&k>0;i++)
{
nums[i]=-nums[i];
k--;
}
Arrays.sort(nums);
if(k%2!=0)
{
nums[0]=-nums[0];
}
int ans=0;
for(int num:nums)
{
ans+=num;
}
return ans;
}
}
8.加油站 134. 加油站 - 力扣(LeetCode)
java
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
//只要总油量大于等于总消耗 那必然存在一条合理路线
int n=gas.length;
int cur=0;
int total=0;
int start=0;
for(int i=0;i<n;i++)
{
int diff=gas[i]-cost[i];
total+=diff;
cur+=diff;
//小于0 则换位置
if(cur<0)
{
start=i+1;
cur=0;
}
}
return total>=0?start:-1;
}
}
9.分发糖果
10.柠檬水找零 860. 柠檬水找零 - 力扣(LeetCode)
java
class Solution {
public boolean lemonadeChange(int[] bills) {
//每次都尽可能地找大的零钱
int[] amount=new int[2];//分别代表5,10
for(int bill:bills)
{
if(bill==5)//无需找钱
{
amount[0]++;
}
else
{
//看有没有5块
if(amount[0]<1)
{
return false;
}
amount[0]--;
if(bill==10)
{
amount[1]++;
}
else if(bill==20)
{
if(amount[1]>0)
{
amount[1]--;
}
else
{
if(amount[0]>=2)
{
amount[0]-=2;
}
else
{
return false;
}
}
}
}
}
return true;
}
}
11.根据身高重建队列 406. 根据身高重建队列 - 力扣(LeetCode)
java
class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people, new Comparator<int[]>(){
public int compare(int[] person1, int[] person2){
if(person1[0]!=person2[0]){
return person1[0] - person2[0];
}
else
{
return person2[1]-person1[1];
}
}
});
int n = people.length;
int[][] ans = new int[n][];
for(int[] person:people){
int spaces=person[1]+1;
for(int i=0;i<n;i++){
if(ans[i]==null){
--spaces;
if(spaces==0){
ans[i]=person;
break;
}
}
}
}
return ans;
}
}