-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsolution.cpp
More file actions
135 lines (116 loc) · 3.95 KB
/
Copy pathsolution.cpp
File metadata and controls
135 lines (116 loc) · 3.95 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* Problem: 466. Count The Repetitions
* Difficulty: Hard
* Topics: String, Dynamic Programming, Two Pointers
* LeetCode Link: https://leetcode.com/problems/count-the-repetitions/
*
* Time Complexity: O(|s1| * |s2|) - Cycle is guaranteed within |s2| + 1 blocks of s1
* Space Complexity: O(|s2|) - Storing index states for cycle detection
*/
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <cassert>
using namespace std;
class Solution {
public:
int getMaxRepetitions(string s1, int n1, string s2, int n2) {
int len1 = s1.length();
int len2 = s2.length();
// Maps s2_index -> {s1_count, s2_count} observed at the end of an s1 block
unordered_map<int, pair<int, int>> seen;
int s2Idx = 0;
int s2Count = 0;
int s1Count = 0;
while (s1Count < n1) {
s1Count++;
// Match current s1 block against s2
for (int i = 0; i < len1; ++i) {
if (s1[i] == s2[s2Idx]) {
s2Idx++;
if (s2Idx == len2) {
s2Count++;
s2Idx = 0;
}
}
}
// Check if we have encountered this s2Idx state previously
if (seen.count(s2Idx)) {
auto [prevS1, prevS2] = seen[s2Idx];
int cycleS1 = s1Count - prevS1;
int cycleS2 = s2Count - prevS2;
// Calculate how many full cycles we can fast-forward
int remainingS1 = n1 - s1Count;
int numCycles = remainingS1 / cycleS1;
s1Count += numCycles * cycleS1;
s2Count += numCycles * cycleS2;
// Clear history to complete the remaining tail iterations linearly
seen.clear();
} else {
seen[s2Idx] = {s1Count, s2Count};
}
}
return s2Count / n2;
}
};
// ==========================================
// Local Test Runner (Guarded for LeetCode Submission)
// ==========================================
#ifdef LOCAL_TEST
int main() {
Solution solver;
// Test Case 1: Standard Example 1
{
string s1 = "acb";
int n1 = 4;
string s2 = "ab";
int n2 = 2;
int result = solver.getMaxRepetitions(s1, n1, s2, n2);
cout << "Test 1 - s1=\"acb\", n1=4, s2=\"ab\", n2=2 -> Expected: 2, Got: " << result << endl;
assert(result == 2);
}
// Test Case 2: Exact matching strings
{
string s1 = "acb";
int n1 = 1;
string s2 = "acb";
int n2 = 1;
int result = solver.getMaxRepetitions(s1, n1, s2, n2);
cout << "Test 2 - s1=\"acb\", n1=1, s2=\"acb\", n2=1 -> Expected: 1, Got: " << result << endl;
assert(result == 1);
}
// Test Case 3: Overlapping repeating pattern
{
string s1 = "aaa";
int n1 = 3;
string s2 = "aa";
int n2 = 1;
int result = solver.getMaxRepetitions(s1, n1, s2, n2);
cout << "Test 3 - s1=\"aaa\", n1=3, s2=\"aa\", n2=1 -> Expected: 4, Got: " << result << endl;
assert(result == 4);
}
// Test Case 4: Long repetition requiring cycle fast-forwarding
{
string s1 = "baba";
int n1 = 11;
string s2 = "ba";
int n2 = 1;
int result = solver.getMaxRepetitions(s1, n1, s2, n2);
cout << "Test 4 - s1=\"baba\", n1=11, s2=\"ba\", n2=1 -> Expected: 22, Got: " << result << endl;
assert(result == 22);
}
// Test Case 5: Large n1 and n2
{
string s1 = "bacaba";
int n1 = 3;
string s2 = "abacab";
int n2 = 1;
int result = solver.getMaxRepetitions(s1, n1, s2, n2);
cout << "Test 5 - s1=\"bacaba\", n1=3, s2=\"abacab\", n2=1 -> Expected: 2, Got: " << result << endl;
assert(result == 2);
}
cout << "\nAll test cases passed successfully!" << endl;
return 0;
}
#endif