3144:给你一个字符串 s
,你需要将它分割成一个或者更多的 平衡 子字符串。比方说,s == "ababcc"
那么 ("abab", "c", "c")
,("ab", "abc", "c")
和 ("ababcc")
都是合法分割,但是 ("a", "bab", "cc")
,("aba", "bc", "c")
和 ("ab", "abcc")
不是,不平衡的子字符串用粗体表示。
请你返回 s
最少 能分割成多少个平衡子字符串。
注意:一个 平衡 字符串指的是字符串中所有字符出现的次数都相同。
思路:从右向左回溯,当当前子串是平衡字符串时,再dfs(由于越靠近左边每次dfs 都会重复,为了提高效率,使用记忆化搜索)。
class Solution {
public:
int dp[1010];
int minimumSubstringsInPartition(string s) {
int ns=s.size();
auto dfs = [&](auto &&dfs,int i) -> int{
if(i<0) return 0;
int &res=dp[i];
if(res) return res;
res=INT_MAX;
int cnt[26]{},k=0,max_cnt=0;
for(int j=i;j>=0;j--)
{
k+= cnt[s[j]-'a']++ == 0;
max_cnt=max(max_cnt,cnt[s[j]-'a']);
if(i-j+1 == k*max_cnt)
{
res = min(res,dfs(dfs,j-1)+1);
}
}
return res;
};
return dfs(dfs,ns-1);
}
};
698:给定一个整数数组 nums
和一个正整数 k
,找出是否有可能把这个数组分成 k
个非空子集,其总和都相等。
class Solution {
public:
bool canPartitionKSubsets(vector<int>& nums, int k) {
int s=accumulate(nums.begin(),nums.end(),0);
if(s%k) return false;
s/=k;
int n=nums.size();
vector<int> cur(k);
auto dfs=[&](auto&&dfs ,int i)-> bool{
if(i==n) return true;
for(int j=0;j<k;j++)
{
if(j&&cur[j]==cur[j-1]) continue;
cur[j]+=nums[i];
if(cur[j]<=s&&dfs(dfs,i+1))
{
return true;
}
cur[j]-=nums[i];
}
return false;
};
sort(nums.begin(),nums.end(),greater<int>());
return dfs(dfs,0);
}
};