最长考拉兹序列

来源:互联网 发布:boost算法 编辑:程序博客网 时间:2024/04/29 14:53

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

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 0