Skip to content

Commit 24f147f

Browse files
authored
Merge pull request codeharborhub#1694 from SadafKausar2025/minimum-substring
Added leetcode 3144 solutions
2 parents 1898caf + b57dcdb commit 24f147f

File tree

2 files changed

+253
-1
lines changed

2 files changed

+253
-1
lines changed

dsa-problems/leetcode-problems/3100-3199.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ export const problems = [
278278
"problemName": "3144. Minimum Substring Partition of Equal Character Frequency",
279279
"difficulty": "Medium",
280280
"leetCodeLink": "https://leetcode.com/problems/minimum-substring-partition-of-equal-character-frequency",
281-
"solutionLink": "#"
281+
"solutionLink": "/dsa-solutions/lc-solutions/3100-3199/minimum-substring-partition-of-equal-charater-frequency"
282282
},
283283
{
284284
"problemName": "3145. Find Products of Elements of Big Array",
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
---
2+
id: minimum-substring-partition-of-equal-charater-frequency
3+
title: Minimum-substring-partition-of-equal-charater-frequency (LeetCode)
4+
sidebar_label: 3144-minimum-substring-partition-of-equal-charater-frequency
5+
tags:
6+
- Dynamic Programming
7+
- Geometry
8+
- Sorting
9+
- Sliding Window
10+
description: this discription is for the solution of minimum-substring-partition-of-equal-charater-frequency
11+
sidebar_position: 3144
12+
---
13+
14+
## Problem Satement
15+
16+
Given a string s, you need to partition it into one or more balanced
17+
substrings
18+
Substring
19+
A substring is a contiguous sequence of characters within a string.
20+
21+
. For example, if `s == "ababcc"` then `("abab", "c", "c")`, `("ab", "abc", "c")`, and `("ababcc")` are all valid partitions, but `("a", "bab", "cc")`, `("aba", "bc", "c")`, and `("ab", "abcc")` are not. The unbalanced substrings are bolded.
22+
23+
Return the minimum number of substrings that you can partition s into.
24+
25+
Note: A balanced string is a string where each character in the string occurs the same number of times.
26+
27+
**Example 1:**
28+
29+
Input: s = "fabccddg"
30+
Output: 3
31+
32+
Explanation:
33+
We can partition the string s into 3 substrings in one of the following ways: ("fab, "ccdd", "g"), or ("fabc", "cd", "dg").
34+
35+
**Example 2:**
36+
37+
Input: s = "abababaccddb"
38+
Output: 2
39+
40+
Explanation:
41+
We can partition the string s into 2 substrings like so: ("abab", "abaccddb").
42+
43+
**Constraints:**
44+
45+
- `1 <= s.length <= 1000`
46+
- `s consists only of English lowercase letters.`
47+
48+
## Solutions:
49+
50+
### Intuition
51+
52+
The problem requires partitioning a string such that each substring is balanced. A substring is balanced if each character appears with the same frequency within that substring. The challenge is to minimize the number of these substrings. This problem can be addressed by understanding the distribution of character frequencies and leveraging dynamic programming to minimize partitions while ensuring that each segment conforms to the balanced condition.
53+
54+
### Approach
55+
56+
- **Character Frequency Calculation:**
57+
- Calculate the maximum frequency for each character in the entire string. This will help determine if a substring can potentially be balanced, as every character in a balanced substring must appear at least as many times as its maximum frequency across the string.
58+
59+
- **Dynamic Programming Initialization:**
60+
- Use a DP array dp where dp[i] represents the minimum number of partitions needed for the first i characters of the string. Initialize dp[0] to 0 because no partitions are needed for an empty string.
61+
62+
- **Sliding Window for Substrings:**
63+
- For each position i in the string, consider every possible substring ending at i and starting from any j (where j ranges from 1 to i). This forms a sliding window from j to i.
64+
65+
- For each window, maintain a frequency count of characters and determine the maximum frequency in the current window.
66+
67+
- **Validation and DP Update:**
68+
- Validate each window by checking if all characters that appear have the frequency equal to the maximum frequency observed in that window. If the substring formed by the window is balanced, then update dp[i] to be the minimum of its current value or dp[j-1] + 1.
69+
70+
- This ensures that dp[i] reflects the minimum partitions up to i including possibly ending a new balanced substring at i.
71+
72+
- **Result Extraction:**
73+
- After processing all characters, dp[length of string] contains the minimum number of partitions for the entire string.
74+
75+
## code:
76+
77+
<Tabs>
78+
<TabItem value="cpp" label="C++" default>
79+
<SolutionAuthor name="@Ajay-Dhangar"/>
80+
```cpp
81+
public:
82+
int minimumSubstringsInPartition(string s) {
83+
vector<int> maxFrequency(26, 0);
84+
for (char ch : s) {
85+
maxFrequency[ch - 'a']++;
86+
}
87+
88+
vector<int> dp(s.length() + 1, INT_MAX);
89+
dp[0] = 0; // Base case: no characters, no partitions needed
90+
91+
for (int i = 1; i <= s.length(); i++) {
92+
vector<int> freq(26, 0);
93+
int maxInWindow = 0;
94+
95+
for (int j = i; j > 0; j--) {
96+
int index = s[j - 1] - 'a';
97+
freq[index]++;
98+
maxInWindow = max(maxInWindow, freq[index]);
99+
100+
bool valid = true;
101+
for (int k = 0; k < 26; k++) {
102+
if (freq[k] > 0 && freq[k] < maxInWindow) {
103+
valid = false;
104+
break;
105+
}
106+
}
107+
108+
if (valid) {
109+
dp[i] = min(dp[i], dp[j - 1] + 1);
110+
}
111+
}
112+
}
113+
return dp[s.length()];
114+
}
115+
```
116+
</TabItem>
117+
<TabItem value="java" label="Java">
118+
<SolutionAuthor name="@Ajay-Dhangar"/>
119+
```java
120+
public int minimumSubstringsInPartition(String s) {
121+
// Initialize an array to store the maximum frequency of each character
122+
int[] maxFrequency = new int[26]; // Array to hold maximum frequency of each character 'a' to 'z'
123+
for (int i = 0; i < s.length(); i++) {
124+
maxFrequency[s.charAt(i) - 'a']++; // Increment frequency of character at position i
125+
}
126+
127+
// dp[i] represents the minimum number of partitions needed for the first i characters
128+
int[] dp = new int[s.length() + 1]; // Array to hold the minimum partitions needed for each prefix of s
129+
dp[0] = 0; // Base case: no characters, no partitions needed
130+
131+
for (int i = 1; i <= s.length(); i++) {
132+
dp[i] = Integer.MAX_VALUE; // Initialize dp[i] with a large number
133+
int[] freq = new int[26]; // Array to keep track of character frequencies in the current window
134+
int maxInWindow = 0; // Variable to store the maximum frequency in the current window
135+
136+
// Check all substrings that end at position i
137+
for (int j = i; j > 0; j--) {
138+
char c = s.charAt(j - 1); // Get character in the string at position j-1
139+
freq[c - 'a']++; // Increment frequency of that character in the current window
140+
maxInWindow = Math.max(maxInWindow, freq[c - 'a']); // Update maxInWindow if current frequency is higher
141+
142+
// Check if the current window can form a balanced substring
143+
boolean isValid = true; // Flag to check if the window is valid
144+
for (int k = 0; k < 26; k++) {
145+
if (freq[k] > 0 && freq[k] < maxInWindow) {
146+
isValid = false; // Set valid to false if any character frequency is less than maxInWindow
147+
break; // Exit the loop as the substring is not valid
148+
}
149+
}
150+
151+
if (isValid) { // If the window is valid
152+
dp[i] = Math.min(dp[i], dp[j - 1] + 1); // Update dp[i] with the minimum partitions found
153+
}
154+
}
155+
}
156+
return dp[s.length()]; // Return the minimum number of partitions for the entire string
157+
}
158+
```
159+
</TabItem>
160+
<TabItem value="python" label="Python">
161+
<SolutionAuthor name="@Ajay-Dhangar"/>
162+
```python
163+
def minimumSubstringsInPartition(self, s):
164+
# Initialize an array to store the maximum frequency of each character
165+
max_frequency = [0] * 26
166+
for char in s:
167+
max_frequency[ord(char) - ord('a')] += 1
168+
169+
# dp[i] represents the minimum number of partitions needed for the first i characters
170+
dp = [float('inf')] * (len(s) + 1)
171+
dp[0] = 0 # Base case: no characters, no partitions needed
172+
173+
for i in range(1, len(s) + 1):
174+
freq = [0] * 26
175+
max_in_window = 0
176+
177+
# Check all substrings that end at position i
178+
for j in range(i, 0, -1):
179+
index = ord(s[j - 1]) - ord('a')
180+
freq[index] += 1
181+
max_in_window = max(max_in_window, freq[index])
182+
183+
# Check if the current window can form a balanced substring
184+
valid = True
185+
for k in range(26):
186+
if freq[k] > 0 and freq[k] < max_in_window:
187+
valid = False
188+
break
189+
190+
if valid:
191+
dp[i] = min(dp[i], dp[j - 1] + 1)
192+
193+
return dp[len(s)]
194+
```
195+
</TabItem>
196+
<TabItem value="c" label="C">
197+
<SolutionAuthor name="@Ajay-Dhangar"/>
198+
```c
199+
int minimumSubstringsInPartition(char* s) {
200+
int len = strlen(s);
201+
int maxFrequency[26] = {0}, dp[len + 1], freq[26], i, j, k, maxInWindow;
202+
for (i = 0; s[i]; i++) {
203+
maxFrequency[s[i] - 'a']++;
204+
}
205+
206+
dp[0] = 0; // Base case
207+
for (i = 1; i <= len; i++) {
208+
dp[i] = INT_MAX;
209+
memset(freq, 0, sizeof(freq));
210+
maxInWindow = 0;
211+
212+
for (j = i; j > 0; j--) {
213+
char c = s[j - 1];
214+
freq[c - 'a']++;
215+
if (freq[c - 'a'] > maxInWindow) maxInWindow = freq[c - 'a'];
216+
217+
int valid = 1;
218+
for (k = 0; k < 26; k++) {
219+
if (freq[k] > 0 && freq[k] < maxInWindow) {
220+
valid = 0;
221+
break;
222+
}
223+
}
224+
225+
if (valid) {
226+
if (dp[j - 1] + 1 < dp[i]) dp[i] = dp[j - 1] + 1;
227+
}
228+
}
229+
}
230+
231+
return dp[len];
232+
233+
}
234+
```
235+
236+
</TabItem>
237+
238+
</Tabs>
239+
240+
## Complexity
241+
242+
**Time complexity:** $O(n^3)$ - The solution involves three nested loops: The outermost loop runs for each character i in the string. For each i, the middle loop considers every possible starting point j for substrings ending at i, and the innermost loop iterates through all 26 characters to ensure the substring from j to i is balanced.
243+
244+
-This results in a time complexity proportional to `n^2` multiplied by a constant factor (26), simplifying to $O(n^3)$.
245+
246+
**Space complexity:** $O(n + 26)$
247+
248+
- $O(n)$ for the dynamic programming array dp which stores the minimum partitions for each substring ending at each position.
249+
250+
- $O(26)$ (constant space) for the frequency array used in each sliding window to keep track of character counts. This part is constant since the number of characters (English lowercase letters) does not scale with n.
251+
252+
This algorithm efficiently handles smaller strings and provides a clear method to determine minimal partitions, but it might be computationally intensive for very large strings due to its cubic time complexity.

0 commit comments

Comments
 (0)