My LeetCode: https://leetcode-cn.com/u/ituring/
My LeetCode source code [GitHub]: https://github.com/izhoujie/Algorithmcii
LeetCode 466. Count the number of duplicates
subject
The string s is composed of N connected strings S, which is recorded as S = [s,n]. For example, ["abc",3] = "ABC ABC".
If we can remove some characters from s2 and change them to s1, the string s1 can be obtained from s2. For example, by definition, "abc" can be obtained from "abdbec", but not from "acbbe".
Now I will give you two non empty strings S1 and S2 (each with a maximum length of 100 characters) and two integers 0 ≤ n1 ≤ 106 and 1 ≤ n2 ≤ 106. Now consider the strings S1 and S2, where S1=[s1,n1], S2=[s2,n2].
Please find a maximum integer m that can satisfy [S2,M] from S1.
Example:
Input: s1 ="acb",n1 = 4 s2 ="ab",n2 = 2 return: 2
Source: LeetCode
Link: https://leetcode-cn.com/problems/count-the-repetitions
Copyright belongs to the network. For commercial reprint, please contact the official authorization. For non-commercial reprint, please indicate the source.
Solutions to problems
One sentence: find out how many S2 formed by S1 splicing of n1 can be divided into S2 formed by S1 splicing of n2 after deleting several characters;
Train of thought 1 - find "cycle section" and then solve it according to the multiple relationship of cycle section
"Cyclic section" refers to a S2 that can be obtained after several s1 are spliced and several characters are deleted. See the diagram:
Therefore, the idea is to find "cyclic section" first, and then see how many such cyclic sections are in S1 spliced by n1 S1, and then deal with the remaining S1 sections before and after the cyclic section, we can get n complete S1 from S1, and N/n2 can get the M value of the required solution of the problem;
Step:
- Match the characters in s2 sequentially from n1 s1, record the number of complete matching s2, record the number of currently matched s2 and the index position of the characters to be matched in s2 after matching the first s1;
- In the following, if the index at the stop of s2 is equal to the first description after matching s1, then the mathematical calculation can be started according to the above ideas;
- If no circular section is found all the time, only n1 s1 can be matched violently. There are two situations:
- Some characters in s2 don't exist in s1, and 0 matches (special cases can be judged first to avoid meaningless calculation later);
- The length of n1 s1 is just enough for one S2, 1 matching;
Algorithm complexity:
- len1 is s1 length, len2 is s2 length, n1 is n1 of n1 s1 in the question
- Time complexity: ${\ color{Magenta}{\Omicron\left(len1 \ast len2\right)} $n1\(\ast\)len1\(\ast\)len2 at worst
- Spatial complexity: ${\ color{Magenta}{\Omicron\left(n1\right)})} $number of matches requiring n1 length array to store s2
Algorithm source code example
package leetcode; /** * @author ZhouJie * @date 2020 7:12:10 PM, April 19, 2010 * @Description: 466. Count the number of duplicates * */ public class LeetCode_0466 { } class Solution_0466 { /** * @author: ZhouJie * @date: 2020 7:12:31 PM, April 19, 2010 * @param: @param s1 * @param: @param n1 * @param: @param s2 * @param: @param n2 * @param: @return * @return: int * @Description: 1-First, try to find the circulatory body, so as to calculate the number of S2 that can be spliced; * */ public int getMaxRepetitions_1(String s1, int n1, String s2, int n2) { int len1 = s1.length(); int len2 = s2.length(); // Special case judgment if (n1 == 0 || n2 == 0 || n1 * len1 < n2 * len2) { return 0; } // Special case - if the characters in s2 are not directly returned in s1 char[] cs2 = s2.toCharArray(); for (char c : cs2) { if (s1.indexOf(c) == -1) { return 0; } } char[] cs1 = s1.toCharArray(); // The subscript of s2 when looking for the circulatory body int index = 0; int count = 0; // The character index position first matched in s2 int firstIndex = 0; // Record the total number of s2 matched at the i-th splicing of s1 int[] countRdecoder = new int[n1]; for (int i = 0; i < n1; i++) { for (int j = 0; j < len1; j++) { // This is a back and forth match. When s2 in s1 is matched, index is shifted to the right. When s2 is completely matched, count is recorded and index is reset if (cs2[index] == cs1[j]) { index++; if (index == len2) { count++; index = 0; } } } // Stop position of s1 after the first matching if (i == 0) { firstIndex = index; } // As of the total matching s2 countRdecoder[i] = count; // If the stop bit index of this time is the same as that of the first time, it means that the loop body is found, start the mathematical calculation and return if (i != 0 && index == firstIndex) { // The first part: when finding the circulatory body, multiply the number of matching s1 in the circulatory body by the number of such circulatory body segments in N1 s2 (n1-1) / I) int part1 = ((n1 - 1) / i) * (countRdecoder[i] - countRdecoder[0]); // The second part: after the first part is removed, the remaining part s2 can be spliced to match the number of s1 int part2 = countRdecoder[(n1 - 1) % i]; // Divide the total number of matching s1 by n2 (n2 s1) to get the M required by the title return (part1 + part2) / n2; } } // If the loop body is not found, then the direct violent solution can only be 0 or 1 return countRdecoder[n1 - 1] / n2; } }