Go Java算法之累加数示例详解

Go Java算法之累加数示例详解

什么是累加数

累加数是指一个字符串序列,划分成多个数字序列,每个数字序列的数字之和等于后面的数字序列的第一个数字。

例如:112358 是一个累加数,因为 1+1=2, 1+2=3, 2+3=5, 3+5=8,后面的数字序列分别为 1, 2, 3, 5。

算法思路

为了判断一个字符串是否为累加数,我们需要枚举前两个数字,然后依次判断后面的数字序列是否合法即可。

假设第一个数字为 i,第二个数字为 j,那么第三个数字就是 i+j,接下来用 i+j 对原字符串进行截取,判断剩余的字符串是否为 i+j,以此类推。

注意,数字序列不能以 0 开头,所以 i 和 j 可能是一位数、两位数、三位数中的任意两个数字。

示例说明

下面给出两个示例,来详细解释累加数的判断过程。

示例一

输入的字符串为 "11235813"。

我们首先枚举前两个数字:i=1, j=1。

然后计算出第三个数字,即 i+j=2,将字符串从当前位置截取出来,得到 "235813",判断该字符串是否为 2,发现不是,因此这个枚举的结果不合法。

接下来我们枚举下一组:i=1, j=2。

计算出第三个数字 i+j=3,截取字符串得到 "35813",判断该字符串是否为 3,不是。

接下来继续枚举:i=2, j=3。

计算出第三个数字 i+j=5,截取字符串得到 "5813",判断该字符串是否为 5,不是。

接下来继续枚举:i=3, j=5。

计算出第三个数字 i+j=8,截取字符串得到 "13",判断该字符串是否为 8,不是。

接下来继续枚举:i=5, j=8。

计算出第三个数字 i+j=13,截取字符串得到 "",判断该字符串是否为 13,是。

因此,该字符串是一个累加数。

示例二

输入的字符串为 "199100199"。

我们首先枚举前两个数字:i=1, j=9。

然后计算出第三个数字,即 i+j=10,由于下一位是 9,因此第一部分为 "19"。

依次计算出第四个数字:i+j=19,截取字符串得到 "9100199",发现它不等于 19,因此这个枚举的结果不合法。

接下来继续枚举:i=9, j=1。

计算出第三个数字 i+j=10,由于第二部分以 0 开头,不合法。

接下来继续枚举:i=1, j=9。

计算出第三个数字 i+j=10,第一部分为 "19",第二部分为 "9"。

依次计算出第四个数字:i+j=19,截取字符串得到 "100199",不等于 19。

接下来继续枚举:i=9, j=1。

计算出第三个数字 i+j=10,第一部分为 "199",第二部分为 "1"。

依次计算出第四个数字:i+j=11,截取字符串得到 "00199",不等于 11。

接下来继续枚举:i=1, j=9。

计算出第三个数字 i+j=10,第一部分为 "1",第二部分为 "99100199"。

依次计算出第四个数字:i+j=9,截取字符串得到 "9100199",不等于 9。

接下来继续枚举:i=9, j=9。

由于第一个数字不能为 0,因此这个枚举的结果不合法。

因此,该字符串不是一个累加数。

代码实现

下面给出代码实现的主要部分,具体实现细节请参考代码注释。

func isAdditiveNumber(num string) bool {
    n := len(num)
    for i := 1; i <= n/2; i++ { // 枚举第一个数字的长度
        for j := 1; j <= (n-i)/2; j++ { // 枚举第二个数字的长度
            if check(num[:i], num[i:i+j], num[i+j:]) { // 如果找到了一个累加数直接返回 true
                return true
            }
            // 如果第二个数字以 0 开头,则不能继续往下枚举
            if num[i:i+j][0] == '0' {
                break
            }
        }
        // 如果第一个数字以 0 开头,则不能继续往下枚举
        if num[0] == '0' {
            break
        }
    }
    return false
}

// 判断是否为累加数
func check(s1, s2, s3 string) bool {
    for len(s3) > 0 { // 按照累加数的定义依次判断后面的数字序列
        if !strings.HasPrefix(s3, add(s1, s2)) {
            return false
        }
        s1, s2, s3 = s2, add(s1, s2), s3[len(add(s1, s2)):]
    }
    return true
}

// 计算两个字符串数字的和
func add(s1, s2 string) string {
    i, j, carry, sum := len(s1)-1, len(s2)-1, 0, []byte{}
    for i >= 0 || j >= 0 {
        n1, n2 := 0, 0
        if i >= 0 {
            n1 = int(s1[i] - '0')
            i--
        }
        if j >= 0 {
            n2 = int(s2[j] - '0')
            j--
        }
        tmp := n1 + n2 + carry
        sum = append(sum, byte(tmp%10)+'0')
        carry = tmp / 10
    }
    if carry > 0 {
        sum = append(sum, byte(carry)+'0')
    }
    // 由于我们计算结果时是从低位开始的,因此要将结果翻转一下
    for i, n := 0, len(sum); i < n/2; i++ {
        sum[i], sum[n-i-1] = sum[n-i-1], sum[i]
    }
    return string(sum)
}

