leetcode--贪心2

  1. 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;
    }
}
  1. 根据身高重建队列
    假设有打乱顺序的一群人站成一个队列,数组 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][]);
    }
}
  1. 用最少数量的箭引爆气球
    有一些球形气球贴在一堵用 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;
    }
}
  1. 无重叠区间
    给定一个区间的集合 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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值