• ProjectEuler 14


    求拉兹序列的最大链长:

    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、以空间来换取时间,使用一个map,每个key值对应每个数,每个value值对应该数拉兹序列的长度。

    2、如果一个数存在在map里,那么取出map的值即为结果

    3、如果一个数n不存在map里,取拉兹序列的下一个数tmp,(即n为偶数除以2,为奇数乘以3+1),那么map[n]=map[tmp]+1,取map跳步骤2

    通过这一个map可以减少许多不必要的计算,比如从1->5时计算:

    1,2通过初值设定map[1]=1,map[2]=2,不需要计算

    计算3时,map[3]=map[10]+1=8,map[10]=map[5]+1=7,map[5]=map[16]+1=6,map[16]=map[8]+1=5,map[8]=map[4]+1=4,map[4]=map[2]+1=3

    以上步骤是递归从后往前计算的,

    再计算4,map[4]再以上步骤已经计算过,那么不需要再计算,直接取map[4]=3

    同理计算5,有map[5]=6

     

    代码如下:

     1 private static int CollatzLen(long n, Map<Long, Integer> a) {
     2         if (n == 1)
     3             return a.get(1L);
     4         if (n == 2) {
     5             return a.get(2L);
     6         }
     7         if (a.get(n) != null)
     8             return a.get(n);
     9 
    10         long tmp = n / 2;
    11         if (n % 2 == 1)
    12             tmp = 6 * tmp + 4;
    13         if (a.get(n) == null)
    14             a.put(n, CollatzLen(tmp, a) + 1);
    15         else
    16             a.put(n, a.get(tmp) + 1);
    17         return a.get(n);
    18     }
    19 
    20     private static int longCollatz(int N) {
    21         int max = 0;
    22         int data = 1;
    23         Map<Long, Integer> a = new HashMap<Long, Integer>();
    24         a.put(1L, 1);
    25         a.put(2L, 2);
    26         for (int i = 1; i <= N; i++) {
    27             int tmp = CollatzLen(i, a);
    28             if (tmp > max) {
    29                 max = tmp;
    30                 data = i;
    31             }
    32         }
    33         // System.out.println("-------每个整数的Collatz链长-------");
    34         // for (long key : a.keySet()) {
    35         // System.out.print(key + " : " + a.get(key) + " , ");
    36         // }
    37         // System.out.println("-------每个整数的Collatz链长-------");
    38         return data;
    39     }
    View Code
  • 相关阅读:
    世界上最快的排序算法——Timsort
    十二种排序包你满意(冒泡、插入、归并、快速排序等包含希尔和计数排序)
    二叉树遍历方法大全(包含莫里斯遍历)
    Nginx知多少系列之(一)前言
    .NET Core项目部署到Linux(Centos7)(一)前言
    Nginx知多少系列之(十四)Linux下.NET Core项目Nginx+Keepalived高可用(主从模式)
    Nginx知多少系列之(七)负载均衡策略
    Nginx知多少系列之(六)Linux下.NET Core项目负载均衡
    Nginx知多少系列之(五)Linux下托管.NET Core项目
    Nginx知多少系列之(四)工作原理
  • 原文地址:https://www.cnblogs.com/lake19901126/p/3084485.html
Copyright © 2020-2023  润新知