题目描述: 给定两个整数数组array1、array2,数组元素按升序排列。假设从array1、array2中分别取出一个元素可构成一对元素,现在需要取出k对元素,并对取出的所有元素求和,计算和的最小值 注意:两对元素如果对应于array1、array2中的两个下标均相同,则视为同一对元素。输入描述: 输入两行数组:array1、array2, 每行首个数字为数组大小:size(0<size<=100) 0<array1[<=1000, 0<array2[i]<=1000 接下来一行为正整数k:0<k<= array1.size()*array2.size() 输出描述: 满足要求的最小和 示例1 输入: 3 1 1 2 3 1 2 3 2 输出:4 说明: 用例中,需要取2对元素 取第一个数组第0个元素与第二个数组第0个元素组成1对元素[1,1]; 取第一个数组第1个元素与第二个数组第0个元素组成1对元素[1,1]; 求和为1+1+1+1=4,为满足要求的最小和
解题思路:
1、处理输入:列表存储数组数据
2、枚举法计算元素和:使用新数组存储a1+b1中各个元素和
3、排序、求和:计算新数组最小k位元素和
代码部分
def min_sum(a1, a2, k):
result = []
for i in a1:
for j in a2:
result.append(i + j)
result.sort()
return sum(result[:k])
try:
#处理输入
a = input().split()
num_a, a1 = int(a[0]), list(map(int, a[1:]))
if num_a != len(a1):
raise ValueError('input number {} not equal to {}'.format(num_a, a1))
else:
b = input().split()
num_b, b1 = int(b[0]), list(map(int, b[1:]))
if num_b != len(b1):
raise ValueError('input number {} not equal to {}'.format(num_b, b1))
else:
num = int(input())
result = min_sum(a1, b1, num)
print(result)
# result_1 = find_k_min_sum(a1, b1, num)
# print(result_1)
except ValueError as e:
print(e)
其他思路:小根堆
最小堆的使用:由于数组是升序排列的,我们可以利用最小堆来进行最优选择。
初始时,我们将 array1 的第一个元素和 array2 的每个元素配对, 然后将这些配对的和插入最小堆。
每次从堆中取出最小的元素(即当前和最小的一对), 然后将该对元素对应的 array1 的下一个元素与 array2 当前元素组合并插入堆中(注意题目中两个array输入时是升序排列的)。
过程持续到选取了 k 对元素:我们重复上述步骤,直到从堆中取出了 k 对元素。
代码部分:
import heapq
def find_k_min_sum(a1, a2, k):
n1, n2 = len(a1), len(a2)
#最小堆,初始化堆时,放入 (sum, i, j) 这样的元组
min_heap = []
for i in range(min(k, n1)): # 只需考虑 array1 的前 k 个元素(多余的不用考虑)
heapq.heappush(min_heap, (a1[i] + a2[0], i, 0))
#用于存储结果最小和
result_sum = 0
#防止重复计算相同组合
count = 0
while count < k:
sum_val, i, j = heapq.heappop(min_heap)
result_sum += sum_val
count += 1
if j + 1 < n2: #继续生成新的组合推入堆中
heapq.heappush(min_heap, ((a1[i] + a2[j + 1]), i, j + 1))
return result_sum
知识点:列表,排序
结语:越简单的题目解法应该越多,请路过大神留下新的思路供本小白学习一下,打开思路