📜  数组中K个最小和最大斐波纳契数的总和与乘积(1)

📅  最后修改于: 2023-12-03 15:26:10.656000             🧑  作者: Mango

数组中K个最小和最大斐波纳契数的总和与乘积

介绍

在一个整数数组中,我们定义一组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)