diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/FindMinArrowShots.java b/Leecode/src/main/java/com/markilue/leecode/greedy/FindMinArrowShots.java new file mode 100644 index 0000000..81cdf3d --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/FindMinArrowShots.java @@ -0,0 +1,73 @@ +package com.markilue.leecode.greedy; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * @BelongsProject: Leecode + * @BelongsPackage: com.markilue.leecode.greedy + * @Author: markilue + * @CreateTime: 2022-11-17 20:29 + * @Description: TODO 力扣452题 用最少的数量的箭引爆气球: + * 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 + * 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。 + * 给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。 + * @Version: 1.0 + */ +public class FindMinArrowShots { + + @Test + public void test() { + int[][] points = {{1, 2}, {3, 4},{5, 6},{7, 8}}; + int[][] points1 = {{10, 16}, {2, 8},{1, 6},{7, 12}}; + int[][] points2 = {{1, 2}, {2, 3},{3, 4},{4, 5}}; + int[][] points3 = {{1, 4}, {1, 3},{3, 4},{4, 5}}; + int[][] points4 = {{-2147483646, -2147483645}, {2147483646, 2147483647}}; + int[][] points5 = {{9,12}, {1, 10},{4, 11},{8, 12}, {3, 9}, {6, 9},{6, 7}}; +// System.out.println((long)(-2147483646)-(long)(2147483647)); //-4294967293 +// System.out.println((int)((long)(-2147483646)-(long)(2147483647)));//3 +// System.out.println((int)(-2147483646)-(int)(2147483647)); //3 + System.out.println(findMinArrowShots(points)); + } + + /** + * 本人思路:先根据xstart进行排序,然后寻找第一个比xend大的xstart则result+1以此类推 + * 排序的时间复杂度为O(nlogn),所以总复杂度为O(nlogn) + * 速度击败12.72%,内存击败88.71% + * @param points + * @return + */ + public int findMinArrowShots(int[][] points) { + + //按xstart进行排序 + Arrays.sort(points, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + //警惕两数相减超过int范围 + return o1[0] == o2[0] ? (o1[1] > o2[1]?1:-1) : (o1[0] > o2[0]?1:-1); + } + }); + + + //遍历points,找到比xend大的xstart就+1 + int result=1; + int lastEnd=points[0][1]; + for (int i = 1; i < points.length; i++) { + + if(points[i][0]>lastEnd){ + result++; + lastEnd=points[i][1]; + } + //判断第二个数是不是比lastEnd还小,如果还小就是子集,那么就还得该lastEnd + if(points[i][1]