引自免费微信小程序:皆我百晓生
在C语言中实现查找给定数组中最长的斐波那契子序列的长度的方法涉及两个步骤:首先确定斐波那契数列的起始值,并构造并插入一个新的数组indices
存储原始数组中的每个元素及其对应的索引位置。然后遍历这个新数组,计算每一项arr[j]
与前一项arr[i]
之间的和temp
,并将之添加到二维数组dp
中,并检查当前元素是否满足题目要求:若其值大于等于0且小于等于数组总长度,说明存在符合条件的斐波那契子序列,并更新最大长度。最后,通过比较并删除已存在的子序列(cur
)和新增的子序列(tmp
),找到并移除最长的斐波那契子序列。
以下是完整的代码实现:
#include
#include
#define MAX_LENGTH 1000
// 计算前两个斐波那契数列的和
int fibonacciSum(int a, int b) {
return a + b;
}
// 负载队列结构用于保存待处理元素
void loadQueue(int arr[], int arrSize) {
queue q(arrSize);
for (int i = 0; i < arrSize; ++i) {
q.push(arr[i]);
}
while (!q.empty()) {
int front = q.front();
q.pop();
int back = front - 1;
// 更新斐波那契数列的起始值
arr[back] = front;
arr[front + 1] = fibonacciSum(front, back + 1);
// 添加新的元素及其索引位置
if (arr[front] > 0 && arr[front] < arrSize - 1) {
hash_item *entry = (hash_item*)malloc(sizeof(hash_item));
entry->key = arr[front];
entry->val = front;
q.push(entry);
}
}
}
// 找出最长的斐波那契子序列的长度
int longestFibSubseq(int* arr, int arrSize) {
HashItem *indices = NULL, *pEntry = NULL;
loadQueue(arr, arrSize);
// 初始化动态规划表(dp)
int dp[MAX_LENGTH][MAX_LENGTH];
// 获取数组中的前三个元素
for (int i = 0; i < arrSize; i++) {
pEntry = (hash_item*)malloc(sizeof(hash_item));
pEntry->key = arr[i];
pEntry->val = i;
Hash_ADD_INT(indices, &arr[i], pEntry);
}
// 构建最长斐波那契子序列的起点
long long start_index = -1;
// 遍历新数组,寻找最长斐波那契子序列
for (int i = 0; i < arrSize; ++i) {
for (int j = i + 1; j < arrSize; ++j) {
// 计算当前斐波那契子序列的和
int temp = arr[i] + arr[j];
// 将当前斐波那契子序列添加到dp数组中
if (temp >= 0 && temp < arrSize) {
dp[j][temp] =
(dp[i][j] + 1) > 3 ? (dp[i][j] + 1) : 3;
if (dp[j][temp] > start_index || (dp[j][temp] == start_index && start_index != -1)) {
start_index = dp[j][temp];
}
}
}
}
// 返回最长斐波那契子序列的长度
long long max_length = start_index + 1;
if (start_index != -1)
max_length = max(max_length, longestFibSubseq(arr, start_index + 1));
// 删除最长斐波那契子序列
for (int i = start_index; i < arrSize; ++i) {
arr[i] = arr[i - start_index];
}
// 最后,释放空间并返回结果
free(indices);
free(pEntry);
return max_length;
}
int main()
{
int arr[] = {1, 3, 7, 11, 12, 14, 18};
int arr_size = sizeof(arr) / sizeof(arr[0]);
int result = longestFibSubseq(arr, arr_size);
printf("Length of the longest Fibonacci subsequence: %d\n", result);
return 0;
}
这段代码定义了一个名为longestFibSubseq
的函数,接受一个整数数组arr
以及数组的大小arrSize
作为参数。函数首先将数组转换为一个哈希表indices
,其中每个键表示数组中的一个元素及其对应的索引。接着,使用链表结构记录前三个斐波那契数列的和,并将初始斐波那契子序列的起点赋值为-1,以确保后续计算过程中遵循减一规则(斐波那契数列是以1为首项,以-1为结尾的数列)。然后遍历新数组arr
,计算当前斐波那契子序列的和,并将其添加到动态规划表dp
中。如果当前元素的和大于等于0且小于等于数组总长度,则更新dp
表的最大长度。同时,检查是否有至少一个满足条件的斐波那契子序列,并将起点更新为当前最大长度所在的位置。当遍历结束后,查找并返回最长斐波那契子序列的长度。最后,释放用于存储元素及其索引位置的哈希表和存储动态规划表的动态规划表。
在main
函数中,我们创建一个示例数组arr
,并调用longestFibSubseq
函数获取最长斐波那契子序列的长度,并打印出结果。这展示了如何使用C语言的哈希表、循环和数组操作来解决最长斐波那契子序列长度的问题。