首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >LeetCode 1638. 统计只差一个字符的子串数目(DP)

LeetCode 1638. 统计只差一个字符的子串数目(DP)

作者头像
Michael阿明
发布2021-02-19 12:43:16
发布2021-02-19 12:43:16
5960
举报

文章目录

1. 题目

给你两个字符串 s 和 t ,请你找出 s 中的非空子串的数目,这些子串满足替换 一个不同字符 以后,是 t 串的子串。 换言之,请你找到 s 和 t 串中 恰好 只有一个字符不同子字符串对的数目。

比方说, “computer” 和 “computation” 加粗部分只有一个字符不同: 'e'/'a' ,所以这一对子字符串会给答案加 1 。

请你返回满足上述条件的不同子字符串对数目。

一个 子字符串 是一个字符串中连续的字符。

代码语言:javascript
复制
示例 1:
输入:s = "aba", t = "baba"
输出:6
解释:以下为只相差 1 个字符的 s 和 t 串的子字符串对:
("aba", "baba")
("aba", "baba")
("aba", "baba")
("aba", "baba")
("aba", "baba")
("aba", "baba")
加粗部分分别表示 s 和 t 串选出来的子字符串。

示例 2:
输入:s = "ab", t = "bb"
输出:3
解释:以下为只相差 1 个字符的 s 和 t 串的子字符串对:
("ab", "bb")
("ab", "bb")
("ab", "bb")
加粗部分分别表示 s 和 t 串选出来的子字符串。

示例 3:
输入:s = "a", t = "a"
输出:0

示例 4:
输入:s = "abe", t = "bbc"
输出:10
 
提示:
1 <= s.length, t.length <= 100
s 和 t 都只包含小写英文字母。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/count-substrings-that-differ-by-one-character 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 暴力枚举

  • 枚举 s 的子串的开始位置 i, t 的子串的开始位置 j
  • 往后遍历,不同的字符个数为 1 的时候,答案 +1
  • 时间复杂度 O ( l e n ( s ) ∗ l e n ( t ) ∗ m i n ( l e n ( s ) , l e n ( t ) ) ) O(len(s)*len(t)*min(len(s), len(t))) O(len(s)∗len(t)∗min(len(s),len(t)))
代码语言:javascript
复制
class Solution {
public:
    int countSubstrings(string s, string t) {
    	int ans = 0, diff;
    	for(int i = 0; i < s.size(); ++i)
    	{
    		for(int j = 0; j < t.size(); ++j)
    		{
    			diff = 0;
    			for(int k = 0; i+k < s.size() && j+k < t.size(); ++k)
    			{
    				if(s[i+k] != t[j+k])
    					diff++;
    				if(diff == 1)
    					ans++;
    				else if(diff > 1)
    					break;
    			}
    		}
    	}
    	return ans;
    }
};

0 ms 6.4 MB

2.2 DP

参考 Zhenghao-Liu 大佬的解法

  • same[i][j], diff[i][j] 分别表示以 i 结尾的 s 的子串,以 j 结尾的 t 的子串,相同的数量,有一个字符不同的数量
  • 时间复杂度 O ( l e n ( s ) ∗ l e n ( t ) ) O(len(s)*len(t)) O(len(s)∗len(t))
代码语言:javascript
复制
class Solution {
public:
    int countSubstrings(string s, string t) {
    	int ans = 0, m = s.size(), n = t.size();
    	vector<vector<int>> same(m, vector<int>(n, 0)),
    						diff(m, vector<int>(n, 0));
    	for(int i = 0; i < m; ++i)
    	{	//初始化
    		same[i][0] = s[i]==t[0] ? 1 : 0;
    		diff[i][0] = s[i]==t[0] ? 0 : 1;
    	}
    	for(int j = 0; j < n; ++j)
    	{	//初始化
    		same[0][j] = s[0]==t[j] ? 1 : 0;
    		diff[0][j] = s[0]==t[j] ? 0 : 1;
    	}
    	for(int i = 1; i < m; ++i)
    	{
    		for(int j = 1; j < n; ++j)
    		{
    			if(s[i] == t[j])
    			{	//字符相同
    				same[i][j] = same[i-1][j-1]+1;
    						// 前面的数量跟我组合,以及 单个字符
    				diff[i][j] = diff[i-1][j-1];
    			}
    			else
    				diff[i][j] = same[i-1][j-1] + 1;
    		}
    	}
    	for(int i = 0; i < m; ++i)
    	{
    		for(int j = 0; j < n; ++j)
    		{
    			ans += diff[i][j];
    		}
    	}
    	return ans;
    }
};

4 ms 7.9 MB


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/11/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1. 题目
  • 2. 解题
    • 2.1 暴力枚举
    • 2.2 DP
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档