力扣每日打卡 2829. k-avoiding 数组的最小总和 (中等)

力扣每日打卡 2829. k-avoiding 数组的最小总和——中等难度

  • 前言
  • 一、题目内容
  • 二、解题方法
    • 1.哈希表
    • 2.官方题解


前言

这是刷算法题的第六天,用到的语言是JS
题目:力扣 2829. k-avoiding 数组的最小总和 (中等)

又又又与两数之和有异曲同工之妙


一、题目内容

给你两个整数 n 和 k 。

对于一个由 不同 正整数组成的数组,如果其中不存在任何求和等于 k 的不同元素对,则称其为 k-avoiding 数组。

返回长度为 n 的 k-avoiding 数组的可能的最小总和。

示例 1:
输入:n = 5, k = 4
输出:18
解释:设若 k-avoiding 数组为 [1,2,4,5,6] ,其元素总和为 18 。
可以证明不存在总和小于 18 的 k-avoiding 数组。

示例 2:
输入:n = 2, k = 6
输出:3
解释:可以构造数组 [1,2] ,其元素总和为 3 。
可以证明不存在总和小于 3 的 k-avoiding 数组。

提示:
1 <= n, k <= 50

二、解题方法

1.哈希表

代码如下(示例):

/**
 * @param {number} n
 * @param {number} k
 * @return {number}
 */
var minimumSum = function (n, k) {
    // 很好啊,我马上的想法就是哈希表,酷似两数之和
    // 思路:
    // 1. n >= k  直接return 0??????? →  假设数组长为n且全为1,则数组值之和为 n?????? 这句话是错误的!!!
    // 2. n > k  
    // 2.1 假设数组为递增数列123456……
    //     定义一个hash = {}
    //     将数列依次进行遍历,如果匹配到有与另一个之和为k的,则不将该数压入hash,而是结束本次循环,进入下一个数的循环,直至hash的长度达到n(使用for循环)
    // 2.2 for循环的长度限制? ×  应该使用while循环,并且使用count来记录压入了hash的个数,即使用count来控制循环 
    
    // 正确思路:进行while循环,如果不存在对应的值,则将值压入hash表,并且sum累加

    // if (n >= k) return 0
    let hash = {}
    let num = 1
    let count = 1
    let sum = 0
    while (count <= n) {
        const rem = num
        const comp = k - rem
        if (!hash[comp]) {// 如果hash中没有对应的值,则压入hash,并且count和sum都加
            // hash[rem] = (hash[rem] || 0)  不能使用这句!!
            hash[rem] = true // 将 值(当前数字) 作为 键(索引) 压入hash表
            count++
            sum += rem
        }
        num++
    }
    return sum

    // for (let i = 0; i < 999; i++) {
    //     const rem = i
    //     const comp = k - i
    //     if (!hash[comp]) {// 如果hash中没有对应的值,则压入hash
    //         hash[rem] = (hash[rem] || 0)
    //     }
    // }
};

2.官方题解

方法一:贪心 + 等差数列求和
思路

根据题目要求,在 k 是奇数的情况下,如果某个正整数 a 在数组中,那么 k−a 肯定不能在数组中。反过来也一样。但是题目要求总和最小,因此我们肯定是将这两个数字中小的放入数组,并且从 1 开始挑选数字放入数组,直到 *⌈2/k⌉ 为止。这之后的数字到 k−1 为止,都不能放入数组。如果这时数字还没到到达 n 个,我们需要从 k 开始,再挑选连续的 k−⌈ 2/k ⌉ 个数字加入数组。因此最后的数组和是一段或者两段等差数列求和。

我们可以自己构造一个等差数列求和的函数,并按照两种情况返回结果。

代码如下(示例):

var minimumSum = function(n, k) {
    if (n <= Math.floor(k / 2)) {
        return arithmeticSeriesSum(1, 1, n);
    } else {
        return arithmeticSeriesSum(1, 1, Math.floor(k / 2)) + arithmeticSeriesSum(k, 1, n - Math.floor(k / 2));
    }
};

function arithmeticSeriesSum(a1, d, n) {
    return (a1 + a1 + (n - 1) * d) * n / 2;
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/determine-the-minimum-sum-of-a-k-avoiding-array/solutions/3609167/k-avoiding-shu-zu-de-zui-xiao-zong-he-by-qgul/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析:
时间复杂度:O(1)。
空间复杂度:O(1)。

链接: 力扣本题官方题解
来源:力扣(LeetCode)

你可能感兴趣的:(每日算法,leetcode,哈希算法,算法)