Skip to content

Commit 268b978

Browse files
committed
Implement count-unique-characters-of-all-substrings-of-a-given-string
name: count-unique-characters-of-all-substrings-of-a-given-string url: https://leetcode.com/problems/count-unique-characters-of-all-substrings-of-a-given-string difficulty: hard time: time-rank: time-complexity: O(N^2) space: space-rank: space-complexity: O(N^3) Fixes #281 This solution was not accepted by LeetCode due to memory usage. At some point, I'll need to come back and study it, because it can apparently be done in O(N) time and O(1) space. Signed-off-by: Christopher Friedt <[email protected]>
1 parent 59610a3 commit 268b978

File tree

2 files changed

+207
-0
lines changed

2 files changed

+207
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (c) 2021, Christopher Friedt
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#include <gtest/gtest.h>
8+
9+
#include "count-unique-characters-of-all-substrings-of-a-given-string.cpp"
10+
11+
using namespace std;
12+
13+
TEST(CountUniqueCharactersOfAllSubstringsOfAGivenString, ABC) {
14+
EXPECT_EQ(10, Solution().uniqueLetterString("ABC"));
15+
}
16+
17+
TEST(CountUniqueCharactersOfAllSubstringsOfAGivenString, ABA) {
18+
EXPECT_EQ(8, Solution().uniqueLetterString("ABA"));
19+
}
20+
21+
TEST(CountUniqueCharactersOfAllSubstringsOfAGivenString, LEETCODE) {
22+
EXPECT_EQ(92, Solution().uniqueLetterString("LEETCODE"));
23+
}
24+
25+
TEST(
26+
CountUniqueCharactersOfAllSubstringsOfAGivenString,
27+
DELQGVWNZKIJJPSXOVWWIZUXCEGWSQLESNSRBMKZARFPAXSVWQEZDENDAHNNIBHGHTFDLPGDLFXMIYRFNLMXHNPIFUAXINXPXLCTTJNLGGMKJIOEWBECNOFQPVCIKIAZMNGHEHFMCPWSMJTMGVSXTOGCGUYKFMNCGLCBRAFJLJVPIVDOLJBURULPGXBVDCEWXXXLTRMSHPKSPFDGNVOCZWDXJUWVNAREDOKTZMIUDKDQWWWSAEUUDBHMWZELOSBIHMAYJEMGZPMDOOGSCKLVHTGMETHUISCLJKDOQEWGVBULEMUXGTRKGXYFDIZTZWMLOFTCANBGUARNWQEQWGMIKMORVQUZANJNRNPMJWYLVHWKDFLDDBBMILAKGFROEQAMEVONUVHOHGPKLBPNYZFPLXNBCIFENCGIMIDCXIIQJWPVVCOCJTSKSHVMQJNLHSQTEZQTTMOXUSKBMUJEJDBJQNXECJGSZUDENJCPTTSREKHPRIISXMWBUGMTOVOTRKQCFSDOTEFPSVQINYLHXYVZTVAMWGPNKIDLOPGAMWSKDXEPLPPTKUHEKBQAWEBMORRZHBLOGIYLTPMUVBPGOOOIEBJEGTKQKOUURHSEJCMWMGHXYIAOGKJXFAMRLGTPNSLERNOHSDFSSFASUJTFHBDMGBQOKZRBRAZEQQVWFRNUNHBGKRFNBETEDJIWCTUBJDPFRRVNZENGRANELPHSDJLKVHWXAXUTMPWHUQPLTLYQAATEFXHZARFAUDLIUDEHEGGNIYICVARQNRJJKQSLXKZZTFPVJMOXADCIGKUXCVMLPFJGVXMMBEKQXFNXNUWOHCSZSEZWZHDCXPGLROYPMUOBDFLQMTTERGSSGVGOURDWDSEXONCKWHDUOVDHDESNINELLCTURJHGCJWVIPNSISHRWTFSFNRAHJAJNNXKKEMESDWGIYIQQRLUUADAXOUEYURQRVZBCSHXXFLYWFHDZKPHAGYOCTYGZNPALAUZSTOU) {
28+
EXPECT_EQ(
29+
629134,
30+
Solution().uniqueLetterString(
31+
"DELQGVWNZKIJJPSXOVWWIZUXCEGWSQLESNSRBMKZARFPAXSVWQEZDENDAHNNIBHGHTFD"
32+
"LPGDLFXMIYRFNLMXHNPIFUAXINXPXLCTTJNLGGMKJIOEWBECNOFQPVCIKIAZMNGHEHFM"
33+
"CPWSMJTMGVSXTOGCGUYKFMNCGLCBRAFJLJVPIVDOLJBURULPGXBVDCEWXXXLTRMSHPKS"
34+
"PFDGNVOCZWDXJUWVNAREDOKTZMIUDKDQWWWSAEUUDBHMWZELOSBIHMAYJEMGZPMDOOGS"
35+
"CKLVHTGMETHUISCLJKDOQEWGVBULEMUXGTRKGXYFDIZTZWMLOFTCANBGUARNWQEQWGMI"
36+
"KMORVQUZANJNRNPMJWYLVHWKDFLDDBBMILAKGFROEQAMEVONUVHOHGPKLBPNYZFPLXNB"
37+
"CIFENCGIMIDCXIIQJWPVVCOCJTSKSHVMQJNLHSQTEZQTTMOXUSKBMUJEJDBJQNXECJGS"
38+
"ZUDENJCPTTSREKHPRIISXMWBUGMTOVOTRKQCFSDOTEFPSVQINYLHXYVZTVAMWGPNKIDL"
39+
"OPGAMWSKDXEPLPPTKUHEKBQAWEBMORRZHBLOGIYLTPMUVBPGOOOIEBJEGTKQKOUURHSE"
40+
"JCMWMGHXYIAOGKJXFAMRLGTPNSLERNOHSDFSSFASUJTFHBDMGBQOKZRBRAZEQQVWFRNU"
41+
"NHBGKRFNBETEDJIWCTUBJDPFRRVNZENGRANELPHSDJLKVHWXAXUTMPWHUQPLTLYQAATE"
42+
"FXHZARFAUDLIUDEHEGGNIYICVARQNRJJKQSLXKZZTFPVJMOXADCIGKUXCVMLPFJGVXMM"
43+
"BEKQXFNXNUWOHCSZSEZWZHDCXPGLROYPMUOBDFLQMTTERGSSGVGOURDWDSEXONCKWHDU"
44+
"OVDHDESNINELLCTURJHGCJWVIPNSISHRWTFSFNRAHJAJNNXKKEMESDWGIYIQQRLUUADA"
45+
"XOUEYURQRVZBCSHXXFLYWFHDZKPHAGYOCTYGZNPALAUZSTOU"));
46+
}
47+
48+
TEST(
49+
CountUniqueCharactersOfAllSubstringsOfAGivenString,
50+
HJPNWLSNXDDEHVXKROILVYDDKFRFSKHKZCNJTKGHSSZOFUXNNJOYGHBNLICUNQRPPKBWWYZOZJXBZTJSXQXMZWARKJQWPVBUWCYGPNEQTHATPLQROFQGWWFMHZXJDDHYUPNLUZKKYSOFGQAWJYRWHFGDPKHIQGKPUPGDEONIPVPTKFQLUYTOGOLJIAEXRNXCKEOFQOJLTDJUUJCNJDJOHQBRZZZZNYMYRBBCJJMACDQYHPWTCMMLPJBQICTCVJGSWQYQCJCRIBFMYAJSODSQICWALLSZOQKXJSOSKXXSTDEAVAVNQNRJELSXXLERMAXMLGQAAEUVNEOVUMNEAZAEGTLZTLXHIHPQBAJJWJUJYORHLDXXBDOCKLRKLGVNOUBEGJRFRSCIGSEMPORRJKIYNCUGKKSEDFPUIQZBMWDAAGQLXIVXAWCCAVCRTELSCBEWRQAXVHKNXPYZDZJUHVOIZXKCXUXLLBKYYYGTQDNGPFFVDVTIVNBNLSURZROXYXCEVSOJBHJHUJQXENHLVLGZCSIBCXWOMFPYEVUMLJANFPJPYHSQXXNAEWKNPNUHPEFFDVTYJQVVYZJEOCTIVQWANNXUBSLXNFIIJADMAMUAXYPNVXAFPLJKZNYSXMYVZNFHVJFDTNYKVXRPANVPVFEDXUPOTPVYQJDXOWYZUDQVVGWPKYJNQLHBVPLHVHPMHLDJWUKQRRDNMAZFRGNNRYNTMLLYSXQJIAPVPEKZCPAYIJAMUAKKBSLWGCTPBQFFYWUEMLURPAYKECSWBQFPFBZGPOPJEXEQSAVXOTTFINNTQJUTNZROGAUJKTLRSNHBEYIROTXSVLTJQJKBXRXQOMTAJOXYTVKQBZSDXANTFQHZSSTBFSONMVQRXPLGRQLTMNNLANAJVIVUCDROTUOSMECCVKIQYSSWGYTKGNHCCRZVLIEPVGWPZBNYYHEMUPZQGZTGHIOZTYAENJEFNZCOFUGSYQYPUOKXGLKCEQOTZWYY) {
51+
EXPECT_EQ(
52+
637068,
53+
Solution().uniqueLetterString(
54+
"HJPNWLSNXDDEHVXKROILVYDDKFRFSKHKZCNJTKGHSSZOFUXNNJOYGHBNLICUNQRPPKBW"
55+
"WYZOZJXBZTJSXQXMZWARKJQWPVBUWCYGPNEQTHATPLQROFQGWWFMHZXJDDHYUPNLUZKK"
56+
"YSOFGQAWJYRWHFGDPKHIQGKPUPGDEONIPVPTKFQLUYTOGOLJIAEXRNXCKEOFQOJLTDJU"
57+
"UJCNJDJOHQBRZZZZNYMYRBBCJJMACDQYHPWTCMMLPJBQICTCVJGSWQYQCJCRIBFMYAJS"
58+
"ODSQICWALLSZOQKXJSOSKXXSTDEAVAVNQNRJELSXXLERMAXMLGQAAEUVNEOVUMNEAZAE"
59+
"GTLZTLXHIHPQBAJJWJUJYORHLDXXBDOCKLRKLGVNOUBEGJRFRSCIGSEMPORRJKIYNCUG"
60+
"KKSEDFPUIQZBMWDAAGQLXIVXAWCCAVCRTELSCBEWRQAXVHKNXPYZDZJUHVOIZXKCXUXL"
61+
"LBKYYYGTQDNGPFFVDVTIVNBNLSURZROXYXCEVSOJBHJHUJQXENHLVLGZCSIBCXWOMFPY"
62+
"EVUMLJANFPJPYHSQXXNAEWKNPNUHPEFFDVTYJQVVYZJEOCTIVQWANNXUBSLXNFIIJADM"
63+
"AMUAXYPNVXAFPLJKZNYSXMYVZNFHVJFDTNYKVXRPANVPVFEDXUPOTPVYQJDXOWYZUDQV"
64+
"VGWPKYJNQLHBVPLHVHPMHLDJWUKQRRDNMAZFRGNNRYNTMLLYSXQJIAPVPEKZCPAYIJAM"
65+
"UAKKBSLWGCTPBQFFYWUEMLURPAYKECSWBQFPFBZGPOPJEXEQSAVXOTTFINNTQJUTNZRO"
66+
"GAUJKTLRSNHBEYIROTXSVLTJQJKBXRXQOMTAJOXYTVKQBZSDXANTFQHZSSTBFSONMVQR"
67+
"XPLGRQLTMNNLANAJVIVUCDROTUOSMECCVKIQYSSWGYTKGNHCCRZVLIEPVGWPZBNYYHEM"
68+
"UPZQGZTGHIOZTYAENJEFNZCOFUGSYQYPUOKXGLKCEQOTZWYY"));
69+
}
70+
71+
TEST(
72+
CountUniqueCharactersOfAllSubstringsOfAGivenString,
73+
PNJBRGRPQSLSXPQBQKGGTUSHTKLLXHGXZBDMHNBZXKWZXTAANMHTOIRXHEYANOPLBVJROVZUDZNMETKKXRDMRHVMLDBHQTRIYGQFMBTZPPXGCLRJJYWHZZURDNTKWPNHLEJHFPPVQJAGSZCNUDMZWWCYUAQZGTUDMPJKLUQOSESLYGYWZKIXJQGHSOCVJQIGVXWQLOYUGFHCJSCJGHQMIGLGYAZWELSHZAPAEZQGMCMRMFRFZTTDGQUIZYDUCBVXZZUIDDCNWUAAPDUNZLBAGNIFNDBJYALQQGBRAMHBIVVERVXRTCSZSZWIGRLWZMUTEYSWZAGUDTPVLRJMOBUHOZBGHKHVOXAWCXMJNAZLQLKQQQNOCLUFGKOVBOKVKOEZEKNWHCFGCENVAABLPVTCEJVZNDTZNCRELHEDWLWIQGDBDGCTGUBZCZGTOVUFNCICJLWSMFDCRQEAGHUEVYEXQDHFFIKVECUAZRELOFJMYJJZNNJDKIMBKLRHSJUSBSTQHVLEJTJCCZQNZBVYFZXGAUDYOSCKYSMMINOANJMBAFHTNBRRZQAGLLWXLXMJANYFELMWRUFTLZUUHBSJEXOOBJKMYMLITIWJTDXSCOTZVZNVIXPDHNSXSODIEATIPIAODGCMDGYVZRJRVFCCMECCHXTIRAIQIJOWZWNRVRKOSIMQSDYRSCBONPPJTEYOEBNUOMRBIFRBQBTECLFQZTBBYROOMREHVFWTRVCODLLGJCTGUXEICJOUDMXBEVZRVRAVKIDNRICWSBNXMXVDCKZAHMQZBRLQUGTMJVOQBXARMLGJEQCORHNODVNOQFOMDPKRCOQOUDCPEOCHKHNHDGHBBYJIIYRVPKVSDYDIWOWCTGDZEHQAFDSZHJKTAYAYQCFVNAJQUQUQGFTPTRYAMLLXNSYSISFBEFNTDJWHZBWRVKRIHQXUOFBHRJKRIGJLDKRMUJQWAJGUFKSQEKMFAIJZSJIOTMCIVROAOEQPOIUD) {
74+
EXPECT_EQ(
75+
620286,
76+
Solution().uniqueLetterString(
77+
"PNJBRGRPQSLSXPQBQKGGTUSHTKLLXHGXZBDMHNBZXKWZXTAANMHTOIRXHEYANOPLBVJR"
78+
"OVZUDZNMETKKXRDMRHVMLDBHQTRIYGQFMBTZPPXGCLRJJYWHZZURDNTKWPNHLEJHFPPV"
79+
"QJAGSZCNUDMZWWCYUAQZGTUDMPJKLUQOSESLYGYWZKIXJQGHSOCVJQIGVXWQLOYUGFHC"
80+
"JSCJGHQMIGLGYAZWELSHZAPAEZQGMCMRMFRFZTTDGQUIZYDUCBVXZZUIDDCNWUAAPDUN"
81+
"ZLBAGNIFNDBJYALQQGBRAMHBIVVERVXRTCSZSZWIGRLWZMUTEYSWZAGUDTPVLRJMOBUH"
82+
"OZBGHKHVOXAWCXMJNAZLQLKQQQNOCLUFGKOVBOKVKOEZEKNWHCFGCENVAABLPVTCEJVZ"
83+
"NDTZNCRELHEDWLWIQGDBDGCTGUBZCZGTOVUFNCICJLWSMFDCRQEAGHUEVYEXQDHFFIKV"
84+
"ECUAZRELOFJMYJJZNNJDKIMBKLRHSJUSBSTQHVLEJTJCCZQNZBVYFZXGAUDYOSCKYSMM"
85+
"INOANJMBAFHTNBRRZQAGLLWXLXMJANYFELMWRUFTLZUUHBSJEXOOBJKMYMLITIWJTDXS"
86+
"COTZVZNVIXPDHNSXSODIEATIPIAODGCMDGYVZRJRVFCCMECCHXTIRAIQIJOWZWNRVRKO"
87+
"SIMQSDYRSCBONPPJTEYOEBNUOMRBIFRBQBTECLFQZTBBYROOMREHVFWTRVCODLLGJCTG"
88+
"UXEICJOUDMXBEVZRVRAVKIDNRICWSBNXMXVDCKZAHMQZBRLQUGTMJVOQBXARMLGJEQCO"
89+
"RHNODVNOQFOMDPKRCOQOUDCPEOCHKHNHDGHBBYJIIYRVPKVSDYDIWOWCTGDZEHQAFDSZ"
90+
"HJKTAYAYQCFVNAJQUQUQGFTPTRYAMLLXNSYSISFBEFNTDJWHZBWRVKRIHQXUOFBHRJKR"
91+
"IGJLDKRMUJQWAJGUFKSQEKMFAIJZSJIOTMCIVROAOEQPOIUD"));
92+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright (c) 2021, Christopher Friedt
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#include <unordered_map>
8+
#include <unordered_set>
9+
#include <vector>
10+
11+
using namespace std;
12+
13+
// clang-format off
14+
// name: count-unique-characters-of-all-substrings-of-a-given-string
15+
// url: https://leetcode.com/problems/count-unique-characters-of-all-substrings-of-a-given-string
16+
// difficulty: 3
17+
// clang-format on
18+
19+
// static vector<string> msgs;
20+
21+
class Solution {
22+
public:
23+
using dp1_t = vector<vector<size_t>>;
24+
using dp2_t = vector<vector<vector<size_t>>>;
25+
26+
int uniqueLetterString(string s) {
27+
28+
const size_t N = s.size();
29+
dp1_t dp1 = dp1_t(N, vector<size_t>(N, -1));
30+
dp2_t dp2 = dp2_t(N, dp1_t(N, vector<size_t>(26, -1)));
31+
32+
// for string s, with indices L, R where L <= R
33+
// UC(s,L,R) = 1, if L == R
34+
// = UC(s,L,R-1) + 1, count(s,L,R-1,s[R]) == 0
35+
// = UC(s,L,R-1) - 1, count(s,L,R-1,s[R]) == 1
36+
// = UC(s,L,R-1) , otherwise
37+
//
38+
// count(s,L,R,c) = count(s,L,R-1,c) + 1, c == s[R]
39+
// = count(s,L,R-1,c) , c != s[R]
40+
// = 1, L == R AND s[L] == c
41+
// = 0, L == R AND s[L] != c
42+
43+
size_t num = 0;
44+
for (size_t L = 0, N = s.size(); L < N; ++L) {
45+
for (size_t R = N; R > L; --R) {
46+
num += UC(dp1, dp2, s, L, R - 1);
47+
}
48+
}
49+
50+
// for(auto& m: msgs) {
51+
// cout << m << endl;
52+
// }
53+
54+
return num;
55+
}
56+
57+
static size_t count(dp2_t &dp2, const string &s, size_t L, size_t R, char c) {
58+
auto &n = dp2[L][R][c - 'A'];
59+
if (n != size_t(-1)) {
60+
return n;
61+
}
62+
63+
if (L == R) {
64+
n = s[L] == c;
65+
// msgs.push_back("count(" + s.substr(L, R - L + 1) + ", " + string(1,c) +
66+
// "): " + to_string(n));
67+
return n;
68+
}
69+
70+
auto m = count(dp2, s, L, R - 1, c);
71+
if (s[R] == c) {
72+
m++;
73+
}
74+
75+
n = m;
76+
// msgs.push_back("count(" + s.substr(L, R - L + 1) + ", " + string(1,c) +
77+
// "): " + to_string(n));
78+
return n;
79+
}
80+
81+
static size_t UC(dp1_t &dp1, dp2_t &dp2, const string &s, size_t L,
82+
size_t R) {
83+
84+
auto &n = dp1[L][R];
85+
if (n != size_t(-1)) {
86+
return n;
87+
}
88+
89+
if (L == R) {
90+
n = 1;
91+
// msgs.push_back("UC(" + s.substr(L, R - L + 1) + "): " + to_string(n));
92+
return n;
93+
}
94+
95+
n = UC(dp1, dp2, s, L, R - 1);
96+
auto m = count(dp2, s, L, R - 1, s[R]);
97+
98+
switch (m) {
99+
case 0:
100+
++n;
101+
break;
102+
case 1:
103+
--n;
104+
break;
105+
default:
106+
break;
107+
}
108+
109+
++m;
110+
dp2[L][R][s[R] - 'A'] = m;
111+
112+
// msgs.push_back("UC(" + s.substr(L, R - L + 1) + "): " + to_string(n));
113+
return n;
114+
}
115+
};

0 commit comments

Comments
 (0)