1710. 卡车上的最大单元数-easy-贪心
思路:按照单元素大小进行排序,贪心即可
/*** @param {number[][]} boxTypes* @param {number} truckSize* @return {number}*/var maximumUnits = function(boxTypes, truckSize) {let result = 0;boxTypes.sort((a,b)=>b[1] - a[1]);boxTypes.map(([num,unit])=>{result += Math.min(truckSize,num)*unit;truckSize = Math.max(0,truckSize - num);})return result;};
1711. 大餐计数-medium-哈希表+枚举
/*** @param {number[]} deliciousness* @return {number}*/var countPairs = function(deliciousness) {const map = new Map();const mod = 1e9+7;let result = 0;deliciousness.map((val)=>{const cnt = map.get(val) || 0;for(let j = 0;j < 22;j++){const target = 2 ** j;if(map.has(target - val)){result = (result + map.get(target - val))%mod;}}map.set(val,cnt + 1);})return result;};
1712. 将数组分成三个子数组的方案数-medium-二分
思路:枚举第一段前缀和位置,然后在右侧两次二分查找使其满足题目要求的前缀和位置上界rr和下界ll,在[ll,rr]之间选任一点作为第二个分割点均可满足要求,所以对答案的贡献为 rr- ll + 1
/**
* @param {number[]} nums
* @return {number}
*/
var waysToSplit = function(nums) {
const n = nums.length;
const pre_sum = new Int32Array(n + 1);
const mod = 1e9 + 7;
pre_sum[0] = nums[0];
for (let i = 1; i < n; i++) {
pre_sum[i] = pre_sum[i - 1] + nums[i];
}
const sum = pre_sum[n - 1];
let result = 0;
for (let i = 0; i < n - 1; i++) {
if (pre_sum[i] * 3 > sum) {
break;
}
let [l, r, ll, rr] = [i + 1, n - 2];
while (l <= r) {
const mid = (l + r) >> 1;
if (pre_sum[mid] >= 2 * pre_sum[i]) {
r = mid - 1;
} else {
l = mid + 1;
}
}
ll = l;
[l, r] = [i + 1, n - 2];
while (l <= r) {
const mid = (l + r) >> 1;
if (sum - pre_sum[mid] >= pre_sum[mid] - pre_sum[i]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
rr = r;
result += (rr - ll + 1) % mod;
}
return result % mod;
};
1713. 得到子序列的最少操作次数-hard-LIS
思路:设target长度为N,假设需要添加x个整数,那么就需要arr 提供N-x个整数,而且这N-x个整数在target中的相对顺序还必须与target的相同,为了使x最小,则需要让N-x最大,即找出arr中满足顺序相同的最长上升子序列因为是最长(严格)递增子序列,所以可以使用O(NlogN)的做法来优化效率。
/**
* @param {number[]} target
* @param {number[]} arr
* @return {number}
*/
const lower_bound = (arr, left, right, val) => {
while (left <= right) {
const mid = (left + right) >> 1;
if (arr[mid] === val) {
return mid;
} else if (arr[mid] < val) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
const LIS = (arr) => {
const n = arr.length;
const res = [];
for (let i = 0; i < n; i++) {
if (!res.length || arr[i] > res[res.length - 1]) {
res.push(arr[i]);
} else {
const index = lower_bound(res, 0, res.length - 1, arr[i]);
res[index] = arr[i];
}
}
return res.length;
}
var minOperations = function(target, arr) {
const map = new Map();
const indexs = [];
for (let i = 0; i < target.length; i++) {
map.set(target[i], i);
}
arr.map(item => {
if (map.has(item)) {
indexs.push(map.get(item));
}
})
return target.length - LIS(indexs);
};
