最长考拉兹序列

在正整数集上定义如下的迭代序列:

n → n/2 (若n为偶数)
n → 3n + 1 (若n为奇数)

从13开始应用上述规则,我们可以生成如下的序列:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
可以看出这个序列(从13开始到1结束)共有10项。尽管还没有被证明,但我们普遍认为,从任何数开始最终都能迭代至1(“考拉兹猜想”)。

从小于一百万的哪个数开始,能够生成最长的序列呢?

注: 序列开始生成后允许其中的项超过一百万。

package EULER14;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2016/8/3.
 * 最长考拉兹序列
 * 在正整数集上定义如下的迭代序列:
 * n → n/2 (若n为偶数)
 * n → 3n + 1 (若n为奇数)
 * 从13开始应用上述规则,我们可以生成如下的序列:
 * 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
 * 可以看出这个序列(从13开始到1结束)共有10项。尽管还没有被证明,但我们普遍认为,从任何数开始最终都能迭代至1(“考拉兹猜想”)。
 * 从小于一百万的哪个数开始,能够生成最长的序列呢?
 * 注: 序列开始生成后允许其中的项超过一百万。
 * 从999999开始遍历,遍历过的放入map,碰到就跳,时间复杂度O(n)
 * 碰到了一个问题,中间超出了int最大值,导致结果出错,以后注意。
 * 妈的,应该是实例类不但占内存还很占时间,直接暴力遍历居然更快。。。。
 * 事实证明时间复杂度低不一定快。。。注释中的代码更快。。。
 */
public class EULER14 {
    public static void main(String[] args){
        long start = System.currentTimeMillis();
        Map<Long,Point> map = new HashMap<Long, Point>();
        Point one = new Point();
        one.setLength(1);
        one.setValue(1);
        map.put(one.getValue(),one);
        long i = 999999;
        while (i>1){
            setMap(map,i);
            i--;
        }
        Point max = one;
        for (Point point:map.values()){
            if (point.getLength()>max.getLength())
                max = point;
        }
        System.out.println("num:" + max.getValue() + ",length:" + max.getLength());
//        int longest = 0;
//        int terms = 0;
//        int i;
//        long j;
//
//        for (i = 1; i <= 1000000; i++)
//        {
//            j = i;
//            int this_terms = 1;
//
//            while (j != 1)
//            {
//                this_terms++;
//
//                if (this_terms > terms)
//                {
//                    terms = this_terms;
//                    longest = i;
//                }
//
//                if (j % 2 == 0)
//                {
//                    j = j / 2;
//                }
//                else
//                {
//                    j = 3 * j + 1;
//                }
//            }
//        }
//        System.out.println("num:" + longest + ",length:" + terms);
        long end = System.currentTimeMillis();
        System.out.print("总用时:"+(end-start)+"毫秒");
    }

    public static void setMap(Map<Long,Point> map,long num){
        long length = 0;
        long baseLength = 0;
        List<Long> keyList = new ArrayList<Long>();
        while (num>1){
            if (map.get(num)!=null)
                break;
            length++;
            keyList.add(num);
            num = num%2==1?3*num+1:num/2;
            if (map.get(num)!=null){//遍历过
                baseLength = map.get(num).getLength();
                break;
            }
        }
        for (long i:keyList){
            Point point = new Point();
            point.setValue(i);
            point.setLength(baseLength+length);
            map.put(i,point);
            length--;
        }
    }

}

package EULER14;

/**
 * Created by Administrator on 2016/8/3.
 */
public class Point {
    private long length;
    private long value;

    public long getLength() {
        return length;
    }

    public void setLength(long length) {
        this.length = length;
    }

    public long getValue() {
        return value;
    }

    public void setValue(long value) {
        this.value = value;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值