14.数组元素之和最小化
问题描述
小C希望构造一个包含n个元素的数组,且满足以下条件:
- 数组中的所有元素两两不同。
- 数组所有元素的最大公约数为
k。 - 数组元素之和尽可能小。
任务是输出该数组元素之和的最小值。
思路解析
本题的目标是构造一个满足特定条件的数组,并求出该数组元素之和的最小值。具体思路围绕如何满足 “所有元素两两不同”“最大公约数为 k” 以及 “元素之和尽可能小” 这三个关键条件来展开。
- 利用最大公约数
k构造元素:
因为要求数组所有元素的最大公约数为k,所以很自然地考虑以k为基础来构造数组元素。通过每次增加k的方式来生成新的元素,这样生成的元素必然都能保证是以k为因数,也就满足了最大公约数是k这一条件。例如,如果k = 3,那么可以生成3、6、9等这样的数,它们的最大公约数就是3。 - 保证元素两两不同:
为了确保数组中的所有元素两两不同,使用了 Python 的集合(set)数据结构。集合的特点是其中的元素具有唯一性,不会出现重复元素。在循环过程中,不断将新生成的元素添加到集合unique_elements中,只要集合中元素的数量还没有达到要求的数组元素个数n,就持续这个添加操作。每次添加元素时,通过current_element += k让当前元素按k的倍数递增,以此来生成不同的元素,直到集合中元素个数满足n个为止。 - 实现元素之和尽可能小:
按照上述以k为基础且每次递增k的方式来构造元素,从最小的符合条件的元素(即k本身)开始逐步递增,这样生成的元素序列是相对最小的,进而保证了这些元素组成的数组其元素之和也是在满足条件下尽可能小的。因为如果不按照这种顺序从小到大构造元素,比如随意选取较大的以k为因数的数,那么最终数组元素之和必然会更大。 - 计算并返回元素之和:
最后,通过sum(unique_elements)计算集合中所有元素的总和,由于集合中已经包含了满足条件的n个不同元素,这个总和就是所求的满足条件的数组元素之和的最小值,将其作为函数的结果返回。
解题步骤
- 函数定义与初始化:
定义了名为 solution 的函数,它接受两个参数:n 表示要构造的数组元素个数(整型),k 表示数组所有元素的最大公约数(整型),函数返回值类型为整型,代表满足条件的数组元素之和的最小值。在函数内部,首先创建了一个空集合 unique_elements,用于存储满足条件的不同元素;然后初始化变量 current_element 为 k,这个变量将用于生成后续的元素,初始化为 k 是因为要从最小的符合最大公约数为 k 的元素开始构造数组。
- 构造满足条件的数组元素集合:
通过一个 while 循环来构造满足条件的元素集合。循环的条件是集合 unique_elements 中的元素个数小于要求的数组元素个数 n。在每次循环中,先将当前元素 current_element 添加到集合中(利用集合的 add 方法,它会自动保证元素的唯一性),然后将 current_element 的值增加 k,以便生成下一个不同的且最大公约数仍为 k 的元素,持续这个过程,直到集合中元素个数达到 n 个为止。
- 计算并返回元素之和:
当集合 unique_elements 中已经有了 n 个满足条件的不同元素后,使用 Python 的内置函数 sum 对集合中的所有元素进行求和操作,得到的结果就是满足题目要求的数组元素之和的最小值,最后通过 return 语句将这个结果返回作为函数的输出。
复杂度分析
时间复杂度:
代码里主要是 while 循环在工作,循环次数由 n(要构造的数组元素个数)决定,循环里操作耗时都是常数级别,所以时间复杂度就是O(n),也就是随 n 增大,运行时间线性增长。
空间复杂度:
用了集合存元素,最多存 n 个,占空间和 n 有关,另外几个变量占空间是常数级别的,整体空间复杂度就是O(n),随 n 变大,内存空间线性增加。
Code
def solution(n: int, k: int) -> int:
unique_elements = set()
current_element = k
while len(unique_elements) < n:
unique_elements.add(current_element)
current_element += k
return sum(unique_elements)
if __name__ == '__main__':
print(solution(n=3, k=1) == 6)
print(solution(n=2, k=2) == 6)
print(solution(n=4, k=3) == 30)