目录
1005.K次取反后最大化的数组和
题目链接:1005. K 次取反后最大化的数组和
题目描述:
给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:
选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
重复这个过程恰好 k 次。可以多次选择同一个下标 i 。
以这种方式修改数组后,返回数组 可能的最大和 。
很容易想到对数组先进行排序,优先翻转负数,之后根据剩下的翻转次数决定是否再进行翻转。
简单的对数组进行升序排列
如果简单的对数组进行升序排列,其它都还好,但是对于最后翻转哪一个元素的判断要考虑的很多。比如下面例子:
-8 -5 -5 -3 -2 3 (k=6)
翻转: 8 5 5 3 2
k: 5 4 3 2 1
此时k=1需要翻转,为了使和最大应该再翻转一次-2。
-2 1 2 3 (k=4)
翻转: 2
k: 3
此时k=3需要翻转,为了使和最大应该翻转的是1,而不是-2。
通过对数组进行简单的升序排列,在这个地方要考虑:
- 翻转还是不翻转
- 翻转第一个整数还是最大的负数
- 如果整个数组全是正数,没有负数们还要与2.相区分
要做的判断就太多了,有一种面向测试用例编程的感觉。
对数组的绝对值进行降序排列
-8 3 -5 -3 -5 -2 (k=6)
排序后 -8 -5 -5 -3 3 -2
同样优先将负数翻转,随后反转的必定是排序后的最后一个元素,也就是绝对值最小的元素,只需要判断是否翻转。
int cmp_int(const int* e1,const int* e2){
return abs(*(int*)e2)-abs(*(int*)e1);
}
int largestSumAfterKNegations(int* nums, int numsSize, int k){
//将数组按绝对值大小降序排列
qsort(nums,numsSize,sizeof(int),cmp_int);
int ret=0;
for(int i=0;i<numsSize;i++){
if(k>0&&nums[i]<0){
nums[i]*=-1;
k--;
}
}
//反转绝对值最小的元素
if(k>0&&k%2==1){
nums[numsSize-1]*=-1;
}
for(int i=0;i<numsSize;i++){
ret+=nums[i];
}
return ret;
}
134. 加油站(×)
题目链接:134. 加油站
题目描述:
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
重新做的时候搞不懂逻辑就画画图!我自己肯定是想不到这样子做。
我觉得挺难理解的,Cral讲解视频:贪心算法,得这么加油才能跑完全程!LeetCode :134.加油站_哔哩哔哩_bilibili
int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize){
//转一圈的剩余油量
int total_gas=0;
//记录当前油量
int cur_gas=0;
int ret=0;
//如果总的消耗大于总共获取的油量,一定不能转一圈
for(int i=0;i<gasSize;i++){
total_gas+=gas[i]-cost[i];
}
if(total_gas<0) return -1;
}
//只要能走完一圈,肯定有合适的路线
for(int i=0;i<gasSize;i++){
//每走一段当前油量+获得和消耗的差值
cur_gas+=gas[i]-cost[i];
//当前油量<0说明从从前面的站点到这个地方都行不通
if(cur_gas<0){
//从下个站点开始
ret=i+1;
//开始时油箱为0
cur_gas=0;
}
}
return ret;
}
135. 分发糖果 (困难,没有加油站困难)
题目链接:135. 分发糖果
题目描述:
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
这个是困难题!比加油站好理解得多啊!!!
左右遍历一遍各取最大值!
int candy(int* ratings, int ratingsSize){
if(ratingsSize==1) return 1;
int* List=(int*)malloc(sizeof(int)*ratingsSize);
//判断左<右
List[0]=1;
for(int i=1;i<ratingsSize;i++){
if(ratings[i]>ratings[i-1]){
List[i]=List[i-1]+1;
}else{
List[i]=1;
}
}
//判断左>右
List[ratingsSize-1]=fmax(1,List[ratingsSize-1]);
int ret=List[ratingsSize-1];
for(int i=ratingsSize-2;i>=0;i--){
int num;
if(ratings[i]>ratings[i+1]){
num=List[i+1]+1;
}else{
num=1;
}
List[i]=fmax(num,List[i]);
ret+=List[i];
}
return ret;
}