剑指 Offer II 093. 最长斐波那契数列-哈希表法
如果序列 X_1, X_2, …, X_n 满足下列条件,就说它是 斐波那契式 的:
n >= 3
对于所有 i + 2 <= n,都有 X_i + X_{i+1} = X_{i+2}
给定一个严格递增的正整数数组形成序列 arr ,找到 arr 中最长的斐波那契式的子序列的长度。如果一个不存在,返回 0 。
(回想一下,子序列是从原序列 arr 中派生出来的,它从 arr 中删掉任意数量的元素(也可以不删),而不改变其余元素的顺序。例如, [3, 5, 8] 是 [3, 4, 5, 6, 7, 8] 的一个子序列)
示例 1:
输入: arr = [1,2,3,4,5,6,7,8]
输出: 5
解释: 最长的斐波那契式子序列为 [1,2,3,5,8] 。
示例 2:
输入: arr = [1,3,7,11,12,14,18]
输出: 3
解释: 最长的斐波那契式子序列有 [1,11,12]、[3,11,14] 以及 [7,11,18] 。
解题代码如下:
struct hash{
int val;
int preval;
int count;
struct hash *next;
};
#define size 1000
void add_hash(struct hash *h,int val,int count,int preval){
struct hash *p=(struct hash *)malloc(sizeof(struct hash));
p->count=count;
p->val=val;
p->preval=preval;
p->next=h->next;
h->next=p;
}
int maxcount;
void find(struct hash *h,int val,int *count,struct hash *hr){
struct hash *p=h->next;
while(p){
if(p->val==val&&p->count>1){
if(p->count+1>maxcount){
maxcount=p->count+1;
}
// printf("val %d pre %d count %d |",val,p->preval,p->count+1);
add_hash(hr+(val+p->preval)%size,val+p->preval,p->count+1,val);
}
p=p->next;
}
}
void print_hash( struct hash *h){
struct hash *p;
for(int i=0;i<size;i++){
p=(h+i)->next;
while(p){
printf("%d %d ",p->val,p->count);
p=p->next;
}
}
}
int lenLongestFibSubseq(int* arr, int arrSize){
struct hash *h=( struct hash *)malloc(sizeof(struct hash )*size);
for(int i=0;i<size;i++){
(h+i)->next=NULL;
}
maxcount=0;
int *count=(int *)malloc(sizeof(int));
for(int i=0;i<arrSize;i++){
int val=arr[i];
find(h+val%size,val,count,h);
for(int j=0;j<i;j++){
add_hash(h+(val+arr[j])%size,val+arr[j],2,val);
// printf("%d ",val+arr[j]);
}
add_hash(h+val%size,val,1,0);
}
// print_hash(h);
return maxcount;
}