<jupyter_start><jupyter_text>Number of Good Ways to Split a StringYou are given a string s, a split is called good if you can split s into 2 non-empty strings p and q where its concatenation is equal to s and the number of distinct letters in p and q are the same.Return the number of good splits you can make in s.  解析题目来源:[LeetCode - Number of Good Ways to Split a String - 1525](https://leetcode.com/problems/number-of-good-ways-to-split-a-string/)如果使用set的方式过滤左右两边的字符，再比较set长度，似乎是很好的办法，但是会消耗巨大的开销。观察整个过程，发现：**左右两边字符数量关系是左增右减**利用这个关系，就不再需要每次都使用set了，直接变换左右两边计数即可。<jupyter_code>from collections import Counter
def numSplits(s):
    count = 0
    left_map = Counter()
    right_map = Counter(s)
    
    for c in s:
        if c in left_map:
            left_map[c] += 1
        else:
            left_map[c] = 1
    
        right_map[c] -= 1

        if right_map[c] == 0:
            right_map.pop(c)
    
        if len(left_map.keys()) == len(right_map.keys()):
            count += 1
    return count
print(numSplits("acbadbaada"))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0947467166979362, 'fraction_numerical': 0.010318949343339587, 'mean_word_length': 3.011278195488722, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '410312', 'license': 'MIT', 'n_tokens_mistral': 439, 'n_tokens_neox': 449, 'n_words': 108, 'path': 'Number-of-Good-Ways-to-Split-a-String.ipynb', 'repo_name': 'AllenTom/Algorithm', 'size': '1066'}