剑指 Offer II 093. 最长斐波那契数列-哈希表法

剑指 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;

    


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值