首页 > 编程语言 >Day 30 贪心算法 Part04

Day 30 贪心算法 Part04

时间:2024-08-01 15:28:38浏览次数:10  
标签:map int 30 Part04 ++ length intervals 区间 Day

452. 用最少数量的箭引爆气球

自己写没写出来,不过找到篇很好的题解,贪心想不到就是想不到,没办法。本以为自己的思路也是贪心,但就是做不出来。

class Solution {
    public int findMinArrowShots(int[][] points) {
        boolean[] visited = new boolean[points.length];
        Arrays.sort(points, (a, b)-> Integer.compare(a[1], b[1]));
        int res = 1;
        int rightMax = points[0][1];
        for(int i = 1; i < points.length; i++){
            if(points[i][0] <= rightMax) continue;
            res++;
            rightMax = points[i][1];
        }
        return res;
    }
}

435. 无重叠区间

做完上一道题再看这个就会容易许多。按照区间右端点升序排序,显然第一个区间一定是要保留的(对于右边界相等的情况,保留任意一个都可,因为结果都一样,这点可以看力扣官解贪心思路,官解这次讲的很清楚),因为没有比他更左边的区间。然后我们去找到第一个不和该区间重合的区间作为下一个可以保留的区间(由于数组按照右端点排序,一定能保证此时是最左的)。其实这种题还是画个图最直观,最好理解。

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals, (a, b)->{
            return Integer.compare(a[1], b[1]);
        });
        int res = 0;
        int right = intervals[0][1];
        for(int i = 1; i < intervals.length; i++){
            if(intervals[i][0] < right) res++;
            else right = intervals[i][1];
        }
        return res;
    }
}

56. 合并区间

做划分字母区间之间先做了这道题,因为我的划分字母区间用了这道题的思路。但这个也是看了题解才做出来。我做题总是跳脱不出之前题的套路,比如前面两道题都是用区间的右边界进行排序,这道题我也想当然的这么去做,结果就是绕死也绕不出来。但如果使用左边界排序,思路就清楚许多。

贪心贪在哪里?由于区间集合已经按照左边界进行升序排序,那么在遍历该集合时,若当前节点的左边界小于等于上一个节点的右边界,说明区间重合,因此就使用当前区间和上一个区间进行合并。当找到了第一个没有重合的集合时,说明前面的部分已经合并完成,继续迭代后面的部分即可。

class Solution {
    public int[][] merge(int[][] intervals) {
        if(intervals.length == 1) return intervals;
        Arrays.sort(intervals, (a, b)->Integer.compare(a[0], b[0]));
        int[] pre = intervals[0];
        List<int[]> listAns = new ArrayList();
        for(int i = 1; i < intervals.length;i ++){
            if(intervals[i][0] <= pre[1]) {
                pre[1] = Math.max(pre[1], intervals[i][1]);
            }
            else {
                listAns.add(pre);
                pre = intervals[i];
            }
            if(i==intervals.length-1) listAns.add(pre);
        }
        return listAns.toArray(new int[listAns.size()][]);
    }
}

763. 划分字母区间

我的思路是与上一题很相似的,比起官解来还是复杂了一些。

首先遍历字符串,得到每个字母出现的第一个和最后一个位置,也就是得到了一组区间的集合。显然这些集合间可能有重合,因此,只需要将这些区间进行合并即可,合并的思路与56. 合并区间完全一致。按照左边界进行升序排序,遇到能合并的则合并即可。

class Solution {
    public List<Integer> partitionLabels(String s) {
        List<Integer> ans = new ArrayList();
        int[][] map = new int[26][2]; 
        for(int[] t:map){
            t[0] = -1;
            t[1] = -1;
        }
        for(int i = 0; i < s.length(); i++){ //更新左右边界
            if(map[s.charAt(i)-'a'][0] == -1) map[s.charAt(i)-'a'][0] = i;
            map[s.charAt(i)-'a'][1] = i;
        }
        Arrays.sort(map, (x, y)->Integer.compare(x[0], y[0])); //按照区间左边界升序排序
        int i = 0;
        while(map[i][0] == -1) i++; //跳过不存在的字母
        List<int[]> q = new ArrayList();
        int[] pre = map[i]; //记录上一个区间
        for(int j = i+1; j < map.length; j++){
            if(map[j][0] <= pre[1]) { //如果上一个区间与当前区间有重合
                pre[1] = Math.max(map[j][1], pre[1]); //扩展区间
            }else{  //没有重合
                q.add(pre);  //后续都不会有重合的区间,存入结果中
                pre = map[j]; 
            }
        }
        q.add(pre);
        q.forEach(a->ans.add(a[1]-a[0]+1));
        return ans;
    }
}

