K 次取反后最大化的数组和
给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:
选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
重复这个过程恰好 k 次。可以多次选择同一个下标 i 。
以这种方式修改数组后,返回数组 可能的最大和 。
示例 1:
输入:nums = [4,2,3], k = 1
输出:5
解释:选择下标 1 ,nums 变为 [4,-2,3] 。
示例 2:
输入:nums = [3,-1,0,2], k = 3
输出:6
解释:选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2] 。
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
int sum = 0;
int index = 0;
Arrays.sort(nums);
for (int i = 0; i < k; i++){
if(i < nums.length - 1 && nums[index] < 0){
nums[index] = -nums[index];
if(nums[index] >= Math.abs(nums[index + 1])){
index++;
}
continue;
}
nums[index] = -nums[index];
}
for(int i = 0; i < nums.length; i++){
sum += nums[i];
}
return sum;
}
}
45. 跳跃游戏 II
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
class Solution {
public int jump(int[] nums) {
if (nums.length == 1) {
return 0;
}
int cover = 0;
int cur = 0; // 当前范围
int step = 0;
for(int i = 0; i < nums.length; i++){
cover = Math.max(cover, i + nums[i]);
// 到达数组尾
if(cover >= nums.length - 1){
step++;
break;
}
if(i == cur){
cur = cover;
step++;
}
}
return step;
}
}
134. 加油站
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
示例 1:
输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int cur = 0; // 当前花销
int count = 0; // 总花销
int idx = 0; // 出发点
for(int i = 0; i < gas.length; i++){
cur += gas[i] - cost[i];
count += gas[i] - cost[i];
if(cur < 0){
cur = 0;
idx = i + 1; // 更新出发点
}
}
if(count < 0) return -1;
return idx;
}
}
860. 柠檬水找零
在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
示例 1:
输入:bills = [5,5,5,10,20]
输出:true
class Solution {
public boolean lemonadeChange(int[] bills) {
if(bills[0] > 5) return false;
int diff = 0;
int five = 0;
int ten = 0;
for(int i = 0; i < bills.length; i++){
if(bills[i] == 5){
five++;
}
if(bills[i] == 10){
ten++;
five--;
}
if(bills[i] == 20){
if(ten == 0){
five -= 3;
}else{
ten--;
five--;
}
}
if(ten < 0 || five < 0){
return false;
}
}
return true;
}
}
根据身高重建队列
假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。
请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。
示例 1:
输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people, (a, b) -> {
if(a[0] == b[0]) return a[1] - b[1];
return b[0] - a[0];
});
LinkedList<int[]> res = new LinkedList<>();
for(int[] tmp: people){
res.add(tmp[1], tmp);
}
return res.toArray(new int[people.length][]);
}
}
用最少数量的箭引爆气球
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。
示例 1:
输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。
class Solution {
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, (o1, o2) -> Integer.compare(o1[0], o2[0]));
int count = 1;
for(int i = 1; i < points.length; i++){
if(points[i][0] > points[i - 1][1]){
count++;
}else{
points[i][1] = Math.min(points[i][1], points[i - 1][1]);
}
}
return count;
}
}
无重叠区间
给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
示例 1:
输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));
int count = 0;
int pre = intervals[0][1];
for(int i = 1; i < intervals.length; i++){
if(pre > intervals[i][0]){
count++;
pre = Math.min(pre, intervals[i][1]);
}else{
pre = intervals[i][1];
}
}
return count;
}
}