【欧拉计划】Q5:Longest Collatz sequence

Longest Collatz sequence


  • 递推与递归

The following iterative sequence is defined for the set of positive integers:

n → n/2 (n is even)
n → 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

Which starting number, under one million, produces the longest chain?

NOTE: Once the chain starts the terms are allowed to go above one million.

1.函数递归调用

/*思路:简单递归
1.if x == 1, return 1;
2.if x == odd, return (3n + 1);
3.if x == even, return (n / 2);
*/

#include<iostream>
using namespace std;

int func(int x){
    if(x == 1){
        return 1;
    }
    if(x % 2 == 0){
        return func(x / 2) + 1;
    }
    return func(3 * x + 1) + 1;   
}

int main(){
    int ans = 0, mmax = 0;
    for(int i = 1; i <= 1000000; ++i){
        int t = func(i);
        if(t > mmax){
            mmax = t;
            ans = i;
        }
    }
    cout << ans << endl;
    return 0;
}

image-20210412171654270

注意:方法1递归步数太多导致出现爆栈(segmentation fault),原因是递归调用太深

2.利用记忆数组优化递归过程

#include<iostream>
using namespace std;

//1.建立一个记忆化数组,存储计算过程中的中间值(需要将数组额外开大一些)
long long num[10000005];

long long func(long long x){
    if(x == 1){
        return 1;
    }
    //2.num[x] != 0,发现该数字之前已经计算过,直接返回数值
    if(x < 10000000 && num[x] != 0){
        return num[x];
    }
    long long t;
    //3.num[x] == 0,发现该数字之前没有计算过,进行计算并存入记忆化数组中
    if(x % 2 == 0){
        t = func(x / 2) + 1;
    }else{
        t = func(3 * x + 1) + 1;
    }
    if(x < 10000000){
        num[x] = t;
    }
    return t;
}

int main(){
    int ans = 0, mmax = 0;
    for(int i = 1; i <= 1000000; ++i){
        int t = func(i);
        if(t > mmax){
            mmax = t;
            ans = i;
        }
    }
    cout << ans << endl;
    return 0;
}

image-20210412171654270

补充:当算法优化到极致时,只能是用空间换时间 or 用时间换空间,而记忆化数组就是典型的用空间换时间

tips:文章部分内容参考算法刷题课程,题解图示内容及代码根据老师课程、以及自己对知识的理解,进行二次整理和部分补充,仅供学习参考使用,不可商业化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值