56. 合并区间
本题也是重叠区间问题,如果昨天三道都吸收的话,本题就容易理解了。
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
- 输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
- 输出: [[1,6],[8,10],[15,18]]
- 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
- 输入: intervals = [[1,4],[4,5]]
- 输出: [[1,5]]
- 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
- 注意:输入类型已于2019年4月15日更改。 请重置默认代码定义以获取新方法签名。
function merge(intervals: number[][]): number[][] {
intervals.sort((a, b) => a[0] - b[0]);
let results: number[][] = [intervals[0]];
for (let i = 1; i < intervals.length; i++) {
if(intervals[i][0] <= results[results.length - 1][1]){
let merged = results.pop();
merged[1] = Math.max(merged[1], intervals[i][1]);
results.push(merged);
} else{
results.push([...intervals[i]]);
}
}
return results;
};
738.单调递增的数字 (需要回看)
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
示例 1:
- 输入: N = 10
- 输出: 9
示例 2:
- 输入: N = 1234
- 输出: 1234
示例 3:
- 输入: N = 332
- 输出: 299
说明: N 是在 [0, 10^9] 范围内的一个整数。
官方题解:
题目要求小于等于N的最大单调递增的整数,那么拿一个两位的数字来举例。
例如:98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]--,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。
这一点如果想清楚了,这道题就好办了。
此时是从前向后遍历还是从后向前遍历呢?
从前向后遍历的话,遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]减一,但此时如果strNum[i - 1]减一了,可能又小于strNum[i - 2]。
这么说有点抽象,举个例子,数字:332,从前向后遍历的话,那么就把变成了329,此时2又小于了第一位的3了,真正的结果应该是299。
那么从后向前遍历,就可以重复利用上次比较得出的结果了,从后向前遍历332的数值变化为:332 -> 329 -> 299
确定了遍历顺序之后,那么此时局部最优就可以推出全局,找不出反例,试试贪心。
function monotoneIncreasingDigits(n: number): number {
let strArr: number[] = String(n).split('').map(i => parseInt(i));
const length = strArr.length;
let flag: number = length;
for (let i = length - 2; i >= 0; i--) {
if (strArr[i] > strArr[i + 1]) {
strArr[i] -= 1;
flag = i + 1;
}
}
for (let i = flag; i < length; i++) {
strArr[i] = 9;
}
return parseInt(strArr.join(''));
};