Skip to content

Commit

Permalink
Solution to "Split a String Into the Max Number of Unique Substrings"
Browse files Browse the repository at this point in the history
problem
  • Loading branch information
dkoval committed Oct 21, 2024
1 parent 12c2ae3 commit 22c873b
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.github.dkoval.leetcode.challenge;

import java.util.HashSet;
import java.util.Set;

/**
* <a href="https://leetcode.com/problems/split-a-string-into-the-max-number-of-unique-substrings/">Split a String Into the Max Number of Unique Substrings</a>
* <p>
* Given a string s, return the maximum number of unique substrings that the given string can be split into.
* <p>
* You can split string s into any list of non-empty substrings, where the concatenation of the substrings forms the original string.
* However, you must split the substrings such that all of them are unique.
* <p>
* Constraints:
* <ul>
* <li>1 <= s.length <= 16</li>
* <li>s contains only lower case English letters.</li>
* </ul>
*/
public interface SplitStringIntoMaxNumberOfUniqueSubstrings {

int maxUniqueSplit(String s);

class SplitStringIntoMaxNumberOfUniqueSubstringsRev1 implements SplitStringIntoMaxNumberOfUniqueSubstrings {

@Override
public int maxUniqueSplit(String s) {
return calc(s, 0, new HashSet<>());
}

private int calc(String s, int start, Set<String> seen) {
if (start == s.length()) {
return 0;
}

// try every position to split s[start:]
// ... xxxxx | yyyyyyyyy
// ^ ^ <-------> a new sub-problem
// start end
int count = 0;
for (int end = start; end < s.length(); end++) {
String substr = s.substring(start, end + 1);
if (seen.contains(substr)) {
continue;
}
// apply backtracking technique
seen.add(substr);
count = Math.max(count, 1 + calc(s, end + 1, seen));
seen.remove(substr);
}
return count;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.github.dkoval.leetcode.challenge

import com.github.dkoval.leetcode.challenge.SplitStringIntoMaxNumberOfUniqueSubstrings.SplitStringIntoMaxNumberOfUniqueSubstringsRev1
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.ArgumentsProvider
import org.junit.jupiter.params.provider.ArgumentsSource
import java.util.stream.Stream

internal class SplitStringIntoMaxNumberOfUniqueSubstringsTest {

class InputArgumentsProvider : ArgumentsProvider {

override fun provideArguments(context: ExtensionContext): Stream<out Arguments> = Stream.of(
Arguments.of("ababccc", 5),
Arguments.of("aba", 2),
Arguments.of("aa", 1),
Arguments.of("wwwzfvedwfvhsww", 11)
)
}

@Nested
inner class SplitStringIntoMaxNumberOfUniqueSubstringsRev1Test {

@ParameterizedTest
@ArgumentsSource(InputArgumentsProvider::class)
fun `should return the maximum number of unique substrings that the given string can be split into`(
s: String,
expected: Int
) {
SplitStringIntoMaxNumberOfUniqueSubstringsRev1().test(s, expected)
}
}
}

private fun SplitStringIntoMaxNumberOfUniqueSubstrings.test(s: String, expected: Int) {
val actual = maxUniqueSplit(s)
assertEquals(expected, actual)
}

0 comments on commit 22c873b

Please sign in to comment.