官解当然还是优雅啊,先遍历字符串,得到每个字母的末尾位置。使用end记录当前字串的区间的末尾,i==end说明已经找到了符合要求的区间。在遍历的的同时更新end。

class Solution {
    public List<Integer> partitionLabels(String s) {
        List<Integer> ans = new ArrayList();
        int[] map = new int[26]; 
        for(int i = 0; i < s.length(); i++){
            map[s.charAt(i)-'a'] = i;
        }
        int pre = -1, end = -1;
        for(int i = 0; i < s.length(); i++){
            end = Math.max(end, map[s.charAt(i)-'a']); //重点
            if(i == end) {
                ans.add(i-pre);
                pre = i;
            }
        }
        return ans;
    }
}

标签:map,int,30,Part04,++,length,intervals,区间,Day
From: https://www.cnblogs.com/12sleep/p/18336799

相关文章

  • 代码随想录算法训练营day01|704. 二分查找,27. 移除元素,977.有序数组的平方
    704.二分查找题目链接:https://leetcode.cn/problems/binary-search/description/本人代码:classSolution{public:intsearch(vector<int>&nums,inttarget){intlow=0,high=nums.size()-1;//此处分情况讨论returnsearchTarget(nums,low,high,tar......
  • P3043 [USACO12JAN] Bovine Alliance G 题解
    P3043[USACO12JAN]BovineAllianceG题目传送门思路首先分情况讨论每种联通块的可能,有三种不同的情况会对答案\(ans\)产生不同的贡献。联通块有环如图,因为每条边都有要有归属,所以环上的边只能全都顺时针或逆时针属于某个点,且不在环上的点仅有一种可能。因此该情况对答......
  • 代码随想录day16 || 513 树左下角值,112 路径之和,116 中序后序遍历构造二叉树
    切片传递问题question:什么情况下传递切片,什么情况下传递切片指针,为什么有时候会修改原始副本,有时候又不会呢?typesli[]intfuncmain(){ slice:=[]int{1} fmt.Printf("slice:%p\n",slice) change1(slice) fmt.Println("=================================") s2:=......
  • Day16 二叉树Part4 常规递归和遍历法的综合应用(二叉树相关)
    目录任务112.路径总和思路113.路径总和II思路106.从中序与后序遍历序列构造二叉树思路105.从前序与中序遍历序列构造二叉树思路心得体会任务112.路径总和给你二叉树的根节点root和一个表示目标和的整数targetSum。判断该树中是否存在根节点到叶子节点的路径,这条路......
  • [BSidesCF 2020]Had a bad day
    [BSidesCF2020]Hadabadday参考:文件包含漏洞Step点一下按钮,发现URL发生改变:url/index.php?category=woofers修改尝试发现回显:​Sorry,wecurrentlyonlysupportwoofersandmeowers.继续尝试修改:url/index.php?category=woofers.php;flag回显:Warn......
  • LKT4304芯片对比认证方案
    对比案应用模式固定,调试简单,MCU主控端只需要移植对称加密算法和简单的加密操作即可,不需对主控MCU端原有程序做大的改动。同时也不需要用户了解加密芯片内部运行流程,因此调试周期短,研发投入小。凌科芯安公司提供相应的Demo例程,用户直接移植即可使用。 对比认证方案实现的步骤如下......
  • 【2024-07-30】烦琐是福
    20:00不以爱之而苟善,不以恶之而苟非。                                                 ——嵇康下午帮大宝约了眼科,已经拖了三个月的检查终于决定换一家医院去继续检......
  • L1-030 一帮一 分数 15
    //11'52"#include<iostream>#include<vector>usingnamespacestd;intmain(){intn;cin>>n;vector<pair<int,string>>qian;vector<pair<int,string>>hou;for(inti=1;i<=......
  • Day47.where过滤
    1.where过滤_查询id大于等于3小于等于6的数据,两种查询方式 2.where过滤_查询薪资是20000或者18000或者17000的数据,两种查询方式3.where过滤_查询员工姓名中包含字母`o`的员工的姓名和薪资4.where过滤_查询员工姓名是由四个字符组成的,姓名和薪资,两种方式5.where过滤_......
  • 【游戏设计随笔10】解密游戏设计的30堂课
    Part1:(1)尤里卡(Eureka)时刻是谜题的基本组成部分(原子)(2)谜题与幽默是同构的(3)最大限度提高Sparkle(闪光点)(4)避开无价值的谜题(Chaff)(5)惊喜是Sparkle的重要源泉(6)有趣的事实是惊喜的源泉(7)尤里卡不是Fiero(自豪)(8)不同解谜者寻求的解谜体验是不尽相同的(9)尤里卡是可分享的(10)创造很多尤里......