- 1005.K次取反后最大化的数组和
- 按照一定的策略,先绝对值排序,再负数修正,最后对绝对值最小的数进行替换,再求和
- 134. 加油站
- 判断是否可以从i 到达i + 1
- 判断gas总量是否大于cost
- 135. 分发糖果
- 采用两次遍历计算糖果数
package algor.trainingcamp;
import java.util.Arrays;
import java.util.stream.IntStream;
/**
* @author lizhe
* @version 1.0
* @description: k次取反后的最大值
* @date 2023/5/8 07:44
*
* 1. 先按照绝对值进行从大到小排序
* 2. 从前到后遍历 如果发现有负数,优先变成正数
* 3. 如果k还没有用完 变换最后一个数,再求和
*/
public class LeetCode1005 {
public int largestSumAfterKNegations(int[] nums, int k) {
// 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
nums = IntStream.of(nums)
.boxed()
.sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
.mapToInt(Integer::intValue).toArray();
for(int i = 0;i < nums.length;i++){
if(nums[i] < 0 && k > 0){
k--;
nums[i] = -nums[i];
}
}
while(k > 0){
k--;
nums[nums.length - 1] = -nums[nums.length - 1];
}
return Arrays.stream(nums).sum();
}
}
package algor.trainingcamp;
/**
* @author lizhe
* @version 1.0
* @description:
*
* 在一条环路上有 n个加油站,其中第 i个加油站有汽油gas[i]升。
*
* 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1个加油站需要消耗汽油cost[i]升。
* 你从其中的一个加油站出发,开始时油箱为空。
*
* 给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/gas-station
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*
* @date 2023/5/8 07:53
*
* 车从i站能开到i+1。
* 所有站里的油总量要>=车子的总耗油量。
*/
public class LeetCode134 {
public int canCompleteCircuit(int[] gas, int[] cost) {
int cur = 0;
int startIdx = 0;
int total = 0;
for(int i = 0;i < gas.length;i++){
//判断: 车从i站能开到i+1
cur += gas[i] - cost[i];
//判断: 所有站里的油总量要>=车子的总耗油量。
total += gas[i] - cost[i];
//重新开始
if(cur < 0){
startIdx = i + 1;
cur = 0;
}
}
return total < 0 ? - 1 : startIdx;
}
}
package algor.trainingcamp;
/**
* @author lizhe
* @version 1.0
* @description: TODO
* @date 2023/5/8 08:06
*
* 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
*
* 你需要按照以下要求,帮助老师给这些孩子分发糖果:
*
* 每个孩子至少分配到 1 个糖果。
* 相邻的孩子中,评分高的孩子必须获得更多的糖果。
* 那么这样下来,老师至少需要准备多少颗糖果呢?
*
* 1. 如果前一位比后一位分数高,则糖果 + 1
*/
public class LeetCode135 {
class Solution {
public int candy(int[] ratings) {
if(ratings == null || ratings.length == 0){
return 0;
}
int[] nums = new int[ratings.length];//记录每一位孩子得到的糖果数
nums[0] = 1;
//先正序遍历,如果后一位比前一位高分,就给比前一位多1的糖果,否则给1
for(int i = 1; i < ratings.length; i++){
if(ratings[i] > ratings[i-1]){
nums[i] = nums[i-1] + 1;
}else {
nums[i] = 1;
}
}
//在倒叙遍历,如果前一位比后一位高分并且得到的糖果小于或等于后一位,就给前一位孩子比后一位孩子多一个糖果
for(int i = ratings.length -2 ; i >= 0; i--){
if(ratings[i] > ratings[i+1] && nums[i] <= nums[i+1]){
nums[i] = nums[i+1] +1;
}
}
int count = 0;
for(int i : nums){
count +=i;
}
return count;
}
}
}