用最少数量的箭引爆气球
核心思路
-
这道题贪心的点在于, 让气球尽可能多的有重合的部分, 这样就可以一箭射穿
-
先根据左边界排序, 再判断 下个气球的左边界和上个气球的右边界是否有重合的部分, 有的话, 就能一箭射穿
- 注意, 这里要更新重合部分的边界, 重合部分的边界是: [当前气球的左边界, 两个气球的最小的右边界]
-
如果没有重合的部分, 那就从当前气球开始重新寻找重合的边界
javapublic static int findMinArrowShots(int[][] points) { Arrays.sort(points, Comparator.comparingInt(a -> a[0])); int res = 1; int rightBian = points[0][1]; for (int i = 1; i < points.length; i++) { int[] point = points[i]; int left = point[0]; int right = point[1]; if (left > rightBian) { res++; rightBian = right; } else { rightBian = Math.min(right, rightBian); } } return res; }
无重叠区间
核心思路
-
和射气球思路类似, 如果重叠就移除, 不重叠, 就用新的右边界继续判断是否重叠
javapublic int eraseOverlapIntervals(int[][] intervals) { Arrays.sort(intervals, Comparator.comparingInt(a -> a[0])); int preRight = intervals[0][1]; int count = 0; for (int i = 1; i < intervals.length; i++) { int[] ints = intervals[i]; int left = ints[0]; int right = ints[1]; if (left < preRight) { count++; preRight = Math.min(right, preRight); } else { preRight = right; } } return count; }
划分字母区间
核心思路
-
找到每个字母的最大区间范围, 如果下个字母和上个字母有重叠, 那就取最小left和最大right作为新的区间, 继续判断
javapublic List<Integer> partitionLabels(String s) { int left = 0; int right = 0; int[] fastIndex = new int[26]; char[] charArray = s.toCharArray(); for (int i = 0; i < charArray.length; i++) { fastIndex[charArray[i] - 'a'] = i; } List<Integer> res = new ArrayList<>(); for (int i = 0; i < charArray.length; i++) { int index = fastIndex[charArray[i] - 'a']; if (i <= right) { left = Math.min(i, left); right = Math.max(index, right); } else { res.add(right - left + 1); left = i; right = index; } } res.add(right - left + 1); return res; }