总结

累加数问题实际上可以转化为一个回溯问题,但是优化后的暴力枚举已经足够应对该问题。在实现时需要注意细节,例如数字序列不能以 0 开头、要注意截取字符串的范围等等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go Java算法之累加数示例详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • java单点登录(SSO)的实现

    下面我将详细讲解Java单点登录(SSO)的实现攻略,主要分为以下几个步骤: 步骤一:准备工作 我们需要准备以下工具和环境: JDK 1.8或以上版本 Maven 3.0或以上版本 Servlet容器,如Tomcat或Jetty Spring Boot 2.0或以上版本 步骤二:配置SSO服务器和客户端 配置SSO服务器我们需要在SSO服务器上做以下配置: …

    Java 2023年5月18日
    00
  • Java+Ajax实现的用户名重复检验功能实例详解

    下面是关于“Java+Ajax实现的用户名重复检验功能实例详解”的完整攻略。 1. 概述 本篇攻略主要介绍如何使用Java和Ajax技术实现一个用户名重复检验功能。在用户填写用户名时,系统会自动检测该用户名是否已经被占用,如果已经被占用,则会提示用户重新填写。 2. 实现步骤 2.1 创建数据库 使用MySQL数据库,创建一个名为user的表,表中包含如下字…

    Java 2023年6月15日
    00
  • java实现贪吃蛇极速版

    Java实现贪吃蛇极速版攻略 简介 贪吃蛇又称为贪食蛇,是一款经典游戏。玩家通过控制贪吃蛇在游戏界面中不断地移动,吃到食物可以增加长度,同时避免撞到自己或游戏界面的边缘。 本文将详细讲解如何使用Java语言实现一个极速版的贪吃蛇游戏,并提供两个示例说明。 游戏功能设计 贪吃蛇移动(上、下、左、右)功能 食物随机生成并在地图上展示 碰撞检测,当贪吃蛇撞到自己或…

    Java 2023年5月23日
    00
  • 使用FileReader采用的默认编码

    使用FileReader对象默认采用的编码方式为UTF-8编码。但是,你也可以通过指定readAsText方法的第二个参数,来指定读取文件的编码方式。下面是使用FileReader对象进行文件读取的攻略: 步骤一:创建FileReader对象 在javascript中创建FileReader对象,可以使用下面的代码: var reader = new Fil…

    Java 2023年5月20日
    00
  • 教你如何写springboot接口

    教你如何写Spring Boot接口攻略 1. 确定项目需求和数据库设计 在编写Spring Boot接口前,需要先明确项目需求和数据库设计,包括接口需要实现哪些功能,数据表的关系等。这样才能确保编写出的接口满足项目需求。同时,我们还需要确定使用的数据库类型和数据库连接方式。 2. 创建Spring Boot项目 接下来我们需要使用Spring Initia…

    Java 2023年5月19日
    00
  • 使用java连接Redis,Maven管理操作

    使用Java连接Redis,本质上是通过Redis的Java客户端来实现。Java开发者可以通过Maven来管理Redis的Java客户端相关依赖,使开发变得更加简单高效。下面,我们将详细介绍如何使用Java连接Redis以及如何通过Maven管理Redis相关依赖。 第一步:引入Redis Java客户端依赖 要使用Java连接Redis,首先需要在Jav…

    Java 2023年5月19日
    00
  • java Springboot实现教务管理系统

    下面我将结合一些简单示例,分享一下实现Java Spring Boot教务管理系统的完整攻略。 概述 Java Spring Boot是一个快速开发框架,它可以让我们轻松创建RESTful API应用。教务管理系统是一种基于Web技术的应用程序,可以用于学校的教务管理。Java Spring Boot可以用于构建教务管理系统的后端。 教务管理系统的主要功能包…

    Java 2023年5月19日
    00
  • MyBatis-Plus动态表名的使用

    下面是关于MyBatis-Plus动态表名的使用的完整攻略。 1. 什么是MyBatis-Plus动态表名 MyBatis-Plus是MyBatis的一个增强工具包,提供了许多增强功能,其中之一就是动态表名。动态表名指的是,在一些场景下,我们需要在同一SQL语句中操作多张表,或者需要让表名根据不同的参数而动态变化,此时就可以使用MyBatis-Plus提供的…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部