力扣刷题-贪心算法2:

第一题:452. 用最少数量的箭引爆气球

  1. 题目说明
  2. 求解思路
    1)就是具有相同区域的球,可以一次性打掉。问题就是如何判别球之前有区域的重叠。
  3. . 求解步骤
    1)首先对数据进行排序,第一个字母从小到大排列。
    2)寻找到最小右边界,如果后面一个求的位置在最小右边界的左边,那么可以视为这个球能够同上一个球一起打掉,并且更新新的最小右边界;
    3)如果没有落在最小右边界的左边,那么就需要一个新的箭,同时更新最小右边界。
    4)最后输出需要多少支箭。
  4. 代码展示
class Solution {
    public int findMinArrowShots(int[][] points) {
    //使用贪心算法:设置一个重叠气球的最小右边界,如果需要添加新的箭,一定要大于这个边界
    
    //1)先进行排序,按照第一个数字大小进行从小到大排序
    Arrays.sort(points,(a,b) ->{
        return a[0]<b[0]?-1:1;   //  ab代表前后的两个数
    });
    System.out.println(Arrays.deepToString(points));  //易错点:多维数组的输出

    //2)循环开始
    int num=1;
    int rightBor=points[0][1];
    for(int i=1;i<points.length;i++){
        if(points[i][0]>rightBor){
            num++;
            rightBor=points[i][1];
        }else{
            rightBor=points[i][1]>rightBor?rightBor:points[i][1];
        }
    }
    return num;
    }
}
  1. 补充说明
    1)数组进行排序的改写:
    如果是单维数组,那么需要用包装类装(其实是一个匿名内部类Comportor,写成了lambda表达式)
    如果是多维数组,那么不一定需要是包装类的数据类型。
//1)一维数组:逆序排列(重写sort方法)
        Integer[] data=new Integer[]{3,2,5,3,6,2,6,1};
        Arrays.sort(data,( a, b)-> b-a );
        System.out.println("排序好的数组="+Arrays.toString(data));
//2)二维数组排序(重写sort方法)
        //先按第一个数的正序排,如果相同,则按第二个数的倒序排
        int[][] data1=new int[][]{{1,2},{3,1},{1,7,9},{2,1,4}};
        Arrays.sort(data1,(a,b)->{
            if(a[0]==b[0]) return b[1]-a[1];
            return a[0]-b[0];
        });
        System.out.println("排序好的数组="+Arrays.deepToString(data1));

2)输出单维数组和多维数组

Integer[] data=new Integer[]{3,2,5,3,6,2,6,1};
System.out.println("排序好的数组="+Arrays.toString(data));
int[][] data1=new int[][]{{1,2},{3,1},{1,7,9},{2,1,4}};
System.out.println("排序好的数组="+Arrays.deepToString(data1));

3)本体的核心思想就是找最小右边界问题,这也是比较难想的一点。

第二题:435. 无重叠区间(hard题)

  1. 题目说明
    这一题暂时没做
  2. 求解思路
  3. . 求解步骤
  4. 代码展示
  5. 补充说明

第三题:#763.划分字母区间

  1. 题目说明
  2. 求解思路
    1)遍历每一个数,如果找到它在数组中最远位置,那么就一直更新找的区间。
  3. . 求解步骤
    1) 首先写一个方法,输入某个值,找到在这个位置上的最大下标
    2)遍历全局,如果小于初始位置最大下表,就一直更新最大值;
    3)如果等于下标值,那么就输出位数,然后进入下一个地方。
  4. 代码展示
class Solution {
    public List<Integer> partitionLabels(String s) {
        //核心思想:从头开始遍历:调用method方法,找到不重复的最远距离;如果重合了,那么从下一个开始。
        List<Integer> list=new ArrayList<>();
        int befor=0;
        int i=0;
        int max=method(s,i,s.charAt(0));
        while(i<s.length()){
            if(i<max ){
                max=Math.max(max,method(s,i,s.charAt(i)));
            }
            if(i==max){
                list.add(i-befor+1);
                befor=i+1;
                if(i<s.length()-1) max=method(s,i,s.charAt(i+1));
            }
            i++;
    }
        return list;
    }
    //方法:一个字符在数组中最远的下标
    public static int method(String s,int b,char a){
        int size=0;
        for(int i=b;i<s.length();i++){
            if(s.charAt(i)==a){
                size=i;
            }
        }
        return size;
    }
}
  1. 补充说明
  1. s.charAt():表示字符串某个位置的值。

第四题:56. 合并区间

  1. 题目说明
  2. 求解思路
    1)先进行排序,然后比较前后两个数是否需要合并,并且不停的更新。
  3. . 求解步骤
    1)重写sort方法进行排序
    2)后者与前者有交集,则合并。
  4. 代码展示
class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> list=new ArrayList<>();
        
        //1)首先进行排序(根据第一个数值大小正序排列)
        Arrays.sort(intervals,(a,b)->{
            return a[0]-b[0];
        });
        System.out.println("intervals="+Arrays.deepToString(intervals));

        //2)只有相邻的两个元素存在重叠情况
        list.add(intervals[0]);
        for(int i=1;i<intervals.length;i++){
            int[] last=list.get(list.size()-1);
            //(1)情况一:后者与前者有交集,则合并
            if(intervals[i][0]<=last[1]){
                int[] temp=new int[]{last[0],Math.max(last[1],intervals[i][1])};
                list.set(list.size()-1,temp);
                continue;
            }
            list.add(intervals[i]);

        }
        //3)把集合转变为二维数组
        int[][] result=new int[list.size()][];
        for(int i=0;i<list.size();i++){
            result[i]=list.get(i);
        }
        return result;
    }

    //方法,输出数组


}
  1. 补充说明
    1)对数组和集合的转变需要非常熟悉。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值