🔥 个人主页: 黑洞晓威
😀你不必等到非常厉害,才敢开始,你需要开始,才会变的非常厉害。
452. 用最少数量的箭引爆气球
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points
,其中points[i] = [xstart, xend]
表示水平直径在 xstart
和 xend
之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x
处射出一支箭,若有一个气球的直径的开始和结束坐标为 x``start
,x``end
, 且满足 xstart ≤ x ≤ x``end
,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 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]。
示例 2:
输入:points = [[1,2],[3,4],[5,6],[7,8]]
输出:4
解释:每个气球需要射出一支箭,总共需要4支箭。
解题思路
- 对气球的区间按照结束位置进行升序排序。
- 初始化变量
arrows
表示射出的箭的数量,end
表示当前射出箭的位置。 - 遍历排序后的气球区间,如果当前气球的起始位置大于等于
end
,说明当前气球与前一个气球不重叠,需要射出一支箭,并更新end
为当前气球的结束位置。 - 如果当前气球的起始位置小于
end
,说明当前气球与前一个气球重叠,不需要额外射箭。 - 最终
arrows
的值即为最少需要射出的箭的数量。
代码实现
import java.util.Arrays;
public class MinArrowShots {
public int findMinArrowShots(int[][] points) {
if (points == null || points.length == 0) {
return 0;
}
Arrays.sort(points, (a, b) -> a[1] - b[1]);
int arrows = 1;
int end = points[0][1];
for (int i = 1; i < points.length; i++) {
if (points[i][0] > end) {
arrows++;
end = points[i][1];
}
}
return arrows;
}
public static void main(String[] args) {
MinArrowShots solution = new MinArrowShots();
// Test Case 1
int[][] points1 = {{10, 16}, {2, 8}, {1, 6}, {7, 12}};
int result1 = solution.findMinArrowShots(points1);
System.out.println("Test Case 1 Result: " + result1); // Output: 2
// Test Case 2
int[][] points2 = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
int result2 = solution.findMinArrowShots(points2);
System.out.println("Test Case 2 Result: " + result2); // Output: 4
}
}
763. 划分字母区间
给你一个字符串 s
。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s
。
返回一个表示每个字符串片段的长度的列表。
示例 1:
输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。
示例 2:
输入:s = "eccbbbbdec"
输出:[10]
解题思路
- 统计每个字符最后出现的位置。
- 从头遍历字符,并更新字符的最远出现下标。如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点。
- 将每个分割点之间的长度作为结果。
代码实现
class Solution {
public List<Integer> partitionLabels(String s) {
int[] last = new int[26];
int length = s.length();
for (int i = 0; i < length; i++) {
last[s.charAt(i) - 'a'] = i;
}
List<Integer> partition = new ArrayList<Integer>();
int start = 0, end = 0;
for (int i = 0; i < length; i++) {
end = Math.max(end, last[s.charAt(i) - 'a']);
if (i == end) {
partition.add(end - start + 1);
start = end + 1;
}
}
return partition;
}
}