Article Directory
Problem Description
Given the
haystack
sum of two stringsneedle
, please find the subscript of the first occurrence of the stringhaystack
in the string (the subscript starts from 0). Returns -1needle
ifneedle
not part ofhaystack
Example 1
Input: haystack = "sadbutsad", needle = "sad"
Output: 0
Explanation: "sad" matches at subscripts 0 and 6.
The index of the first match is 0, so return 0.
Example 2
Input: haystack = "leetcode", needle = "leeto"
Output: -1
Explanation: "leeto" does not appear in "leetcode", so return -1.
hint
- 1 <= haystack.length, needle.length <= 104
- haystack and needle consist of lowercase English characters only
Idea analysis
When solving this problem, you can use the idea of double pointers. First, we set two pointers to the starting positions of
haystack
and , respectivelyneedle
. Then, we start to traversehaystack
the string and compare whether the character at the current pointer positionneedle
is the same as the character in the string. If they are the same, we continue to compare the next character until there is a complete match orneedle
the string is traversed.
Proceed as follows:
- If
needle
it is an empty string, subscript 0 is returned. - Calculate the lengths of
haystack
and , denoted as and ,needle
respectively .n
m
- Start traversing from
haystack
the first character of , and the traversing range isn - m + 1
. - For each position
i
,j
iterate over using the pointerneedle
and compare the characters ofhaystack[i+j]
andneedle[j]
for equality. If they are equal, continue to compare the next character; if they are not equal, jump out of the loop. - If
j
traverses toneedle
the end of , that isj == m
, the first match is found, returni
the value of the current pointer minusneedle
the length ofm
. haystack
If no match is found after traversing , -1 is returned, indicatingneedle
that is nothaystack
part of .
This way, we can find the subscript of the first occurrence of the string needle
in string .haystack
code analysis
-
First, check the special case, if
needle
is an empty string, then directly return the subscript 0, because the empty string is a substring of any string. -
Calculate the lengths of
haystack
andneedle
, and assign them to the variablesn
and , respectivelym
. This is done to avoid accessing the function multiple times in the looplen()
. -
Use the outer loop
for i in range(n - m + 1)
to traversehaystack
every possible starting position of . Note that the scope of the outer loop isn - m + 1
because when the number of remaining characters is less thanneedle
the length of , it is naturally impossible to match. -
In the inner loop
for j in range(m)
, use the pointerj
to traverseneedle
each character of andhaystack
compare it with the character at the corresponding position in . If the characters are equal, continue to compare the next character; if the characters are not equal, exit the inner loop. -
If the inner loop ends normally, that is,
j
the traversal reachesneedle
the end of , indicating that the first matching item is found, andi
the value of the current pointer can be returned. -
If no match is found after the outer loop ends, -1 is returned, indicating that
needle
is nothaystack
a substring of .
The idea of this algorithm is to compare characters one by one until a match is found or the whole is traversed haystack
. In the worst case (no match or match at the last starting position), approximately (n - m + 1) * m
character comparison operations are required.
full code
class Solution(object):
def strStr(self, haystack, needle):
if not needle: # 特殊情况判断:needle为空字符串
return 0
n = len(haystack) # haystack长度
m = len(needle) # needle长度
for i in range(n - m + 1): # 遍历haystack的每个起始位置
for j in range(m): # 遍历needle的每个字符
if haystack[i+j] != needle[j]: # 当前字符不匹配,跳出内层循环
break
else:
return i # 内层循环正常结束,找到匹配项,返回当前指针i的值
return -1 # 未找到匹配项,返回-1
Detailed analysis
class Solution(object):
def strStr(self, haystack, needle):
"""
:type haystack: str
:type needle: str
:rtype: int
"""
This code defines a class named and a method Solution
named in the class . The method accepts two parameters and , which represent the string to be searched and the substring to be searched respectively. The return type of the method is declared as .strStr
strStr
haystack
needle
int
if not needle:
return 0
This code first checks the special case, that is, if needle
is an empty string, it returns 0 directly. Because the empty string is a substring of any string.
n = len(haystack)
m = len(needle)
This code uses len()
the function to get the lengths of the strings haystack
and needle
, and stores them in the variables n
and , respectively m
. This is done to improve efficiency by avoiding multiple calls to the function in subsequent loops len()
.
for i in range(n - m + 1):
j = 0
while j < m and haystack[i+j] == needle[j]:
j += 1
if j == m:
return i
This code uses two loops to match strings. The outer loop iterates over every possible starting position in for
loop using the range . Because when the remaining characters are less than the length of , no match can be made.haystack
n - m + 1
needle
The inner loop uses while
the loop to match by comparing haystack
the characters in with the characters in . needle
The loop condition is j < m and haystack[i+j] == needle[j]
, which means that when the pointer j
is less than needle
the length of and the current character matches, continue looping.
If the inner loop ends normally, and j
the value of the pointer is equal to m
, that is, the entire loop has been traversed needle
, indicating that a matching substring has been found, and i
the value of the current pointer is returned.
return -1
If no match is found after the outer loop ends, it means that needle
is not haystack
a substring of and returns -1.
Screenshot of running effect
call example
solution = Solution()
haystack = "sadbutsad"
needle = "sad"
haystack1 = "leetcode"
needle1 = "leeto"
print(solution.strStr(haystack, needle))
print(solution.strStr(haystack1, needle1))