一、题目
袋子中装有一些物品,每个物品上都标记着数字 1
、0
或 -1
。
给你四个非负整数 numOnes
、numZeros
、numNegOnes
和 k
。
袋子最初包含:
numOnes
件标记为1
的物品。numZeroes
件标记为0
的物品。numNegOnes
件标记为-1
的物品。
现计划从这些物品中恰好选出k
件物品。返回所有可行方案中,物品上所标记数字之和的最大值。
示例
输入:numOnes = 3, numZeros = 2, numNegOnes = 0, k = 2
输出:2
解释:袋子中的物品分别标记为 {1, 1, 1, 0, 0} 。取 2 件标记为 1 的物品,得到的数字之和为 2 。
可以证明 2 是所有可行方案中的最大值。
提示:
- 0 <= numOnes, numZeros, numNegOnes <= 50
- 0 <= k <= numOnes + numZeros + numNegOnes
二、题解
解法1(初级)
- 思路:先取完标记为
1
的物品,再取0
,最后取-1
- 步骤
- 生成一个包含所有物品的数组,数组从大到小排序 如[1,1,1,0,-1,-1…]
- 数组的前
K
位的累加值,即为返回值
/**
* @param {number} numOnes
* @param {number} numZeros
* @param {number} numNegOnes
* @param {number} k
* @return {number}
*/
var kItemsWithMaximumSum = function(numOnes, numZeros, numNegOnes, k) {
let itemList = [];
itemList = [...new Array(numOnes).fill(1),...new Array(numZeros).fill(0),...new Array(numNegOnes).fill(-1)];
let sum = 0;
for(let i = 0; i <k; i++){
sum = sum + itemList[i]
}
return sum;
};
。。 性能不太行呀,看看其它大神的解答
解法2(推荐)
- 不必列出每个物品的标记
- 利用二维数组
/**
* @param {number} numOnes
* @param {number} numZeros
* @param {number} numNegOnes
* @param {number} k
* @return {number}
*/
var kItemsWithMaximumSum = function (numOnes, numZeros, numNegOnes, k) {
let itemArray = [[1, numOnes], [0, numZeros], [-1, numNegOnes]];
let sum = 0;
for (let [val, count] of itemArray) {
let selectNum = Math.min(count, k);
k -= selectNum;
sum += selectNum * val;
if (k <= 0) return sum;
}
return sum;
};
性能显著提升~
三、拓展 for…of
遍历二维数组及解构数组元素
let iterable = [["a", 1,11], ["b", 2,22]];
for (let entry of iterable) {
console.log(entry);
}
for (let [val1, val2,val3] of iterable) {
console.log(val1);
console.log(val2);
console.log(val3);
}
> Array ["a", 1, 11]
> Array ["b", 2, 22]
> "a"
> 1
> 11
> "b"
> 2
> 22