56. 合并区间
public int[][] merge(int[][] intervals) {
// 排序
Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);
List<int[]> result = new ArrayList<>();
for (int[] currInterval : intervals) {
if (result.isEmpty()) {
result.add(currInterval);
continue;
}
int[] lastInterval = result.get(result.size() - 1);
if (lastInterval[1] >= currInterval[0]) {
lastInterval[1] = Math.max(lastInterval[1], currInterval[1]);
} else {
result.add(currInterval);
}
}
return result.toArray(new int[result.size()][2]);
}
57. 插入区间
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> result;
for (auto currInterval: intervals) {
if (currInterval[1] < newInterval[0]) {
result.push_back(currInterval);
continue;
}
// 开始合并区间
if (currInterval[0] > newInterval[1]) {
result.push_back(newInterval);
newInterval = currInterval;
continue;
}
if (currInterval[1] >= newInterval[0] ||
currInterval[0] <= newInterval[1]) {
// 替换开始时间
newInterval[0] = min(currInterval[0], newInterval[0]);
newInterval[1] = max(newInterval[1], currInterval[1]);
continue;
}
}
result.push_back(newInterval);
return result;
}
252会议室
-
会员题目
-
题目描述:给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei),请你判断一个人是否能够参加这里面的全部会议
-
示例:
Input: [[0,30],[5,10],[15,20]]
Output: falseInput: [[7,10],[2,4]]
Output: true
public boolean canAttendMeetings(int[][] intervals) {
// 按照会议的开始时间,从小到大排序
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; i++) {
// 上一个会议时间
int[] pre = intervals[i - 1];
// 当前会议的时间
int[] curr = intervals[i];
// 当前会议的开始时间,小于上一个会议的结束时间,就表明有重合
if (curr[0] < pre[1]) {
return false;
}
}
return true;
}
253会议室 II
- 用优先级队构建最小堆 和 栈
/**
* 最少会议室
*
* @param interval
* @return
*/
public int minMeetRooms(int[][] interval) {
Arrays.sort(interval, Comparator.comparingInt(a -> a[0]));
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// add the first meeting end time;
minHeap.add(interval[0][1]);
for (int i = 1; i < interval.length; i++) {
if (interval[i][0] >= minHeap.peek()) {
minHeap.poll();
}
minHeap.add(interval[i][1]);
}
return minHeap.size();
}
495. 提莫攻击
public int findPoisonedDuration(int[] timeSeries, int duration) {
int count = 0;
// 当前被攻击的持续时间
int currAttackInterval = timeSeries[0] + duration - 1;
int len = timeSeries.length;
for (int i = 1; i < len; i++) {
// 没有覆盖,在中毒之后,才出现新的攻击
if (timeSeries[i] > currAttackInterval) {
count += duration;
currAttackInterval = timeSeries[i] + duration - 1;
continue;
}
// 在中毒时候,又被攻击了;
// case 1: 更新被攻击的持续时间
currAttackInterval = timeSeries[i] + duration - 1;
// 去掉重置的中毒时间,然后做累加
count += timeSeries[i] - timeSeries[i - 1];
}
// 因为我们统计的是上次「中毒」维持的时间,不要忘记最后一次中毒将维持 duration秒。所以在遍历结束的时候,结果需要加上 duration。
// 是不是有点像 dp[i]?
count += duration;
return count;
}
763. 划分字母区间
- 有点滑动窗口的感觉
public List<Integer> partitionLabels(String s) {
// 所有字符的最大下标
int[] allIndex = new int[128];
for (int i = 0; i < s.length(); i++) {
allIndex[s.charAt(i)] = i;
}
List<Integer> res = new ArrayList<>();
int left = 0;
int right = 0;
for (int i = 0; i < s.length(); i++) {
char currChar = s.charAt(i);
// 当前字符的最大下标
right = Math.max(right, allIndex[currChar]);
// 遍历到最大下标位置
// 可以做长度截取
if (i == right) {
res.add(right - left + 1);
// 更新left 下标位置,便于下次做截取
left = i + 1;
}
}
return res;
}
986. 区间列表的交集
public int[][] intervalIntersection(int[][] firstList, int[][] secondList) {
int len1 = firstList.length;
int len2 = secondList.length;
if (len1 == 0 || len2 == 0) {
return new int[0][];
}
List<int[]> res = new ArrayList<>();
int i = 0;
int j = 0;
while (i < len1 && j < len2) {
int maxLeft = Math.max(firstList[i][0], secondList[j][0]);
int minRight = Math.min(firstList[i][1], secondList[j][1]);
if (maxLeft <= minRight) {
res.add(new int[]{maxLeft, minRight});
}
if (firstList[i][1] < secondList[j][1]) {
i++;
} else {
j++;
}
}
return res.toArray(new int[res.size()][2]);
}
最后
- 感谢各位大佬的题解教程,谢谢你们
- 主要是为了个人刷题,做个总结,侵权的话,我删除链接;
- 一键直达code;