【C++动态规划】3144. 分割字符频率相等的最少子字符串|1917

本文涉及知识点

C++动态规划 划分型

LeetCode3144. 分割字符频率相等的最少子字符串

给你一个字符串 s ,你需要将它分割成一个或者更多的 平衡 子字符串。比方说,s == "ababcc" 那么 ("abab", "c", "c") ,("ab", "abc", "c") 和 ("ababcc") 都是合法分割,但是 ("a", "bab", "cc") ,("aba", "bc", "c") 和 ("ab", "abcc") 不是,不平衡的子字符串用粗体表示。

请你返回 s 最少 能分割成多少个平衡子字符串。

注意:一个 平衡 字符串指的是字符串中所有字符出现的次数都相同。

示例 1:

输入:s = "fabccddg"

输出:3

解释:

我们可以将 s 分割成 3 个子字符串:("fab, "ccdd", "g") 或者 ("fabc", "cd", "dg") 。

示例 2:

输入:s = "abababaccddb"

输出:2

解释:

我们可以将 s 分割成 2 个子字符串:("abab", "abaccddb") 。

提示:

1 <= s.length <= 1000

s 只包含小写英文字母。

动态规划 划分型

Isij记录si...j是否是平衡字符串。cntk记录numsi...j中字符ch-'a'的数量。numsi...j迭代成numsi...j+1时,只需要 k =numsj+1-'a', cntk++。

cnt1记录cnt中,非0字符的数量。cnt1 +=(1==cntk)。

iMax 记录 最多字符的数量。iMax = max(iMax,cntk)。

isij = (j-i+1) == iMax*cnt1。

动态规划的状态表示

dpi 表示划分完前i个元素的最少子串。空间复杂度😮(n)。

动态规划的填报顺序

枚举前置状态 i = 0 to n-1

动态规划的转移方程

如果Isij成立

MinSelf(dpj+1,dpi+1)

单个状态转移时间复杂度:O(n) 总时间复杂度:O(nn)。

动态规划的初始值

dp0=0,其它全部为INT_MAX/2。

动态规划的返回值

dp.back

代码

核心代码

cpp 复制代码
class Solution {
		public:
			int minimumSubstringsInPartition(string s) {
				const int N = s.length();
				vector<vector<bool>> can(N, vector<bool>(N));
				for (int i = 0; i < N; i++) {
					int cnt[26] = { 0 };
					int cnt1=0, iMax = 0;
					for (int j = i; j < N; j++) {
						auto& tmp = cnt[s[j] - 'a'];
						tmp ++;
						cnt1 += (1 == tmp);
						iMax = max(iMax, tmp);
						can[i][j] = (iMax * cnt1 == j - i + 1);
					}
				}
				vector<int> dp(N + 1, N);
				dp[0] = 0;
				for (int i = 0; i < N; i++) {
					for (int j = i; j < N; j++) {
						if (!can[i][j])continue;
						dp[j + 1] = min(dp[j + 1], dp[i] + 1);
					}
				}
				return dp.back();
			}
		};

单元测试

cpp 复制代码
	string s;
		TEST_METHOD(TestMethod11)
		{
			s = "fabccddg";
			auto res = Solution().minimumSubstringsInPartition(s);
			AssertEx(3, res);
		}
		TEST_METHOD(TestMethod12)
		{
			s = "abababaccddb";
			auto res = Solution().minimumSubstringsInPartition(s);
			AssertEx(2, res);
		}
		TEST_METHOD(TestMethod13)
		{
			s="abbcabaa";
			auto res = Solution().minimumSubstringsInPartition(s);
			AssertEx(4, res);
		}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关推荐
奇妙之二进制几秒前
机器人导航路径规划算法入门(6)Dijkstra(迪杰斯特拉)算法深入解析
算法·导航
重生的黑客1 分钟前
Qt 常用控件精讲(1):QWidget 核心属性全解 —— 从 geometry 到 qrc 与 QSS
c++·qt·qwidget·qss·常用控件
Hespethorn15 分钟前
取 `X-Forwarded-For` 首段做频控 key,等于把限流开关交给了调用方
c++
米糕闯编程15 分钟前
鱼香ros2(七)功能包组织C++节点
c++·ros2·cmakelists
Niuguangshuo22 分钟前
论文解读:Qwen2-Audio,阿里的通用音频语言模型
算法·音视频·语音识别
汉克老师38 分钟前
GESP2026年9月认证C++四级( 第三部分编程题(1、新汉诺塔))精讲
c++·gesp·小学生·学c++编程
唠玖馆2 小时前
智能指针详解
c++
WiChP2 小时前
【V0.1B16】从零开始的2D游戏引擎开发之路
开发语言·算法·游戏引擎
ShineWinsu2 小时前
对于Git:基础操作的超详细保姆级解析
linux·c++·git·面试·备份·管理·版本控制器
番茄巴士2 小时前
手写一个 mini HashMap,彻底搞懂哈希表原理
算法