zoukankan      html  css  js  c++  java
  • 【LeetCode每日一题】2020.6.9 面试题46. 把数字翻译成字符串

    面试题46. 把数字翻译成字符串

    给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

    示例:

    输入: 12258
    输出: 5
    解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"

    分析:

    动态规划:

    ​ 对数字的每一位,都有两种选择:走1步(翻译一个数字)或者走2步(翻译两个数字)。因此我们可以在草稿纸上画出一个树的结构。

    ​ 仔细分析上图,我们可以看出,有许多重复计算的地方。

    ​ 如果在递归算法中反复求解同堂的子问题,我们就把这种性质称作重叠子问题。这是适合用动态规划方法求解的最优化问题应该具备的性质。

    ​ 因此我们就可以想到利用动态规划来求解问题。

    滚动数组:

    ​ 动态规划的空间复杂度一般为O(n),实际上对于很多问题都有提升的空间。例如本题:我们不需要存储所有下标为i的数字翻译方式。只需要得到i为最后一位的结果。在此过程中,只需要不断更新i-2i-1位置上的结果就满足要求。这就是利用滚动数组思想来降低动态规划的时间复杂度。

    代码:

    package main
    
    import (
    	"fmt"
    	"strconv"
    )
    
    // 直接递归
    func translateNum1(num int) int {
    	str := strconv.Itoa(num)
    	var dfs func(str string, index int) int
    	dfs = func(str string, index int) int {
    		if index >= len(str) - 1 {
    			return 1
    		}
    		temp := int(str[index] - '0') * 10 + int(str[index + 1] - '0')
    		if temp >= 10 && temp <= 25 {
    			return dfs(str, index + 1) + dfs(str, index + 2)
    		} else {
    			return dfs(str, index + 1)
    		}
    	}
    	return dfs(str, 0)
    }
    
    // 递归加备忘
    func translateNum2(num int) int {
    	str := strconv.Itoa(num)
    	memo := make([]int, len(str))
    	var dfs func(str string, index int) int
    	dfs = func(str string, index int) int {
    		if index >= len(str) - 1 {
    			return 1
    		}
    		if memo[index] != 0 {
    			return memo[index]
    		}
    		temp := int(str[index] - '0') * 10 + int(str[index + 1] - '0')
    		if temp >= 10 && temp <= 25 {
    			memo[index] = dfs(str, index + 1) + dfs(str, index + 2)
    		} else {
    			memo[index] = dfs(str, index + 1)
    		}
    		return memo[index]
    	}
    	return dfs(str, 0)
    }
    
    // 自底向上
    func translateNum3(num int) int {
    	str := strconv.Itoa(num)
    	n := len(str)
    	// dp[i]保存前i个数有多少中翻译方式
    	dp := make([]int, n + 1)  // 多存储一位,以方便理解
    	dp[0] = 1
    	dp[1] = 1
    	for i := 2; i < n + 1; i++ {
    		temp := int(str[i - 2] - '0') * 10 + int(str[i - 1] - '0')
    		if temp >= 10 && temp <= 25 {
    			dp[i] = dp[i - 2] + dp[i - 1]
    		} else {
    			dp[i] = dp[i - 1]
    		}
    	}
    	return dp[n]
    }
    
    // 利用滚动数组压缩空间复杂度
    func translateNum4(num int) int {
    	str := strconv.Itoa(num)
    	n := len(str)
    	prev := 1
    	cur := 1
    	for i := 2; i < n + 1; i++ {
    		temp := int(str[i - 2] - '0') * 10 + int(str[i - 1] - '0')
    		if temp >= 10 && temp <= 25 {
    			tmp := cur
    			cur = prev + cur
    			prev = tmp
    		} else {
    			prev = cur
    		}
    	}
    	return cur
    }
    
  • 相关阅读:
    IDEA 基本配置
    IDEA 创建一个普通的java项目
    Intellij Idea 创建一个Web项目
    override的实现原理
    elasticsearch 复杂查询小记
    post 中文数据到elasticsearch restful接口报json_parse_exception 问题
    String intern()方法详解
    JVM的DirectMemory设置
    深入浅出 JIT 编译器
    为什么 JVM 不用 JIT 全程编译
  • 原文地址:https://www.cnblogs.com/enmac/p/13081443.html
Copyright © 2011-2022 走看看