[Java] 1ms 100%Time 55.4% Space, only Array used. In detail explaination. O(L* M)
Key word: Regular, Cycle, Math;\n\nIdea: \n\nStep 1: As we should not brute force answer, we need to seperate it to a small problem, I did it wrong here in my f
Key word: Regular, Cycle, Math;\n\nIdea: \n\nStep 1: As we should not brute force answer, we need to seperate it to a small problem, I did it wrong here in my first thought. I divided it to how many characters it need from s1 to form s2. This is trivial as after first round of choosing the character, the start of next round may not be start at the same character with same idx in s1.\n\nStep 2: Ok, we extend problem to how many s2 we can form when we endAt same character with same idx in s1, here is the cycle we want to find.\neg. AAA and AA,\n\n1st Round: AA, we stop at idx 1 of s1 to collect s2(ie AA)\n\n2nd Round: AAA | A, we stop at idx 0 of second s1 to collect s2(A|A)\n\n3rd Round: AAA | AAA, we stop at idx 2 of second s1 to collect s2(AA)\n\n4th Round: AAA | AAA | AA, we stop at idx1 of third s1 to collect s2(AA)\n\n5th Round: There is not 5th round as we have already find a Cycle(1st and 4th round both stop at idx1) which means that \n**every    3  +   3  +  2 = 8  characters we can collect 4 s2;**\n\t\t    (AAA | AAA | AA)  \n\nso this is ideal scenario as we can start at first one. Generally, our first match might start at characters in s1 other than first one\neg NBA and AB, it starts from second character. How about we refine our cycle length by deleting the header, so it will be\n\n1st Round: NB**A | NB**A, we stop at idx 1 of second s1 (A|NB) to collect BA \n\n2nd Round: NBA | NB**A | NB**A we stop at idx 1 of third s1 to collect s2(B|A), here is cycle, \n\nThe cycle length is 3 + 3 + 2 - 2 = 6;\n(NBA | NBA | NBA | - NB)\n\nCool, we got length of cycle now, and we also know the total length of S1 is s1.length * n1, we can know how many cycles in S1, with the regular we got above, we can know in the cycles, how many s2 we can collect by #of Cycle * s2 per cycle\n\nWhat about remainning characters? They are capable to form s2 as well. Recall to how we find cycle, we defined in every round that how many s2 we can collect when we endAt specific idx. so we can get number of extra s2 that we collect from remaining characters;\n\nHere we go, we got total number of s2 we can collect from s1 by s2 in cycle + s2 in remaining characters.\n\nGiven repeating number n2 of s2, we can know how many s2 + s2 + ... + s2 we can get by total number of s2 / n2;\n\nConclusively, it will be **(# of s2 in cycle + # of s2 in remaining charaters) / n2**, by doing so, you can beat 100%, if not, ask Xfinity or Verizon for it. \n\n```\nclass Solution {\n    public int getMaxRepetitions(String s1, int n1, String s2, int n2) {\n        int len1 = s1.length(), len2 = s2.length();\n\t\t// for detecting cycle\n        boolean[] endAt = new boolean[len1];\n        char[] chs1 = s1.toCharArray(), chs2 = s2.toCharArray();\n\t\t// how many s1 we use and how many s2 we collect when we endAt specific\n        int[] nums1 = new int[len1], nums2 = new int[len1];\n        \n        int tltS1Len = len1 * n1;\n        \n        int startIdx = s1.indexOf(chs2[0]);\n        if(startIdx == -1){\n            return 0;\n        }\n        \n        int s2n = 0, s1n = 0, curIdx = 0, prevIdx = -1;\n        while(s1n * len1 + curIdx < tltS1Len){\n            for(char c : chs2){\n                curIdx = s1.indexOf(c, prevIdx + 1);\n                \n                if(curIdx == -1 && prevIdx == -1){\n                    return 0;\n                }\n                prevIdx = curIdx;\n                if(curIdx == -1){\n                    ++s1n;\n                    curIdx = s1.indexOf(c, prevIdx + 1);\n                }\n                prevIdx = curIdx;\n            }\n            // cycle found\n            if(endAt[curIdx]){\n                break;\n            }\n            \n            prevIdx = curIdx;\n            ++s2n;\n            endAt[curIdx] = true;\n            nums1[curIdx] = s1n;\n            nums2[curIdx] = s2n; \n        }\n\t\t\n        int cycleLen = (s1n - nums1[curIdx]) * len1;\n        if(cycleLen == 0){\n            return 0;\n        }\n        int nS2 = (tltS1Len - startIdx - 1) / cycleLen * s2n;\n        int remain = (tltS1Len - startIdx - 1) % cycleLen;\n        \n        int extraNum = 0;\n        for(int i = 0; i < len1; ++i){\n            if(!endAt[i]){\n                continue;\n            }\n            \n            if(remain >= i + nums1[i] * len1){\n                extraNum = Math.max(nums2[i], extraNum);\n            }\n        }\n        \n        return (nS2 + extraNum) / n2;\n    }\n}\n```
[]