-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path1593.go
99 lines (86 loc) · 2.45 KB
/
1593.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Source: https://leetcode.com/problems/split-a-string-into-the-max-number-of-unique-substrings
// Split a String Into the Max Number of Unique Substrings
// Difficulty: Medium
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Given a string s, return the maximum number of unique substrings that the given string can be split into.
// 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.
// A substring is a contiguous sequence of characters within a string.
//
// Example 1:
//
// Input: s = "ababccc"
// Output: 5
// Explanation: One way to split maximally is ['a', 'b', 'ab', 'c', 'cc']. Splitting like ['a', 'b', 'a', 'b', 'c', 'cc'] is not valid as you have 'a' and 'b' multiple times.
//
// Example 2:
//
// Input: s = "aba"
// Output: 2
// Explanation: One way to split maximally is ['a', 'ba'].
//
// Example 3:
//
// Input: s = "aa"
// Output: 1
// Explanation: It is impossible to split the string any further.
//
// Constraints:
//
// 1 <= s.length <= 16
// s contains only lower case English letters.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package main
// Loop for all possible splits
func maxUniqueSplit(s string) int {
n := len(s) - 1
m := uint(1) << n
res := 0
OUTER:
for bits := uint(0); bits < m; bits++ {
words := make(map[string]bool, n+1)
// Construct split
substr := ""
for b := 0; b < n; b++ { // loop for bits
substr += string(s[b])
if (bits >> b & 1) == 1 {
if words[substr] {
continue OUTER
}
words[substr] = true
substr = ""
}
}
substr += string(s[n])
if words[substr] {
continue OUTER
}
words[substr] = true
res = max(res, len(words))
}
return res
}
// Backtracking
func maxUniqueSplit2(s string) int {
n := len(s)
seen := make(map[string]bool, 1<<n)
var backtrack func(start int) int
backtrack = func(start int) int {
if start == n {
return 0
}
maxSplits := 0
for end := start + 1; end <= n; end++ {
word := s[start:end]
if seen[word] {
continue
}
seen[word] = true
maxSplits = max(maxSplits, 1+backtrack(end))
seen[word] = false
}
return maxSplits
}
return backtrack(0)
}