leetcode1525. 字符串的好分割数目
给你一个字符串 s ,一个分割被称为 「好分割」 当它满足:将 s 分割成 2 个字符串 p 和 q ,它们连接起来等于 s 且 p 和 q 中不同字符的数目相同。
请你返回 s 中好分割的数目。
示例 1:
输入:s = “aacaba”
输出:2
解释:总共有 5 种分割字符串 “aacaba” 的方法,其中 2 种是好分割。
(“a”, “acaba”) 左边字符串和右边字符串分别包含 1 个和 3 个不同的字符。
(“aa”, “caba”) 左边字符串和右边字符串分别包含 1 个和 3 个不同的字符。
(“aac”, “aba”) 左边字符串和右边字符串分别包含 2 个和 2 个不同的字符。这是一个好分割。
(“aaca”, “ba”) 左边字符串和右边字符串分别包含 2 个和 2 个不同的字符。这是一个好分割。
(“aacab”, “a”) 左边字符串和右边字符串分别包含 3 个和 1 个不同的字符。
思路:
暴力解法是每次都显式地 将字符串分割为左右,即每次都去重新遍历左右子串来获取字符情况
这样时间复杂度是 O(n^2)
但是实际上每次移动的话只是一个字符,相当于左半部分滑窗增大,右半部分滑窗减小
那么我们就可以先统计整个字符串的字符出现情况,先将整个字符串作为右半部分,然后逐一缩减,左半部分逐渐增大
使用两个数组 leftCount 和 rightCount 记录左右两部分的各个字符出现次数
使用两个变量 leftVaild 和 rightVaild 记录左右两部分不同字符的出现次数
比如左半部分字符串为 “aabac”,右半部分字符串为 “acdd”
那么 leftValid = 3,因为有 a b c 三种不同的字符
那么 rightValid = 3,因为有 a c d 三种不同的字符
作者:suan-tou-wang-ba
链接:https://leetcode-cn.com/problems/number-of-good-ways-to-split-a-string/solution/leetcode-5458-wo-gan-jio-jiang-de-ying-gai-xiang-x/
代码:
class Solution {
public int numSplits(String s) {
//暴力破解
int res = 0;
int rigthvalid = 0;
int leftvalid = 0;
int[] rightnum = new int[26];
int[] leftnum = new int[26];
char[] chars = s.toCharArray();
for (char c : chars) {
if(rightnum[c-'a']==0)
rigthvalid++;
rightnum[c-'a']++;
}
for(char c:chars){
if(leftnum[c-'a']==0)
leftvalid++;
if(rightnum[c-'a']==1)
rigthvalid--;
leftnum[c-'a']++;
rightnum[c-'a']--;
if(leftvalid==rigthvalid)
res++;
}
return res;
}
}