在柠檬水摊上,每一杯柠檬水的售价为 5
美元。顾客排队购买你的产品,(按账单 bills
支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5
美元、10
美元或 20
美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5
美元。
注意,一开始你手头没有任何零钱。
给你一个整数数组 bills
,其中 bills[i]
是第 i
位顾客付的账。如果你能给每位顾客正确找零,返回 true
,否则返回 false
。
贪心思路:感觉也不算是贪心,就是常识,由于顾客只会支付 5元,10元,20元三种,于是我们可以分别用 five,ten来统计五元和十元的数量,然后根据用户的给钱成功找零即可
class Solution {
public boolean lemonadeChange(int[] bills) {
int ten=0;
int five=0;
for(int money:bills){
if(money==5) {
five++;
}else if(money==10){
if(five>0) {
five--;
ten++;
}else{
return false;
}
}else {
if(five>0&&ten>0){
ten--;
five--;
}else if(five>=3){
five-=3;
}else {
return false;
}
}
}
return true;
}
}
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points
,其中points[i] = [xstart, xend]
表示水平直径在 xstart
和 xend
之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x
处射出一支箭,若有一个气球的直径的开始和结束坐标为 x
start
,x
end
, 且满足 xstart ≤ x ≤ x
end
,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points
,返回引爆所有气球所必须射出的 最小 弓箭数 。
给定一个区间的集合 intervals
,其中 intervals[i] = [starti, endi]
。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区
贪心思路:个人感觉这三道题的思路是一致的,本质上来说都需要求解的都是是公用的区间,我们需要先让数组根据左边区间或者右边区间进行排序,完成之后在使用循环便利判断公共区间,就是用第二期个区间的左边界和第一个区间的右边界比较即可,有公共区间则需要更新右边界的值,最后统计即可。
个人总结模版代码:
//将数组按照左区间进行排序
Arrays.sort(arr,(a,b)->Integer.compare(a[0],b[0]);
//遍历数组记录重合区间
for(int i=1;i<len;i++){
if(arr[i][0]>arr[i-1][1]){
//说明两个区间不重合,
}else{
//说明两个区间重合所以需要更新左右边界的值,方便下一次比较
arr[i][1]=Math.min(arr[i][1],arr[i-1][1]);
}
}
return **;
给你一个字符串 s
。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s
。
返回一个表示每个字符串片段的长度的列表。
第一次看题目对他的意思不是很理解,先分析一下题目意思
s = "ababcbacadefegdehijhklij"
例如上述字符串,假如从第一个遍历,第一个是a,那么你需要保证a只能出现在一个片段中,直白得奖就是除了划分含有a的区间之外其他区间不能右a,也就是区间长度要达到a出现的最远位置,也及时这个题目中的8,同理继续便利到b,不也是一样的道理,只不过他比a小,于是我们取a,循环往复即可。
说到这里之后,其实题目意思明白了,就很好求解,首先记录所有出现的字母最远的位置,一个for循环使用hash表就可以搞定,数组索引就是当前字母减去'a'。之后对字符数组进行遍历使用一个索引初始值为0-记录划分字符串的最有区间,每一次便利后和当前字母最远位置比较更新索引,当遍历到索引位置时,将切割的字符串加入结果集之中,重复上述操作即可。
class Solution {
public List<Integer> partitionLabels(String s) {
//先记录所有字母 的最远位置
int[] maxindex=new int[26];
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
maxindex[ch-'a']=i;
}
//使用right记录字幕的 最大右区间
int right=0;
//统计最终的结果
List<Integer> res=new ArrayList<>();
int count=0;
for(int i=0;i<s.length();i++){
right=Math.max(right,maxindex[s.charAt(i)-'a']);
count++;
if(i==right){
res.add(count);
count=0;
}
//count++;
}
return res;
}
}
By-三体直线围墙