How I think about this. Z function and sliding window.
Intuition\nDisclaimer: This is code from another solution. i am just providing my views on the intuition i got after reading it, and steps to solve it yourself.
# Intuition\nDisclaimer: This is code from another solution. i am just providing my views on the intuition i got after reading it, and steps to solve it yourself.\n\nFirst, understand the z function. Know what the z function aims to calculate (the max len of prefix overlap of s[i:] and s).\n\nNow, to solve this problem, the first step is to calculate the maximum index we can hop to from every character of s. A hop just means "take a prefix of a word that overlaps with the prefix of target and move the pointer at target to the next character not seen yet". A really clever way is to use the z function, with input of every string as word#target (# can be substituted for any other character that wont exist in word or target). With this trick, the z function will calculate the max length of overlap of every suffix of target with the word. We are using max() in the code for updating the dp array because we want the farthest point we can hop to from the index after considering all words.\n\nThe last operation is to use a sliding window (two pointers) technique to find the minimum number of hops.\n\nIn summary, we use the z function to find the farthest index we can hop to from each index in target, and use a sliding window to find the result.\n\n# Code\n```python\nclass Solution:\n    def minValidStrings(self, words: List[str], target: str) -> int:\n        \n        def Z_function(s):\n            n = len(s)\n            Z = [0] * n\n            l = r = 0\n            for i in range(1, n):\n                if i < r:\n                    Z[i] = min(Z[i - l], r - i)\n                while i + Z[i] < n and s[Z[i]] == s[i + Z[i]]:\n                    Z[i] += 1\n                if i + Z[i] > r:\n                    l = i\n                    r = i + Z[i]\n            return Z\n        \n        n = len(target)\n        dp = [0] * n\n        for word in words:\n            Z_arr = Z_function(word + \'#\' + target)\n            offset = len(word) + 1\n            for i in range(n):\n                dp[i] = max(dp[i], Z_arr[i + offset])\n\n        l = r = 0\n        hops = 0\n        while r < n:\n            max_reach = 0\n            for i in range(l, r + 1):\n                max_reach = max(max_reach, i + dp[i])\n            if max_reach == 0: # we cannot go further\n                return -1\n            l = r + 1\n            r = max_reach\n            hops += 1\n        return hops\n         \n```
['Sliding Window', 'Python3']