【剑指Offer46-把数字翻译成字符串(DFS和动态规划)】

这篇博客探讨了一种使用深度优先搜索(DFS)和动态规划解决字符串解码问题的方法。题目要求根据给定的整数计算可能的字母数字解码方式数量。DFS通过递归遍历所有可能的拆分,而动态规划则从底向上计算每个数字的解空间。博主通过C++代码展示了两种方法,并提到动态规划可以避免重复计算,提高效率。
摘要由CSDN通过智能技术生成

题目:
在这里插入图片描述
这题我一开始想到的就是DFS遍历。因为之前有做过这种拆分问题。然后一看今天的每日一题(91.解码方法),好家伙,一摸一样。只不过那边的拆分需要进一步考虑‘0’的影响,但是本质上是一样的。

我们先来说说DFS的做法:
很简单,就是一直往下递归遍历就好了。只需要考虑每次是拆一个字符,还是拆两个字符,解空间类似一个二叉树。因为画图之后会发现有很多重复计算,所以用一个map数组去存储遍历到当前索引值的解个数。如果存在的话,说明已经计算过了,直接返回即可。

至于动态规划的做法,我觉得和DFS是一个反向的过程。DFS是一直拆解字符串,拆解到底层,然后逐一返回统计个数。动态规划更像是一开始就在计算,然后返回所有的个数。(当然,如果你要返回所有的解,还是要用DFS)

动态规划的思想是,对于每一个数字,都去考虑它是单独存在还是和前面结合存在。
如果可以单独存在的话,那么就等于去掉这个数字之后的所有解集。即dp【i】 = dp【i-1】
如果和前面结合起来存在的话,就相当于去掉这两个绑定数字之后的街机。即dp【i】 = dp【i-2】
那么,增加这个数字之后,总方案数就是这两种方案的和。
当然,这里需要判定是不是不满足题解条件,比如是否>25了。

C++(两种做法附带测试)

#include<iostream>
#include<vector>
#include<string>
#include<cstring>
#include<unordered_map>


using namespace std;

//class Solution {
//public:
//    int translateNum(int num) {
//		string s = to_string(num);
//		int n = s.size();
//		vector<int> dp(n+1,0);
//		dp[0] = 1;
//		dp[1] = 1;
//		for(int i=2;i<n+1;i++){
//			auto pre = s.substr(i - 2, 2);
//			if(pre <= "25" && pre >= "10"){
//				dp[i] = dp[i-1] + dp[i-2];
//			}else{
//				dp[i] = dp[i-1];
//			}
//		}
//		return dp[n];
//    }
//};


class Solution{
public:
	int backtrace(string& str,int pos,vector<int> map){
		int n  = str.size();
		if(pos>=n){
			return 1;
		}
		if(map[pos]!=-1){
			return map[pos];
		}
		if(pos==n-1||str[pos]=='0'||str.substr(pos,2)>"25"){
			return backtrace(str,pos+1,map);
		}
		return backtrace(str,pos+1,map)+ backtrace(str,pos+2,map);
	}
	
	int translateNum(int num){
		string str = to_string(num);
		vector<int> map(str.size(),-1);
		return backtrace(str,0,map);
	}
};



int main(){
	Solution solution;
	cout<<solution.translateNum(12258);
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值