Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
给你一个整数数组 nums 和一个整数 target 。
请你统计并返回 nums 中能满足其最小元素与最大元素的 和 小于或等于 target 的 非空 子序列的数目。
由于答案可能很大,请将结果对 109 + 7 取余后返回。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/nu… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
一看到子序列脑子中很快就想到了动态规划或者回溯,再仔细看下题目的意思,显然用回溯暴力应该可以做出来,但是应该是过不了的,因为题目说了结果很大,都要取余来获取最终的结果了,不过没事,反正很久没有写过回溯的题目了,正好回顾一下。回溯的题目无疑要注意去重,这里的相同元素是有不同的含义的,所以连去重都省了,那么回溯要做什么呢?把最大值/最小值改回原来的值。很快一份超时的代码就出炉来。
超时代码
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var numSubseq = function(nums, target) {
let min=Infinity,max=-Infinity,cnt=0;
let vis=new Array(nums.length).fill(false);
nums.sort((a,b)=>a-b);
dfs(0);
return cnt%(10**9 + 7);
function dfs(index){
if(min+max>target){
return;
}
if(min+max<=target){
cnt++;
}
for(let i=index;i<nums.length;i++){
vis[i]=true;
let preMin=min;
let preMax=max;
if(min>nums[i]){
min=nums[i];
}
if(max<nums[i]){
max=nums[i];
}
dfs(i+1);
vis[i]=false;
min=preMin;
max=preMax;
}
}
};
显然暴力很多时候是解决不了问题的,那我们就需要继续揣摩下题目了。仔细想想,其实我们只要找个最大值最小值,然后介于这两者之间的数能有多少种组合,那么答案就是几1了。那么可以分为下面几步解决这个问题
- 从小到大对数组进行排序;
- 查找 target-nums[i] 应该在的位置j;
- 计算介于i和j之间可以组成的数的个数; 三、AC 代码:
代码一:
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var numSubseq = function(nums, target) {
let count = BigInt(0), mod = BigInt(1e9 + 7);
nums.sort((a, b) => a - b);
let len = nums.length;
for (let i = 0; i < len; i++) {
let j = findMax(target - nums[i], nums);
if (j >= i) {
count = (count + quickPow(2, j - i) % mod) % mod;
}
}
return count;
};
// 快速幂算法
function quickPow(x, n) {
if (n === 0) return BigInt(1);
let y = quickPow(x, Math.floor(n / 2));
return n % 2 === 0 ? BigInt(y) * BigInt(y) : BigInt(y) * BigInt(y) * BigInt(x);
}
// 找到小于 value 的最大的索引
function findMax(value, arr) {
let left = 0, right = arr.length - 1;
while (left <= right) {
let midIndex = left + ((right - left) >> 1);
if (arr[midIndex] > value) {
right = midIndex - 1;
} else {
if (midIndex === arr.length - 1 || arr[midIndex+1] > value) {
return midIndex;
} else {
left = midIndex + 1;
}
}
}
return -1;
}
四、总结:
暴力是解决不了问题的哇