📅  最后修改于: 2023-12-03 15:26:10.656000             🧑  作者: Mango
在一个整数数组中,我们定义一组k个数字x1、x2、...、xk,这组数字的和 s=x1+x2+...+xk 。如果一组数字满足斐波那契数列的性质,就称这组数字为斐波那契数。斐波那契数列的第一个和第二个数字为 1,后面的每个数字都是前面两个数字的和。
这个问题中,我们需要求出数组中k个最小和最大的斐波那契数的和与乘积。假设所有输入都是合法的,则答案不会超出int的范围。
我们需要维护一个斐波那契数列,首先构建一个大小为 30 的斐波那契数列数组,计算出所有小于等于100000000的斐波那契数。接着将输入的数组排序,从小到大或者从大到小,然后对排好序的数组从前往后或从后往前遍历,进行斐波那契数列的查找,如果当前数在斐波那契数列中,则将该数加入到斐波那契数列数组中,然后递归查找剩下的数,否则直接递归查找剩下的数。递归的过程中,需要维护两个集合,一个是已经找到的斐波那契数集合,另一个是未找到的数的集合。
最后,根据题目要求返回k个最小和最大斐波那契数的和与乘积即可。
def find_fibonacci(seq, fib_array):
i = 0
while i < len(fib_array) and fib_array[i] <= seq:
if seq == fib_array[i]:
return [seq]
i += 1
return []
def get_fibonacci_nums(num):
fib_array = [1, 2]
while fib_array[-1] < num:
fib_array.append(fib_array[-1] + fib_array[-2])
return fib_array[2:]
def fibonacci_sum_product(array, k):
array.sort()
fibonacci_nums = get_fibonacci_nums(array[-1])
fibonacci_set = set(fibonacci_nums)
already_set = set()
result_sum, result_mul = [], []
for num in reversed(array):
if num in already_set:
continue
result_sum += find_fibonacci(num, fibonacci_nums)
if len(result_sum) == k:
break
if num in fibonacci_set:
result_mul.append(num)
already_set.add(num)
if len(result_mul) == k:
break
else:
already_set.add(num)
result_sum = sum(result_sum)
result_mul = reduce(lambda x, y: x * y, result_mul)
return result_sum, result_mul
assert fibonacci_sum_product([1, 4, 3, 5, 8, 11], 2) == (14, 40)
assert fibonacci_sum_product([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 3) == (34, 945)