贪心 -力扣860.柠檬水找零力扣2208.将数组和减半的最少操作次数力扣179.最大数力扣376.摆动序列

本文主要是介绍贪心 -力扣860.柠檬水找零力扣2208.将数组和减半的最少操作次数力扣179.最大数力扣376.摆动序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

目录

力扣860.柠檬水找零

力扣2208.将数组和减半的最少操作次数

力扣179.最大数

力扣376.摆动序列


贪心策略,局部最优->全局最优

1.把解决问题的过程分为若干步骤

2.解决每一步的时候,都选择当前看起来“最优秀的”解法

3.希望能够得到全局最优解

例子1:找零问题 50-4=46  ->[20,10,5,1] 46->26->6->5->1   找当前能够找到的最大解法。

例子2:最小路径和(当初动态规划)

每次只能向下,或者向右侧,找到最小的路径,                                                                              11611,这个不一定对,但是符合贪心的策略,鼠目寸光

例子三:背包问题

疯狂装体积小的,直接塞满(只去考虑体积,考虑价值,则去疯狂交给价值)

1.贪心策略的特点:

1.贪心策略的提出是没有标准和模版的

2.可能每一道贪心策略都是不同的

2.贪心策略的正确性

贪心策略可能是一个错误的方法,正确的贪心,是需要一个证明的

常用的证明方法:数学中见过的所有方法

找零问题:【20,10,5,1】

力扣860.柠檬水找零

class Solution {public boolean lemonadeChange(int[] bills) {
if(bills[0]>5){return false;
}
//找钱也就是15块和5块
int five=0;int ten=0;
for(int i=0;i<bills.length;i++){if(bills[i]==5){five++;}else if(bills[i]==10){ten++;five--;}else if(bills[i]==20){if(ten>0){ten--;five--;}else{five=five-3;}}if(five<0||ten<0){return false;
}}return true;}
}

力扣2208.将数组和减半的最少操作次数

class Solution {//贪心,每次都去挑选数组中最大的数,然后减半,知道数组和到原来的一半public int halveArray(int[] nums) {int count=0;//每次都挑选最大的数,借助一个数据结构(大根堆)
//拿到堆顶,然后再去/2放到大根堆里面PriorityQueue <Double>priorityQueue=new PriorityQueue<>((a,b)->b.compareTo(a));double sum=0;for(double num:nums){priorityQueue.add(num);sum+=num;}sum=sum/2.0;
while(sum>0){double p=priorityQueue.poll()/2.0;count++;sum=sum-p;priorityQueue.add(p);
}
return count;}
}

力扣179.最大数

正常的排序:确定元素的先后顺序:谁在前面,谁在后面

a和b是同一数量级,比如 8,9 或者10,11或者34, 36。我的意思是,两位数和两位数比,一位数和一位数比

a和b不是统一数量级,假如位数不一样,那么就依次循环,来确定首尾

谈谈这块,首先这个sort的使用比较器的方法,只适用于包装类的逆序,并不适用于基础类型

      Integer []nums={1,2,3,4};//排序Arrays.sort(nums,Comparator.reverseOrder());for(int x:nums){System.out.println(x);}

在Java中,当你尝试对字符串数组使用Lambda表达式进行排序,并且使用(b+a).compareTo(a+b)作为比较逻辑时,b+a和a+b在大多数情况下看起来可能相同,因为它们都是将两个字符串拼接起来。但是,这里的关键在于这两个表达式在特定的字符串上可能会产生不同的结果,特别是当涉及到字符串连接时的数值解释时。

考虑以下情况:

当a和b都是数字字符串时(例如a="12",b="3"),b+a和a+b拼接后的字符串在数值上可能不同,但它们在字典顺序上可能是相同的。例如,"312"和"123"作为字符串在字典顺序上是不同的。
当a和b中包含非数字字符时,拼接后的结果将完全基于字符串的字典顺序,而不是任何潜在的数值解释。

现在,让我们详细分析(b+a).compareTo(a+b)的比较逻辑:

如果b+a在字典顺序上位于a+b之前,则compareTo方法将返回一个负数,表示b应该在a之前。
如果b+a和a+b在字典顺序上相同,则compareTo方法将返回0,表示a和b的位置不变。
如果b+a在字典顺序上位于a+b之后,则compareTo方法将返回一个正数,表示b应该在a之后。

这种比较逻辑在某些特定情况下可能看起来有些奇怪,特别是当处理数字字符串时。通常,如果你想要按照数值对数字字符串进行排序,你应该先将它们转换为数值类型(如Integer或Long),然后再进行比较。

然而,在你提供的例子中,这种比较逻辑可能用于创建一种特定的排序顺序,该顺序可能基于字符串的某种非直观或特殊的比较逻辑。

最后,值得注意的是,对于非数字字符串,这种比较逻辑可能不会产生有意义的结果,因为字符串的字典顺序和它们的任何潜在数值解释之间可能没有直接关系。

其实不用记住顺序,尝试一遍不就好咯。

class Solution {public String largestNumber(int[] nums) {int n=nums.length;String[] strs=new String[n];for(int i=0;i<n;i++) strs[i]=""+nums[i];//排序Arrays.sort(strs,(a,b)->{return (b+a).compareTo(a+b);});
//提取结果
StringBuffer ret=new StringBuffer();
for(String s:strs) ret.append(s);
if(ret.charAt(0)=='0')return "0";
return ret.toString();}
}

只有符合全序关系,才能说明贪心正确。

证明 ab,ba两个拼接起来都是数,能够比较大小,就算是字符串也是可以比较ac码,所以可以视为数字。

力扣376.摆动序列

class Solution {public  static int wiggleMaxLength(int[] nums) {int n=nums.length;if(n<2){return n;}int left=0;int ret=0;int right=0;for(int i=0;i<n-1;i++){right=nums[i+1]-nums[i];if(right==0){continue;}//y要么是波峰, 要么是波谷//第一个点也考虑进去,注意等于0的情况是第一个点,假如第一个点不是0,那么left*right也不会等于0,因为假如right=0,那么就会跳过了if(left*right<=0){ret++;}left=right;}return ret+1;}}

这篇关于贪心 -力扣860.柠檬水找零力扣2208.将数组和减半的最少操作次数力扣179.最大数力扣376.摆动序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/989790

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

usaco 1.3 Barn Repair(贪心)

思路:用上M块木板时有 M-1 个间隙。目标是让总间隙最大。将相邻两个有牛的牛棚之间间隔的牛棚数排序,选取最大的M-1个作为间隙,其余地方用木板盖住。 做法: 1.若,板(M) 的数目大于或等于 牛棚中有牛的数目(C),则 目测 给每个牛牛发一个板就为最小的需求~ 2.否则,先对 牛牛们的门牌号排序,然后 用一个数组 blank[ ] 记录两门牌号之间的距离,然后 用数组 an

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

POJ2010 贪心优先队列

c头牛,需要选n头(奇数);学校总共有f的资金, 每头牛分数score和学费cost,问合法招生方案中,中间分数(即排名第(n+1)/2)最高的是多少。 n头牛按照先score后cost从小到大排序; 枚举中间score的牛,  预处理左边与右边的最小花费和。 预处理直接优先队列贪心 public class Main {public static voi

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

ural 1820. Ural Steaks 贪心

1820. Ural Steaks Time limit: 0.5 second Memory limit: 64 MB After the personal contest, happy but hungry programmers dropped into the restaurant “Ural Steaks” and ordered  n specialty steaks