Java solution with explanation.
Took reference from https://discuss.leetcode.com/topic/71256/easy-understanding-java-solution-with-detailed-explanation-21ms but tried to give more detailed exp
Took reference from https://discuss.leetcode.com/topic/71256/easy-understanding-java-solution-with-detailed-explanation-21ms but tried to give more detailed explanation about the pattern math.\n\n```\n    public int getMaxRepetitions(String s1, int n1, String s2, int n2) {\n        if (!verifyInput(s1, s2)) {\n            return 0;\n        }\n\n        int totalOccurrence = 0;\n        String remaining = "", str = s1;\n        boolean loopFound = false;\n        Map<String, Integer> cycleIndex = new HashMap<String, Integer>();\n        ArrayList<Integer> occurenceCountAtEachCycle = new ArrayList<Integer>(); \n        \n        for (int i = 0; i <= n1; i++) {\n            StringBuilder sb = new StringBuilder();\n            totalOccurrence += getRemaining(str, s2, sb);\n            remaining = sb.toString();\n\n            if (cycleIndex.containsKey(remaining)) {\n                loopFound = true;\n                break;\n            }\n\n            cycleIndex.put(remaining, i);\n            \n            occurenceCountAtEachCycle.add(totalOccurrence);\n            \n            str = remaining + s1; // append s1 to make a new string\n        }\n\n        if (!loopFound) {\n            return totalOccurrence / n2; // if there is no loop\n        }\n\n        int indexBeforeLoop = cycleIndex.get(remaining);\n        \n        int occurrenceCountInLoopCycle = totalOccurrence - occurenceCountAtEachCycle.get(indexBeforeLoop);\n       \n       // represents the number of cycles required to complete a loop\n        int loopCycleLength = occurenceCountAtEachCycle.size() - indexBeforeLoop;\n        \n        // resetting the total occurrence to cycle before loop happened\n        totalOccurrence = occurenceCountAtEachCycle.get(indexBeforeLoop);\n        \n        // removing cycles from n1 before loop started. Adding 1 as n1 is 1 based and other index are 0 based\n        n1 -= (indexBeforeLoop + 1);\n        \n        // total occurrence is number of occurrence before loop + number of occurrence in loops for the rest of n1\n        totalOccurrence += occurrenceCountInLoopCycle * (n1 / loopCycleLength);\n        \n        // if loop cycle terminated prematurely then the remaining cycles should be accounted\n        n1 %= loopCycleLength;\n\n        if(n1 != 0){\n            // occurenceCountAtEachCycle.get(indexBeforeLoop) is required because we just want to add the left over cycles of incomplete loop.\n            totalOccurrence += occurenceCountAtEachCycle.get(indexBeforeLoop + n1) - occurenceCountAtEachCycle.get(indexBeforeLoop);\n        }\n\n        return totalOccurrence / n2;\n    }\n\n    // check if s1 contains all s2 characters\n    private boolean verifyInput(String s1, String s2) {\n        boolean[] arr = new boolean[26];\n\n        for (char ch : s1.toCharArray()) {\n            arr[ch - 'a'] = true;\n        }\n\n        for (char ch : s2.toCharArray()) {\n            if (!arr[ch - 'a']){\n                return false;\n            }\n        }\n        \n        return true;\n    }\n\n    // get remain string after s1 obtains s2, return the matching count\n    private int getRemaining(String s1, String s2, StringBuilder remaining) {\n        int count = 0, lastMatchIdx = -1, s2Idx = 0;\n        for (int i = 0; i < s1.length(); i++) {\n            if (s1.charAt(i) == s2.charAt(s2Idx)) {\n                if (++s2Idx == s2.length()) {\n                    s2Idx = 0;\n                    count++;\n                    lastMatchIdx = i;\n                }\n            }\n        }\n        remaining.append(s1.substring(lastMatchIdx + 1));\n        return count;\n    }\n```
[]