<p>You are given a string <code>s</code>.</p>

<p>A split is called <strong>good</strong> if you can split <code>s</code> into two non-empty strings <code>s<sub>left</sub></code> and <code>s<sub>right</sub></code> where their concatenation is equal to <code>s</code> (i.e., <code>s<sub>left</sub> + s<sub>right</sub> = s</code>) and the number of distinct letters in <code>s<sub>left</sub></code> and <code>s<sub>right</sub></code> is the same.</p>

<p>Return <em>the number of <strong>good splits</strong> you can make in <code>s</code></em>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;aacaba&quot;
<strong>Output:</strong> 2
<strong>Explanation:</strong> There are 5 ways to split <code>&quot;aacaba&quot;</code> and 2 of them are good. 
(&quot;a&quot;, &quot;acaba&quot;) Left string and right string contains 1 and 3 different letters respectively.
(&quot;aa&quot;, &quot;caba&quot;) Left string and right string contains 1 and 3 different letters respectively.
(&quot;aac&quot;, &quot;aba&quot;) Left string and right string contains 2 and 2 different letters respectively (good split).
(&quot;aaca&quot;, &quot;ba&quot;) Left string and right string contains 2 and 2 different letters respectively (good split).
(&quot;aacab&quot;, &quot;a&quot;) Left string and right string contains 3 and 1 different letters respectively.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;abcd&quot;
<strong>Output:</strong> 1
<strong>Explanation:</strong> Split the string as follows (&quot;ab&quot;, &quot;cd&quot;).
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s.length &lt;= 10<sup>5</sup></code></li>
	<li><code>s</code> consists of only lowercase English letters.</li>
</ul>

class Solution:
    left_part_dict = {}
    right_part_dict = {}

    def numSplits(self, s: str) -> int:
        self.left_part_dict = {}
        self.right_part_dict = {}
        count = 0
        if len(s) <= 1:
            return 0
        else:
            # initializing the right part dict once
            for i in range(0, len(s)):
                c = s[i]
                if c not in self.right_part_dict:
                    self.right_part_dict[c] = 1
                else:
                    self.right_part_dict[c] = self.right_part_dict[c] + 1
            j = 1
            while j < len(s):
                part1 = s[0:j]
                part2 = s[j : len(s)]
                left_count = self.getUniqueElementsCount(part1, isLeft=True)
                right_count = self.getUniqueElementsCount(part2, isLeft=False,removed_element = part1[-1])
                if left_count == right_count:
                    count = count + 1
                j = j + 1
            return count

    def getUniqueElementsCount(self, s: str, isLeft=False,removed_element='') -> int:
        output_dict = {}
        if isLeft:
            c = s[-1]
            if c not in self.left_part_dict:
                self.left_part_dict[c] = 1
            else:
                self.left_part_dict[c] = self.left_part_dict[c] + 1
        else:
            if self.right_part_dict.get(removed_element,1) - 1 == 0:
                self.right_part_dict.pop(removed_element,False)
            else:
                self.right_part_dict[removed_element] = self.right_part_dict[removed_element] - 1

        return (
            len(self.left_part_dict.keys())
            if isLeft
            else len(self.right_part_dict.keys())
        )

        return count

17000