Alice is attempting to type a specific string on her computer. However, she tends to be clumsy and may press a key for too long, resulting in a character being typed multiple times.
Although Alice tried to focus on her typing, she is aware that she may still have done this at mostonce.
You are given a string word, which represents the final output displayed on Alice’s screen.
Return the total number of possible original strings that Alice might have intended to type.
Since Alice may have pressed a key for too long at most once, the original string can be obtained by reducing the length of any one group of consecutive characters by any amount (including not reducing it at all). For each group, we can try all possible reductions (removing 0 up to all but one character from the group), and count the total number of unique original strings.
Group the string into consecutive runs of the same character.
For each group, consider reducing its length by any amount (from 0 up to the group length minus 1), but only for one group (since at most one long press).
For each group, generate the possible original strings by reducing that group, and add them to a set.
Always include the original string (no reduction).
classSolution {
public:int possibleStringCount(std::string word) {
std::vector<std::pair<char, int>> groups;
int n = word.size(), i =0;
while (i < n) {
int j = i;
while (j < n && word[j] == word[i]) ++j;
groups.push_back({word[i], j - i});
i = j;
}
std::set<std::string> st;
// Original string
std::string orig;
for (auto& [c, cnt] : groups) orig += std::string(cnt, c);
st.insert(orig);
for (int g =0; g < groups.size(); ++g) {
for (int reduce =1; reduce < groups[g].second; ++reduce) {
std::string s;
for (int k =0; k < groups.size(); ++k) {
int len = groups[k].second;
if (k == g) len -= reduce;
s += std::string(len, groups[k].first);
}
st.insert(s);
}
}
return st.size();
}
};
classSolution {
publicintpossibleStringCount(String word) {
List<int[]> groups =new ArrayList<>();
int n = word.length(), i = 0;
while (i < n) {
int j = i;
while (j < n && word.charAt(j) == word.charAt(i)) ++j;
groups.add(newint[]{word.charAt(i), j - i});
i = j;
}
Set<String> st =new HashSet<>();
StringBuilder orig =new StringBuilder();
for (int[] g : groups) for (int k = 0; k < g[1]; ++k) orig.append((char)g[0]);
st.add(orig.toString());
for (int g = 0; g < groups.size(); ++g) {
for (int reduce = 1; reduce < groups.get(g)[1]; ++reduce) {
StringBuilder sb =new StringBuilder();
for (int k = 0; k < groups.size(); ++k) {
int len = groups.get(k)[1];
if (k == g) len -= reduce;
for (int t = 0; t < len; ++t) sb.append((char)groups.get(k)[0]);
}
st.add(sb.toString());
}
}
return st.size();
}
}
classSolution {
funpossibleStringCount(word: String): Int {
val groups = mutableListOf<Pair<Char, Int>>()
var i = 0while (i < word.length) {
var j = i
while (j < word.length && word[j] == word[i]) j++ groups.add(word[i] to (j - i))
i = j
}
val st = mutableSetOf<String>()
val orig = buildString { for ((c, cnt) in groups) append(c.toString().repeat(cnt)) }
st.add(orig)
for (g in groups.indices) {
for (reduce in1 until groups[g].second) {
val s = buildString {
for ((k, group) in groups.withIndex()) {
var len = group.second
if (k == g) len -= reduce
append(group.first.toString().repeat(len))
}
}
st.add(s)
}
}
return st.size
}
}
classSolution:
defpossibleStringCount(self, word: str) -> int:
n = len(word)
groups = []
i =0while i < n:
j = i
while j < n and word[j] == word[i]:
j +=1 groups.append((word[i], j - i))
i = j
st = set()
orig =''.join(c * cnt for c, cnt in groups)
st.add(orig)
for g, (c, cnt) in enumerate(groups):
for reduce in range(1, cnt):
s =''.join(
(c2 * (cnt2 - reduce) if k == g else c2 * cnt2)
for k, (c2, cnt2) in enumerate(groups)
)
st.add(s)
return len(st)
impl Solution {
pubfnpossible_string_count(word: String) -> i32 {
let n = word.len();
let bytes = word.as_bytes();
letmut groups =vec![];
letmut i =0;
while i < n {
letmut j = i;
while j < n && bytes[j] == bytes[i] { j +=1; }
groups.push((bytes[i], j - i));
i = j;
}
use std::collections::HashSet;
letmut st = HashSet::new();
letmut orig = Vec::new();
for&(c, cnt) in&groups {
for _ in0..cnt { orig.push(c); }
}
st.insert(orig.clone());
for g in0..groups.len() {
for reduce in1..groups[g].1 {
letmut s = Vec::new();
for (k, &(c, cnt)) in groups.iter().enumerate() {
let len =if k == g { cnt - reduce } else { cnt };
for _ in0..len { s.push(c); }
}
st.insert(s);
}
}
st.len() asi32 }
}