分类不好,这道题就做不出来!
1.题目描述
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points
,其中points[i] = [xstart, xend]
表示水平直径在 xstart
和 xend
之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x
处射出一支箭,若有一个气球的直径的开始和结束坐标为 x``start
,x``end
, 且满足 xstart ≤ x ≤ x``end
,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points
,返回引爆所有气球所必须射出的 最小 弓箭数 。
示例 1:
1 2 3 4 5
| 输入:points = 输出:2 解释:气球可以用2支箭来爆破: -在x = 6处射出箭,击破气球和。 -在x = 11处发射箭,击破气球和。
|
示例 2:
1 2 3
| 输入:points = 输出:4 解释:每个气球需要射出一支箭,总共需要4支箭。
|
示例 3:
1 2 3 4 5
| 输入:points = 输出:2 解释:气球可以用2支箭来爆破: - 在x = 2处发射箭,击破气球和。 - 在x = 4处射出箭,击破气球和。
|
提示:
- $1 <= points.length <= 10^5$
points[i].length == 2
- $-2^{31} <= x_{start} < x_{end} <= 2^{31} - 1$
2.题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public int findMinArrowShots(int[][] points) { Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
int result = 1;
for (int i = 1; i < points.length; i++) { if (points[i][0] > points[i - 1][1]) { result++; } else { points[i][1] = Math.min(points[i][1], points[i - 1][1]); } }
return result; } }
|
1.题目描述
给定一个区间的集合 intervals
,其中 intervals[i] = [starti, endi]
。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
注意 只在一点上接触的区间是 不重叠的。例如 [1, 2]
和 [2, 3]
是不重叠的。
示例 1:
1 2 3
| 输入: intervals = 输出: 1 解释: 移除 后,剩下的区间没有重叠。
|
示例 2:
1 2 3
| 输入: intervals = 输出: 2 解释: 你需要移除两个 来使剩下的区间没有重叠。
|
示例 3:
1 2 3
| 输入: intervals = 输出: 0 解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
|
提示:
- $1 <= intervals.length <= 10^5$
intervals[i].length == 2
- $-5 * 10^4 <= start_i < end_i <= 5 * 10^4$
2.题解
2.1 贪心算法-写法1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public int eraseOverlapIntervals(int[][] intervals) { Arrays.sort(intervals, (a, b) -> { return a[0] - b[0]; }); int count = 1; for (int i = 1; i < intervals.length; i++) { if(intervals[i-1][1] <= intervals[i][0]){ count++; } else { intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]); } } return intervals.length - count; } }
|
2.2 贪心算法-写法2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Solution { public int eraseOverlapIntervals(int[][] intervals) { Arrays.sort(intervals, (a, b) -> { return Integer.compare(a[0], b[0]); });
int remove = 0; int preR = intervals[0][1];
for (int i = 1; i < intervals.length; i++) { if (preR <= intervals[i][0]) { preR = intervals[i][1]; } else { remove++; preR = Math.min(preR, intervals[i][1]); } }
return remove; } }
|
1.题目描述
给你一个字符串 s
。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s
。
返回一个表示每个字符串片段的长度的列表。
示例 1:
1 2 3 4 5 6
| 输入:s = "ababcbacadefegdehijhklij" 输出:[9,7,8] 解释: 划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。 每个字母最多出现在一个片段中。 像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。
|
示例 2:
1 2
| 输入:s = "eccbbbbdec" 输出:[10]
|
提示:
1 <= s.length <= 500
s
仅由小写英文字母组成
2.题解
- 思路:
- 统计每一个字符最后出现的位置
- 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public List<Integer> partitionLabels(String s) { int[] edge = new int[26]; for(int i = 0; i < s.length(); i++) edge[s.charAt(i) - 'a'] = i; List<Integer> result = new ArrayList<>(); int left = 0, right = 0; for(int i = 0; i < s.length(); i++) { right = Math.max(right, edge[s.charAt(i) - 'a']); if(right == i) { result.add(right - left + 1); left = right + 1; } } return result; } }
|
1.题目描述
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例 1:
1 2 3
| 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 输出:[[1,6],[8,10],[15,18]] 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
|
示例 2:
1 2 3
| 输入:intervals = [[1,4],[4,5]] 输出:[[1,5]] 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
|
提示:
- $1 <= intervals.length <= 10^4$
intervals[i].length == 2
- $0 <= start_i <= end_i <= 10^4$
2.题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Solution { public int[][] merge(int[][] intervals) { if(intervals.length == 0) return new int[0][2];
Arrays.sort(intervals, new Comparator<int[]>() { public int compare(int[] intervals1, int[] intervals2) { return intervals1[0] - intervals2[0]; } });
List<int[]> result = new ArrayList<>();
for(int i = 0; i < intervals.length; i++) { int L = intervals[i][0], R = intervals[i][1];
if(result.size() == 0 || result.get(result.size() - 1)[1] < L) { result.add(new int[]{L, R}); } else { result.get(result.size() - 1)[1] = Math.max(result.get(result.size() - 1)[1], R); } }
return result.toArray(new int[result.size()][]); } }
|