1288. 删除被覆盖区间
给你一个区间列表,请你删除列表中被其他区间所覆盖的区间。
只有当 c <= a 且 b <= d 时,我们才认为区间 [a,b) 被区间 [c,d) 覆盖。
在完成所有删除操作后,请你返回列表中剩余区间的数目。
示例:
输入: intervals = [[1,4],[3,6],[2,8]]
输出: 2
解释: 区间 [3,6] 被区间 [2,8] 覆盖,所以它被删除了。
解题思路:一个区间如果要被覆盖,必须满足两个条件,比如区间a1 = [1,8],如果区间 a2要被a1覆盖的话,a2的左区间要大于等于1,右区间要小于等于8,所以我们可以将intervals数组按照左区间从小到大排序,这样的话右边的左区间始终大于等于左边的左区间,被包含在内了,现在只要判断,左边的数据右区间是否大于右边数据的右区间了,如果左边数据右区间大于左边的,那么右边的数据就被覆盖,所以当左区间相等的时候按照右区间大到小排序,可以找到左边右区间最大值,当右边右区间小于等于左边右区间最大值是,右边数据就被覆盖了,代码如下:
var removeCoveredIntervals = function(intervals) {
//将数组按照左区间由小到大排序,当左区间相等的时候按照右区间大到小排序
intervals.sort(function(a,b){
if(a[0] == b[0]) return b[1] - a[1];
else return a[0] - b[0];
})
//cnt记录的是有多少个区间被覆盖,记录左边最大的右区间值
let cnt = 0,r_max = -1;
for(let i = 0; i < intervals.length; i ++){
//a是当前区间的左区间,因为已经按照小到大排序的,所以不用比较,b是右区间,当b小于最大右区间值,就说明被覆盖了,如果小于,就替换最大值
let [a,b] = intervals[i]
if(b <= r_max) cnt ++;
else r_max = b;
}
//cnt是被覆盖的区间数量
return intervals.length - cnt;
};
491. 递增子序列
给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。 示例 1:
输入:nums = [4,6,7,7]
输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]
示例 2:
输入: nums = [4,4,3,2,1]
输出: [[4,4]]
解题思路:这题是利用的递归来组合数据,代码如下
var findSubsequences = function(nums) {
//保存符合条件的数组
let ret = [];
//0代表的是从第0位开始遍历,[]是组合的数组
find_subsequences(nums,0,[],ret)
return ret;
};
let find_subsequences = function(arr,k,buff,ret){
//因为是数组要大于两位,所以当组合的数组大于1的时候就保存到ret中,[...buff]就相当于是重新定义的一个数组,不然里面内容会被新的内容更新
if(buff.length > 1) ret.push([...buff]);
//默认新增加的数字是0
buff.push(0);
//记录当前循环已有数据,避免重复
let set = {};
for(let i = k; i < arr.length; i ++){
//如果当前循环这个数字已经组合过,就不用再组合了,避免重复
if(set[arr[i]]) continue;
//如果buff只有一个值,那肯定就是0,所以需要替换,因为buff最后以为是0 ,所以需要与buff倒数第二位比较,替换
if(buff.length == 1 || arr[i] >= buff[buff.length - 2]){
buff[buff.length - 1] = arr[i];
//记录当前循环已经组合过的数字
set[arr[i]] = 1;
//第一次循环是[4]继续与后面组合,循环还会继续,就是[4,6]继续与后面数组组合
find_subsequences(arr,i + 1,[...buff],ret);
}
}
return;
}
面试题 04.12. 求和路径
给定一棵二叉树,其中每个节点都含有一个整数数值(该值或正或负)。设计一个算法,打印节点数值总和等于某个给定值的所有路径的数量。注意,路径不一定非得从二叉树的根节点或叶节点开始或结束,但是其方向必须向下(只能从父节点指向子节点方向)。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
3
解释: 和为 22 的路径有:[5,4,11,2], [5,8,4,5], [4,11,7]
解题思路:这题就是通过递归来计算,代码如下:
var pathSum = function(root, sum) {
if(!root) return 0;
//从根节点开始遍历是否存在等于sum值
let a = path_sum(root,sum);
// 根节点,加左节点,和右节点
return a + pathSum(root.left,sum) + pathSum(root.right,sum);
};
let path_sum = function(root,sum){
if(!root) return 0;
let val = sum - root.val;
//(root.val == sum) == 1
return (root.val == sum) + path_sum(root.left,val) + path_sum(root.right,val);
}