3029. Minimum Time to Revert Word to Initial State I
Problem Description
In this problem, we have a string word
, which is indexed starting from 0, and an integer k
. The goal is to determine the minimum time to bring word
back to its original state through a series of operations performed every second. Each second, we need to:
- Remove the first
k
characters (sub-string) fromword
. - Append any
k
characters at the end ofword
.
The added twist is that the characters you add don't have to be the ones you just removed. The requirement is to perform both operations simultaneously, and we need to find the minimum number of seconds necessary to revert word
to its initial state.
Intuition
The intuition behind the solution relies on discovering a pattern in the transformation of the string word
. At each operation, we take a block of k
characters from the front and append k
characters at the back. To find when the word
returns to its original state, we should look for a repetition in the string that matches the start of the string.
The key observation is that if after i
operations (where i
is a multiple of k
), the part of the string after k*i
characters matches the original string starting from the 0th index up to n-k*i
, where n
is the length of word
, then the word has come back to its original state. This would mean every k*i
characters in the string can be cycled through removals and additions to achieve the initial state of the string.
To implement this idea, we iterate through the string, checking at each multiple of k
if the postfixed string word[k*i:]
is the same as the start of the original string word[:-k*i]
. If we find a match, then dividing the matching index by k
gives us the total operations (seconds) taken to get back to the starting state. If we don't find any such match, then the smallest number of operations needed would involve going through the entire string once, hence (n + k - 1) // k
operations.
Solution Approach
The implementation of the solution is simple and direct. It follows the steps outlined in the Reference Solution Approach, utilizing a single loop and basic string comparison to find the cycle that brings the word
back to its initial state.
No complex data structures are needed for this approach. The main algorithm pattern in place here is enumeration, which is a straightforward technique to iterate through the possibilities until the solution is found.
The process of the algorithm is as follows:
- Calculate the length of the string
word
and store it in a variablen
. - Use a
for
loop to iterate over the string, starting fromk
and continuing in increments ofk
until the end of the stringn
. - Inside the loop, check if the substring of
word
from the current indexi
to the end (word[i:]
) matches the substring from the start ofword
to then - i
index (word[:-i]
). This represents that after removing and appendingk
charactersi // k
times,word
has returned to its initial state. - If the condition in step 3 is true, immediately return
i // k
as the minimum time. - If the loop completes without finding a match, then the
word
does not revert to its initial state until we have gone through all its characters at least once. Thus we return(n + k - 1) // k
, which accounts for the case where the last set of characters to revert might not be a fullk
characters in length.
The return (n + k - 1) // k
line handles the edge case that when we're left with fewer than k
characters at the end, we still need an extra operation to complete the cycle.
This procedure finds the minimum number of operations necessary to restore word
to its original state, by systematically checking for cycles in the string formed by the series of operations defined in the problem.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's consider a simple example to illustrate the solution approach using a string word = "abcabc"
and k = 3
.
Step by step process:
- We calculate the length
n
ofword
, which in this case is 6. - Now,
k
is 3, so we will be taking and appending blocks of 3 characters at each operation. We start iterating with afor
loop beginning fromk
(3 in this case) and increment byk
with each iteration. - At each iteration
i
(which is a multiple ofk
), we compare the substring ofword
from indexi
to the end,word[i:]
, with the substring from the start ofword
to the indexn-i
,word[:n-i]
.- At
i = 3
, we take the substringword[i:]
which is"abc"
, and compare it withword[:n-i]
, which is also"abc"
. They match, indicating that after 1 operation (removing "abc" from the start and appending "abc" to the end), the word will return to its original state.
- At
- Since we have found a match, we return
i // k
, which is3 // 3
or 1 in this case.
Therefore, in this example, it takes a minimum of 1 operation to bring word
back to its original state.
No further iterations are necessary because we found the cycle length in this example during the first iteration. If the word did not revert to its initial state by the end of the iteration through its length, we would have used the formula (n + k - 1) // k
to determine the minimum number of operations required.
Solution Implementation
1class Solution:
2 def minimum_time_to_initial_state(self, word: str, k: int) -> int:
3 # Calculate the length of the word
4 word_length = len(word)
5
6 # Iterate over the word, checking substrings of length multiples of k
7 for i in range(k, word_length, k):
8 # Check if the substring from the current position to the end
9 # matches the substring from the beginning to the complementary position
10 if word[i:] == word[:-i]:
11 # If yes, the minimum number of times to reach the initial state can be calculated
12 # by dividing the current index by k. Return this value.
13 return i // k
14
15 # If no pattern was found, calculate and return the ceiling division of the
16 # word's length by k, as the number of times needed to process the entire string
17 return (word_length + k - 1) // k
18
19# Example of usage:
20# solution = Solution()
21# result = solution.minimum_time_to_initial_state("abcabcabc", 3)
22# print(result) # Output will be 1, since "abcabcabc" returns to the initial "abc" after 1 iteration of size 3
23
1class Solution {
2 public int minimumTimeToInitialState(String word, int k) {
3 // Calculate the length of the word
4 int wordLength = word.length();
5
6 // Loop through the word in increments of 'k'
7 for (int i = k; i < wordLength; i += k) {
8 // Check if the substring starting from index 'i' to the end of the word
9 // is equal to the substring from the beginning of the word to length 'wordLength - i'
10 if (word.substring(i).equals(word.substring(0, wordLength - i))) {
11 // If they are equal, return the minimum number of times 'k' fits into 'i'
12 return i / k;
13 }
14 }
15
16 // If no such substring is found that matches the condition,
17 // return the minimum number of times to cover the entire word plus the remaining characters,
18 // also accounting for partially filling the last segment.
19 return (wordLength + k - 1) / k;
20 }
21}
22
1class Solution {
2public:
3 // Function to determine the minimum number of time units to return a string to its initial state
4 int minimumTimeToInitialState(string word, int k) {
5 int n = word.size(); // Store the length of the input string
6
7 // Loop through the string in steps of 'k'
8 for (int i = k; i < n; i += k) {
9 // Check if the substring starting at index 'i' is equal to the substring starting at the beginning of the word
10 // with the same length. This indicates that the pattern repeats and the initial state is reached.
11 if (word.substr(i) == word.substr(0, n - i)) {
12 // If a match is found, return the number of steps taken to reach the initial state
13 return i / k;
14 }
15 }
16
17 // If no repeating pattern is found that matches the criteria, return the ceiling of word size divided by 'k'
18 // This implies performing the operation on the whole string until the initial state is reached.
19 return (n + k - 1) / k;
20 }
21};
22
1/**
2 * Calculates the minimum time to return to the initial state of a word by deleting every k-th character.
3 * The process repeats until a previous state is formed or all characters are deleted.
4 *
5 * @param {string} word - The word to be reverted to its initial state.
6 * @param {number} k - The step size indicating after how many characters a deletion occurs.
7 * @returns {number} - The number of steps required to return to the initial state.
8 */
9function minimumTimeToInitialState(word: string, k: number): number {
10 // n represents the length of the word.
11 const n = word.length;
12
13 // Loop through the word, incrementing by k each time.
14 for (let i = k; i < n; i += k) {
15 // Check if the substring from the current position 'i' to the end
16 // is equal to the substring from the start to the length of the word minus 'i'.
17 // If they are equal, the word can be reverted to its previous state in i/k steps.
18 if (word.slice(i) === word.slice(0, -i)) {
19 return Math.floor(i / k);
20 }
21 }
22
23 // If no previous state is found, calculate the maximum number of steps
24 // required to delete all characters based on the step size 'k'.
25 // The expression ensures the result is rounded up to account for the last remaining characters.
26 return Math.floor((n + k - 1) / k);
27}
28
Time and Space Complexity
The time complexity of the provided code is O(n^2)
. In the worst case, the for
loop runs for n/k
iterations, and in each iteration, it performs a substring operation and string comparison with a complexity of O(n)
leading to a total of O(n * (n/k))
which simplifies to O(n^2)
because k
is a constant and does not grow with n
. Substring operations involve creating new strings which take O(n)
time each.
The space complexity is O(n)
primarily due to the substring operation within the loop that potentially creates a new string of size n
at each iteration. Although only one substring is kept in memory at a time, its size could be as large as the original word
, which means it directly scales with the input size n
.
Learn more about how to find time and space complexity quickly using problem constraints.
Given a sorted array of integers and an integer called target, find the element that
equals to the target and return its index. Select the correct code that fills the
___
in the given code snippet.
1def binary_search(arr, target):
2 left, right = 0, len(arr) - 1
3 while left ___ right:
4 mid = (left + right) // 2
5 if arr[mid] == target:
6 return mid
7 if arr[mid] < target:
8 ___ = mid + 1
9 else:
10 ___ = mid - 1
11 return -1
12
1public static int binarySearch(int[] arr, int target) {
2 int left = 0;
3 int right = arr.length - 1;
4
5 while (left ___ right) {
6 int mid = left + (right - left) / 2;
7 if (arr[mid] == target) return mid;
8 if (arr[mid] < target) {
9 ___ = mid + 1;
10 } else {
11 ___ = mid - 1;
12 }
13 }
14 return -1;
15}
16
1function binarySearch(arr, target) {
2 let left = 0;
3 let right = arr.length - 1;
4
5 while (left ___ right) {
6 let mid = left + Math.trunc((right - left) / 2);
7 if (arr[mid] == target) return mid;
8 if (arr[mid] < target) {
9 ___ = mid + 1;
10 } else {
11 ___ = mid - 1;
12 }
13 }
14 return -1;
15}
16
Recommended Readings
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!