leetcode-pp / 91alg-5-daily-check

91 天学算法第五期打卡
55 stars 14 forks source link

【Day 83 】2021-12-01 - 28 实现 strStr( #102

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

28 实现 strStr(

入选理由

暂无

题目地址

[-BF&RK)

https://leetcode-cn.com/problems/implement-strstr/](-BF&RK

https://leetcode-cn.com/problems/implement-strstr/)

前置知识

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。

示例 1:

输入: haystack = "hello", needle = "ll" 输出: 2 示例 2:

输入: haystack = "aaaaa", needle = "bba" 输出: -1 说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

watermelonDrip commented 2 years ago
class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if len(needle) == 0:
            return 0
        if len(haystack) < len(needle):
            return -1
        # RK 
        hash_val = 0
        target = 0

        for i in range(len(haystack)):
            if i < len(needle):
                hash_val  = hash_val*26 + ord(haystack[i]) - ord('a')
                target = target*26 + ord(needle[i]) - ord('a')  
            else:
                tmp = ord(haystack[i]) - ord('a') 
                hash_val = 26*(hash_val - ( ord(haystack[i-len(needle)]) - ord('a') )*(26**(len(needle) - 1))) + tmp
            if i>= len(needle)-1 and hash_val == target:
                return i - len(needle) + 1
        return 0 if hash_val == target else -1

        # BF
        for i in range(len(haystack) - len(needle) + 1):
            if haystack[i:i+len(needle)] == needle:
                return i
        return -1
chaggle commented 2 years ago

title: "Day 83" date: 2021-12-01T15:26:54+08:00 tags: ["Leetcode", "c++", "KMP"] categories: ["91-day-algorithm"] draft: true


28. 实现 strStr()

题目

实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回  -1 。

 

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

 

示例 1:

输入:haystack = "hello", needle = "ll"
输出:2
示例 2:

输入:haystack = "aaaaa", needle = "bba"
输出:-1
示例 3:

输入:haystack = "", needle = ""
输出:0
 

提示:

0 <= haystack.length, needle.length <= 5 * 104
haystack 和 needle 仅由小写英文字符组成

题目思路

  • 1、经典一看,发现是KMP算法的喜悦,将 haystack 替换为 s 主串,needle替换为模式串。
class Solution {
public:
    int strStr(string s, string p) {
        int n = s.size(), m = p.size();
        if(m == 0) return 0;

        s.insert(s.begin(), ' ');
        p.insert(p.begin(), ' ');

        vector<int> next(m + 1);

        for(int i = 2, j = 0; i <= m; i++) {
            while(j && p[i] != p[j + 1]) j = next[j];
            if(p[i] == p[j + 1]) j++;
            next[i] = j;
        }

        for(int i = 1, j = 0; i <= n; i++) {
            while(j && s[i] != p[j + 1]) j = next[j];
            if(s[i] == p[j + 1]) j++;
            if(j == m) return i - m;
        }
        return -1;
    }
};

复杂度

Zhang6260 commented 2 years ago

JAVA版本

思路:

使用滚动哈希,其中哈希的算法可以使用位运算来计算。

class Solution {
    public int strStr(String haystack, String needle) {
        //使用RK(滚动哈希)  自己设计一个哈希算法  来判读needle
        if(needle.length()==0)return 0;
        int n_val = 0, h_val = 0;
        for(int i=0;i<needle.length();i++){
            n_val ^= needle.charAt(i);
        }
        int size = needle.length();
        boolean istrue = true;
        for(int i=0;i<haystack.length();i++){
            h_val ^= haystack.charAt(i);
            if(i<size&&istrue){
                if(i==size-1){
                    istrue = false;
                    if(h_val==n_val&&haystack.substring(i-size+1,i+1).equals(needle)){
                        return i-size+1;
                    }
                }
                continue;
            }
            h_val ^=haystack.charAt(i-size);
            if(h_val==n_val&&haystack.substring(i-size+1,i+1).equals(needle)){
                return i-size+1;
            }
        }
        return -1;
    }
}

时间复杂度:O(n)

空间复杂度:O(1)

jiahui-z commented 2 years ago

思路: brute force, could be improved with KMP algorithm

class Solution {
    public int strStr(String haystack, String needle) {
        if (needle.length() == 0) return 0;
        if (haystack.length() == 0) return -1;

        int m = haystack.length(), n = needle.length();

        for (int i = 0; i <= m - n; i++) {
            for (int j = 0; j < n && haystack.charAt(i+j) == needle.charAt(j); j++) {
                if (j == n - 1) {
                    return i;
                }
            }
        }

        return -1;
    }
}

Time Complexity: O(n*m), n and m are the length of two input strings Space Complexity: O(1)

ginnydyy commented 2 years ago

Problem

https://leetcode.com/problems/implement-strstr/

Note

Solution

Complexity

jaysonss commented 2 years ago

RK:

class Solution {
    public int strStr(String haystack, String needle) {
        int hLen = haystack.length();
        int nLen = needle.length();

        if(hLen<nLen)return -1;

        int targetHash = hash(needle,0,nLen-1);
        int curHash = 0; 

        for(int i=0;i<=hLen-nLen;i++){
            int end = i + nLen - 1;
            if(i==0){
                curHash = hash(haystack,0,end);
            }else {
                curHash += (haystack.charAt(end) - haystack.charAt(i-1));
            }

            if(curHash == targetHash && haystack.substring(i,end+1).equals(needle)){
                return i;
            }
        }
        return -1;
    }

    int hash(String str,int start,int end){
        int ret = 0;
        for(int i=start;i<=end;i++){
            ret+=(str.charAt(i) - 'a');
        }
        return ret;
    }
}

BF:

class Solution {
    public int strStr(String haystack, String needle) {
        if(needle == null || needle.length() == 0)return 0;
        int hLen = haystack.length();
        int nLen = needle.length();

        if(hLen<nLen)return -1;

        for(int i=0;i<=hLen - nLen;i++){
            int k = 0;

            for(int j=0;j<nLen;j++){
                if(haystack.charAt(i+j) == needle.charAt(j)){
                    k++;
                }else {
                    break;
                }
            }

            if(k == nLen)return i;

        }
        return -1;
    }
}
kennyxcao commented 2 years ago

28. Implement strStr()

Intuition

Code

/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
const strStr = function(haystack, needle) {
  if (haystack == null || needle == null) return -1;
  const m = needle.length;
  if (m === 0) return 0;
  const MOD = 1e7 + 7;
  const BASE = 31;
  const maxBase = getMaxBase(m);
  const needleCode = getHashCode(needle);
  let hashCode = 0;
  for (let i = 0; i < haystack.length; i++) {
    hashCode = (hashCode * BASE + haystack.charCodeAt(i)) % MOD; // abc + d
    if (i < m - 1) continue; // no need to check if less than needle length
    if (i >= m) { // abcd - a, exceed needle length, remove left most char
      hashCode = (hashCode - (haystack.charCodeAt(i - m) * maxBase)) % MOD;
      if (hashCode < 0) hashCode += MOD; // in case hash turns negative from subtraction above
    }
    // double check the string match
    if (hashCode === needleCode && haystack.slice(i - m + 1, i + 1) === needle) return i - m + 1;
  }
  return -1;

  function getMaxBase(len) {
    let maxBase = 1;
    for (let i = 0; i < len; i++) {
      maxBase = (maxBase * BASE) % MOD; // 31^m
    }
    return maxBase;
  }

  function getHashCode(str) {
    let hash = 0;
    for (let i = 0; i < str.length; i++) {
      hash = (hash * BASE + str.charCodeAt(i)) % MOD;
    }
    return hash;
  }
};

Complexity Analysis

xixvtt commented 2 years ago

先看答案 后学习

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if len(needle) == 0:
            return 0
        for i in range(len(haystack) - len(needle) + 1):
            if haystack[i: i + len(needle)] == needle:
                return i
        return -1
chen445 commented 2 years ago

代码

class Solution:
    def strStr(self, haystack, needle):
        if needle == "":
            return 0
        for i in range(len(haystack)-len(needle)+1):
            for j in range(len(needle)):
                if haystack[i+j] != needle[j]:
                    break
                if j == len(needle)-1:
                    return i
        return -1

复杂度

Time: O(m*n)

Space: O(1)

mannnn6 commented 2 years ago

代码

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        for (int i = 0; i + m <= n; i++) {
            boolean flag = true;
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return i;
            }
        }
        return -1;
    }
}

复杂度

时间复杂度: O(m*n)

空间复杂度: O(1)

cecilialmw commented 2 years ago
class Solution {
    public int strStr(String haystack, String needle) {
        int len_h = haystack.length();
        int len_n = needle.length();

        if (len_n == 0) {
            return 0;
        }
        if (len_n > len_h) {
            return -1;
        }

        for (int i = 0; i < len_h - len_n; i++) {
            if (haystack.substring(i, i + len_n).equals(needle)) {
                return i;
            }
        }
        return -1;
    }
}

Complexity:

Time: O(m*n)

Space: O(1)

ZJP1483469269 commented 2 years ago

代码

class Solution {
    public int strStr(String haystack, String needle) {
        if(needle.length() == 0) return 0;
        if(haystack.length() == 0) return -1;
        for(int i = 0; i <= haystack.length() - needle.length(); i++){
            int j = 0;
            for(;j < needle.length();j++){
                if(haystack.charAt(i + j) != needle.charAt(j)){
                    break;                    
                }
            }
            if(j == needle.length())return i;
        }
        return -1;
    }
}
carterrr commented 2 years ago

class Solution {
    public int strStr(String haystack, String needle) {
        int n = needle.length();
        if(n == 0) return 0;
        int h = haystack.length();
        char[] hay = haystack.toCharArray();
        char[] ne = needle.toCharArray();

        // 生成next数组 最长相同前后缀问题
        int[] next = new int[n] ;
        for(int l = 0, r = 1; r < n;) {
             // l 和 r 不同  找l 前一个元素 对应的最长相同前后缀 转到该元素处的下一个来比较  
             // 如abcabcabf 到了abcabf != abcabc f应该转到第一个c处来和长串比较 但是 abc != abf 因此再次回退到0
            while(l > 0 && ne[l] != ne[r]) l = next[l - 1];
            if(ne[l] == ne[r]) l++;
            next[r] = l;  // 如果退到0 位置 直接填入就好  否则 应该比较的是l的下一个位置 因此先把l++
            r++;
        }

        for(int i = 0, j = 0; i < h;) {
            // 不相等 转到前一位的最长公共子串的下一位
            // 如 issip  到了p 不相等  应该转到和s 比较  因为i是一样的
            while(j > 0 && hay[i] != ne[j]) j = next[j - 1]; 

            if(hay[i] == ne[j]) j++; // 匹配上了  子串指针后移一位
            if(j == n) return i - n + 1; // 整个子串needle匹配上了  ne[n-1] 都相等了  此时j++ 后等于n
            i ++;
        }
        return  -1;
    }
}

字符串hash比较简单 就不写了

15691894985 commented 2 years ago

【day83】题目地址(28 实现 strStr()-BF&RK)

https://leetcode-cn.com/problems/implement-strstr/

1.BF

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if len(needle) ==0:
            return 0
        for i in range(len(haystack)-len(needle) +1):
            if haystack[i:i+len(needle)] == needle:
                return i
        return -1

时间复杂度:O((m-n)*n) 空间复杂度:O(1)

2.RF f(T[s..s + m]) = T[s] 10 ^ (m - 1) + T[s + 1] 10 ^ (m - 2) ... + T[s + m - 1] f(T[s+1..s + m]) = T[s+1] 10 ^ (m - 1) + T[s + 2] 10 ^ (m - 2) ... + T[s + m] = (f(T[s..s + m]) - T[s] 10 ^ (m - 1)) 10 + T[s + m ]

    def strStr(self, haystack: str, needle: str) -> int:
        # Robin-Krap (RK)算法
        count = 0
        hay_length = len(haystack)
        nee_length = len(needle)
        pathash = hash(needle)
        for i in range(hay_length-nee_length+1):
            strhash = hash(haystack[i:i+nee_length])
            # 使用hash值判断代替字符的遍历判断
            if strhash != pathash:
                continue
            else:
                for j in range(nee_length):
                    if haystack[i+j] != needle[j]:
                        break
                    else:
                        count += 1
            if count == nee_length:
                return i
        if count != nee_length:
            return -1
RonghuanYou commented 2 years ago
class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        for i in range(len(haystack) - len(needle) + 1):
            if haystack[i: i + len(needle)] == needle:
                return i
        return -1
Laurence-try commented 2 years ago
class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        # for i in range (len(haystack) - len(needle) + 1):
        #     if haystack[i:len(needle) + i] == needle:
        #         return i
        # return -1
        if needle in haystack:
            return haystack.index(needle)
        return -1
okbug commented 2 years ago
class Solution {
public:
    int strStr(string s, string p) {
        int n = s.size(), m = p.size();
        for(int i = 0; i <= n - m; i++){
            int j = i, k = 0; 
            while(k < m and s[j] == p[k]){
                j++;
                k++;
            }
            if(k == m) return i;
        }
        return -1;
    }
};
L-SUI commented 2 years ago

/**

last-Battle commented 2 years ago

代码

C++ Code:


class Solution {
public:
    int strStr(string haystack, string needle) {
        if (needle.empty()) {
            return 0;
        }

        int lenh = haystack.length();
        int lenn = needle.length();

        if (lenh < lenn) {
            return -1;
        }

        for (int i = 0; i <= lenh - lenn; ++i) {
            int j = 0;
            while (j < lenn && haystack[i + j] == needle[j]) {
                ++j;
            }

            if (j == lenn) {
                return i;
            } 
        }

        return -1;
    }
};

复杂度分析

令 n 为数组长度。

Tomtao626 commented 2 years ago

思路

guangsizhongbin commented 2 years ago
func strStr(haystack string, needle string) int {
    return strings.Index(haystack, needle)
}
ccslience commented 2 years ago
int strStr(string& haystack, string& needle)
{
    if (needle == "") return 0;
    int l = 0, r = needle.length() - 1;
    while(r < haystack.length())
    {
        int tmp = l;
        int flag = 0;
        while(haystack[tmp] == needle[flag] && (tmp <= r))
        {
            flag++;
            tmp++;
        }
        if(tmp == r + 1)
            return l;
        l++;
        r++;
    }
    return -1;
}
ymkymk commented 2 years ago

class Solution { public int strStr(String haystack, String needle) { if (needle == null || needle.trim() == "") { return 0; }

    if (haystack == null || haystack.trim() == "") {
        return -1;
    }

    return haystack.indexOf(needle);
}

}

asterqian commented 2 years ago

思路

brute force

代码

int strStr(string haystack, string needle) {
        if (needle.size() == 0) return 0;
        if (haystack.size() < needle.size()) return -1;
        for (int i = 0; i < haystack.size() - needle.size() + 1; ++i) {
            if (haystack.substr(i, needle.size()) == needle) return i;
        }
        return -1;
    }
时间复杂度 O(N*M)
空间复杂度 O(1)
machuangmr commented 2 years ago

java

class Solution {
    public int strStr(String haystack, String needle) {
        char[] haystackChar = haystack.toCharArray();
        char[] needleChar = needle.toCharArray();
        for(int i = 0;i + needleChar.length <= haystackChar.length;i++) {
            boolean flag = true;
            for(int j = 0;j < needleChar.length;j++) {
                if(haystackChar[i + j] != needleChar[j]) {
                    flag = false;
                    break;
                }
            }
            if(flag) return i;
        }
        return -1;
    }
}

复杂度

HouHao1998 commented 2 years ago
class Solution {
    public int strStr(String haystack, String needle) {

        int lenHaystack = haystack.length();
        int lenNeedle = needle.length();
        // needle equal to zero
        if(needle.length() == 0){
            return 0;
        }

        // haystack shorter than
        if(lenNeedle < lenNeedle){
            return -1;
        }

        for(int i = 0; i <  lenHaystack - lenNeedle + 1; i++){
            for(int j =0; j < lenNeedle; j++){
                if(haystack.charAt(i+j) != needle.charAt(j)){
                    break;
                }

            }
        }
    }
}
AruSeito commented 2 years ago
var strStr = function (haystack, needle) {
    if (needle.length === 0)
        return 0;

    const getNext = (needle) => {
        let next = [];
        let j = -1;
        next.push(j);

        for (let i = 1; i < needle.length; ++i) {
            while (j >= 0 && needle[i] !== needle[j + 1])
                j = next[j];
            if (needle[i] === needle[j + 1])
                j++;
            next.push(j);
        }

        return next;
    }

    let next = getNext(needle);
    let j = -1;
    for (let i = 0; i < haystack.length; ++i) {
        while (j >= 0 && haystack[i] !== needle[j + 1])
            j = next[j];
        if (haystack[i] === needle[j + 1])
            j++;
        if (j === needle.length - 1)
            return (i - needle.length + 1);
    }

    return -1;
};
yibenxiao commented 2 years ago

【Day 83】28 实现 strStr()

代码

class Solution {
public:
    int strStr(string haystack, string needle) {
        int n = haystack.size(), m = needle.size();
        if (m == 0) {
            return 0;
        }
        vector<int> pi(m);
        for (int i = 1, j = 0; i < m; i++) {
            while (j > 0 && needle[i] != needle[j]) {
                j = pi[j - 1];
            }
            if (needle[i] == needle[j]) {
                j++;
            }
            pi[i] = j;
        }
        for (int i = 0, j = 0; i < n; i++) {
            while (j > 0 && haystack[i] != needle[j]) {
                j = pi[j - 1];
            }
            if (haystack[i] == needle[j]) {
                j++;
            }
            if (j == m) {
                return i - m + 1;
            }
        }
        return -1;
    }
};

复杂度

时间复杂度:O(N+M)

空间复杂度:O(M)

mokrs commented 2 years ago
int strStr(string haystack, string needle) {
    int n = haystack.size(), m = needle.size();
    for (int i = 0; i + m <= n; ++i) {
        bool flag = true;
        for (int j = 0; j < m; ++j) {
            if (haystack[i + j] != needle[j]) {
                flag = false;
                break;
            }
        }
        if (flag) {
            return i;
        }
    }
    return -1;
}
WeiWri-CC commented 2 years ago
class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if not len(needle):
            return 0
        try:
            return haystack.index(needle)
        except Exception:
            pass    
        return -1
winterdogdog commented 2 years ago

滑动窗口

/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
var strStr = function(haystack, needle) {
    let hLen = haystack.length, nLen = needle.length, res = -1;
    if (hLen < nLen) return -1;
    if (nLen === 0) return 0;
    for(let i = 0; i < hLen - nLen + 1; i++) {
        if (haystack.slice(i, i + nLen) === needle) {
            res = i
            break
        }
    }
    return res;
};
falsity commented 2 years ago
class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        for (int i = 0; i + m <= n; i++) {
            boolean flag = true;
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return i;
            }
        }
        return -1;
    }
}
yj9676 commented 2 years ago
class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        if (m == 0) {
            return 0;
        }
        int[] pi = new int[m];
        for (int i = 1, j = 0; i < m; i++) {
            while (j > 0 && needle.charAt(i) != needle.charAt(j)) {
                j = pi[j - 1];
            }
            if (needle.charAt(i) == needle.charAt(j)) {
                j++;
            }
            pi[i] = j;
        }
        for (int i = 0, j = 0; i < n; i++) {
            while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
                j = pi[j - 1];
            }
            if (haystack.charAt(i) == needle.charAt(j)) {
                j++;
            }
            if (j == m) {
                return i - m + 1;
            }
        }
        return -1;
    }
}
ChenJingjing85 commented 2 years ago
class Solution:
    '''滚动hash'''
    def strStr(self, haystack: str, needle: str) -> int:
        lenH = len(haystack)
        lenN = len(needle)
        if not lenN:
            return 0
        if lenH < lenN:
            return -1
        target_hash = 0
        hay_hash = 0
        base = 101

        for i in range(lenN):
            target_hash = target_hash * 26 + (ord(needle[i])-ord('a'))
            target_hash %= base
            hay_hash = hay_hash * 26 + (ord(haystack[i])-ord('a'))
            hay_hash %= base
        if target_hash == hay_hash and haystack[:lenN] == needle:
            return 0
        for i in range(1, lenH-lenN+1):
            hay_hash = (hay_hash - (ord(haystack[i-1]) -ord('a'))*(26**(lenN-1)))*26 + (ord(haystack[i+lenN-1]) -ord('a'))
            hay_hash %= base
            if hay_hash == target_hash and haystack[i:i+lenN] == needle:
                return i
        return -1

时间 O(m+n) 空间 O (1)

for123s commented 2 years ago

代码

C++ Code:


class Solution {
public:
    vector<int> next;

    void queryNext(string needle)
    {
        int n = needle.size();
        int k = -1, j = 0;
        next.assign(n,-1);
        while(j<n-1)
        {
            if(k==-1||needle[j]==needle[k])
            {
                k++;
                j++;
                if(needle[j]==needle[k])
                    next[j] = next[k];
                else
                    next[j] = k;
            }
            else
                k = next[k];
        }
    }

    int strStr(string haystack, string needle) {
        queryNext(needle);
        int i = 0, j = 0, hn = haystack.size(), nn = needle.size();
        while(i<hn&&j<nn)
        {
            if(j==-1||haystack[i]==needle[j])
            {
                i++;
                j++;
            }
            else
                j = next[j];
        }
        if(j==nn)
            return i - j;
        return -1;
    }
};
chenming-cao commented 2 years ago

解题思路

暴力解法。在haystack中找到substring,然后与needle比较。

代码

class Solution {
    public int strStr(String haystack, String needle) {
        if (needle == null || needle.isEmpty()) {
            return 0;
        }

        int m = haystack.length();
        int n = needle.length();
        if (m < n) {
            return -1;
        }

        for (int i = 0; i <= m - n; i++) {
            String subStr = haystack.substring(i, i + n);
            if (subStr.equals(needle)) {
                return i;
            }
        }        
        return -1;
    }
}

复杂度分析

xinhaoyi commented 2 years ago

28. 实现 strStr()

实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

示例 1:

输入:haystack = "hello", needle = "ll" 输出:2 示例 2:

输入:haystack = "aaaaa", needle = "bba" 输出:-1 示例 3:

输入:haystack = "", needle = "" 输出:0

提示:

0 <= haystack.length, needle.length <= 5 * 104 haystack 和 needle 仅由小写英文字符组成

思路一:KMP算法

参考题解:

【宫水三叶】简单题学 KMP 算法 - 实现 strStr() - 力扣(LeetCode) (leetcode-cn.com)

多图预警👊🏻详解 KMP 算法 - 实现 strStr() - 力扣(LeetCode) (leetcode-cn.com)

(4 封私信 / 60 条消息) 如何更好地理解和掌握 KMP 算法? - 知乎 (zhihu.com)

知乎的这个写的很好

代码

class Solution {
    // KMP 算法
    // ss: 原串(string)  pp: 匹配串(pattern)
    public int strStr(String ss, String pp) {
        if (pp.isEmpty()) return 0;

        // 分别读取原串和匹配串的长度
        int n = ss.length(), m = pp.length();
        // 原串和匹配串前面都加空格,使其下标从 1 开始
        ss = " " + ss;
        pp = " " + pp;

        char[] s = ss.toCharArray();
        char[] p = pp.toCharArray();

        // 构建 next 数组,数组长度为匹配串的长度(next 数组是和匹配串相关的)
        int[] next = new int[m + 1];
        // 构造过程 i = 2,j = 0 开始,i 小于等于匹配串长度 【构造 i 从 2 开始】
        for (int i = 2, j = 0; i <= m; i++) {
            // 匹配不成功的话,j = next(j)
            while (j > 0 && p[i] != p[j + 1]) j = next[j];
            // 匹配成功的话,先让 j++
            if (p[i] == p[j + 1]) j++;
            // 更新 next[i],结束本次循环,i++
            next[i] = j;
        }

        // 匹配过程,i = 1,j = 0 开始,i 小于等于原串长度 【匹配 i 从 1 开始】
        for (int i = 1, j = 0; i <= n; i++) {
            // 匹配不成功 j = next(j)
            while (j > 0 && s[i] != p[j + 1]) j = next[j];
            // 匹配成功的话,先让 j++,结束本次循环后 i++
            if (s[i] == p[j + 1]) j++;
            // 整一段匹配成功,直接返回下标
            if (j == m) return i - m;
        }

        return -1;
    }
}

复杂度分析

时间复杂度:$O(m + n)$

空间复杂度:$O(m)$

BpointA commented 2 years ago

思路

kmp

代码


class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if len(needle)==0:
            return 0
        nexts=[0]*len(needle)
        i=0
        j=-1
        nexts[0]=-1
        while i<len(needle)-1:
            if j==-1 or needle[i]==needle[j]:
                i+=1
                j+=1
                nexts[i]=j
            else:
                j=nexts[j]
        m=len(haystack)
        n=len(needle)
        i=0
        j=0
        while i<m and j<n:
            if j==-1 or haystack[i]==needle[j]:
                i+=1
                j+=1
            else:
                j=nexts[j]
        if j==n:
            return i-j
        else:
            return -1
ZETAVI commented 2 years ago
class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        for (int i = 0; i + m <= n; i++) {
            boolean flag = true;
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return i;
            }
        }
        return -1;
    }
}
taojin1992 commented 2 years ago
# Understand:
0 <= haystack.length, needle.length <= 5 * 10^4
haystack and needle consist of only lower-case English characters.

index of the first occurrence of needle 
cannot find => -1

needle "" -> return 0

Tests:
"mississippi"
"issip"

4

# Plan & Match:
bruteforce:
traverse the haystack, 
for each char in haystack matching with needle.charAt(0):
    traverse from that char

how to search the needle efficiently?

# Evaluate:
## Time: O(haystack.length() * needle.length())

## Space: O(1)

==============Rabin-Karp=======to fina all the matches
0 <= haystack.length, needle.length <= 5 * 10^4

haystack and needle consist of only lower-case English characters.
-> use the power of 26 for hashing

2^63 - 1 < 26 ^ (5 * 10^4)

Code:

class Solution {
    // =====Rabin-Karp=======to fina all the matches=======
    public int strStr(String haystack, String needle) {
        // edge cases
        if (needle.length() == 0) {
            return 0;
        }
        if (haystack.length() == 0 || needle.length() > haystack.length()) {
            return -1;
        }

        int prime = 101;
        int base = 26; // only lower-case English characters.
        long initHaystackHash = getInitialHash(haystack, 0, needle.length() - 1, base, prime);
        long initNeedleHash = getInitialHash(needle, 0, needle.length() - 1, base, prime);

        for (int start = 0; start <= haystack.length() - needle.length(); start++) {
            // for each start (except start == 0) recalculate the hash
            // O(1)
            if (start > 0) {
                // recalculate hash by one step
                // - leftmost
                initHaystackHash -= haystack.charAt(start - 1);
                // / base
                initHaystackHash /= base;
                // + new rightmost
                // initHaystackHash += (haystack.charAt(start + needle.length() - 1) * Math.pow(base, needle.length() - 1) % prime) % prime;
                // initHaystackHash %= prime;
                initHaystackHash += haystack.charAt(start + needle.length() - 1) * Math.pow(base, needle.length() - 1);
            }
            if (initHaystackHash == initNeedleHash && haystack.substring(start, start + needle.length()).equals(needle)) {
                return start;
            }
        }
        return -1;
    }

    // % a prime to reduce the complexity
    // "abc"
    // 'a' + 'b' * base + 'c' * base * base
    // inclusive
    // O(needle) time complexity
    private long getInitialHash(String str, int startIndex, int endIndex, int base, int prime) {
        long hashRes = 0L;
        for (int i = startIndex; i <= endIndex; i++) {
            // hashRes += (str.charAt(i) * (Math.pow(base, i - startIndex) % prime)) % prime;
            // hashRes %= prime;
            hashRes += str.charAt(i) * (Math.pow(base, i - startIndex));
        }
        return hashRes;
    }

    public int strStr0(String haystack, String needle) {
        // two edge cases
        if (needle.length() == 0) {
            return 0;
        }
        if (haystack.length() == 0 || needle.length() > haystack.length()) {
            return -1;
        }

        for (int i = 0; i <= haystack.length() - needle.length(); i++) {
            int needleIndex = 0;
            int haystackIndex = i;
            while (haystack.charAt(haystackIndex) == needle.charAt(needleIndex)) {
                needleIndex++;
                haystackIndex++;
                if (needleIndex == needle.length()) {
                    return haystackIndex - needle.length();
                }
            }
        }
        return -1;
    }

    // another way
     public int strStr1(String haystack, String needle) {
        // two edge cases
        if (needle.length() == 0) {
            return 0;
        }
        if (haystack.length() == 0 || needle.length() > haystack.length()) {
            return -1;
        }

        // Logic: i is the starting index in haystack that potentially match the            first char of needle
        // j is the length of the matched needle part
        // time complexity O(m * n), m is the length of haystack, n is the length of needle
        for (int i = 0; i <= haystack.length() - needle.length(); i++) {
            for (int j = 0; j < needle.length() && haystack.charAt(i + j) == needle.charAt(j); j++) {
                if (j == needle.length() - 1) return i;
            }
        }
        return -1;
    }
}
Richard-LYF commented 2 years ago

class Solution: def strStr(self, haystack, needle): """ :type haystack: str :type needle: str :rtype: int """ lenA, lenB = len(haystack), len(needle) if not lenB: return 0 if lenB > lenA: return -1

    for i in range(lenA - lenB + 1):
        if haystack[i:i + lenB] == needle:
            return i
    return -1
joriscai commented 2 years ago

思路

代码

javascript

/*
 * @lc app=leetcode.cn id=28 lang=javascript
 *
 * [28] 实现 strStr()
 */

// @lc code=start
/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
var strStr = function(haystack, needle) {
  if (needle === '') {
    return 0
  }

  hLen = haystack.length
  nLen = needle.length

  for (let i = 0; i < hLen - nLen + 1; i++) {
    if (haystack.slice(i, i + nLen) === needle) {
      return i
    }
  }
  return -1
};

// @lc code=end

复杂度分析

revisegoal commented 2 years ago

思路

BF,用RK由于大数类耗时多超时

代码

import java.math.BigInteger;

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length();
        int m = needle.length();

        if (m == 0) {
            return 0;
        }
        if (n < m) {
            return -1;
        }
        for (int i = 0; i < n - m + 1; i++) {
            int j = 0;
            while (j < m) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    break;
                }
                j++;
            }
            if (j == m) {
                return i;
            }
        }
        return -1;
    }
}

复杂度

time:O(n*m),n是

pan-qin commented 2 years ago
class Solution {
    public int strStr(String haystack, String needle) {
        if(needle==null || needle.length()==0)
            return 0;
        int m = haystack.length();
        int n = needle.length();
        if(m<n)
            return -1;
        for(int i=0;i<=m-n;i++) {
            if(haystack.substring(i,i+n).equals(needle))
                return i;
        }
        return -1;
    }
}
wangyifan2018 commented 2 years ago
class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if not haystack and not needle:
            return 0
        if not haystack or len(haystack) < len(needle):
            return -1
        if not needle:
            return 0
        hash_val = 0
        target = 0
        prime = 101
        for i in range(len(haystack)):
            if i < len(needle):
                hash_val = hash_val * 26 + (ord(haystack[i]) - ord("a"))
                target = target * 26 + (ord(needle[i]) - ord("a"))
            else:
                hash_val = (
                    hash_val - (ord(haystack[i - len(needle)]) - ord("a")) * 26 ** (len(needle) - 1)
                ) * 26 + (ord(haystack[i]) - ord("a"))
            if i >= len(needle) - 1 and hash_val == target :
                return i - len(needle) + 1
        return -1
chakochako commented 2 years ago
func strStr(haystack, needle string) int {
    n, m := len(haystack), len(needle)
outer:
    for i := 0; i+m <= n; i++ {
        for j := range needle {
            if haystack[i+j] != needle[j] {
                continue outer
            }
        }
        return i
    }
    return -1
}
septasset commented 2 years ago
def strStr(self, haystack: str, needle: str) -> int:
    if not haystack and not needle:
        return 0
    if not haystack or len(haystack) < len(needle):
        return -1
    if not needle:
        return 0
    hash_val = 0
    target = 0
    prime = 2**31 - 19
    for i in range(len(haystack)):
        if i < len(needle):
            hash_val = hash_val * 26 + (ord(haystack[i]) - ord("a"))
            hash_val %= prime
            target = target * 26 + (ord(needle[i]) - ord("a"))
            target %= prime
            # print(target)
        else:
            hash_val = (
                hash_val - (ord(haystack[i - len(needle)]) - ord("a")) * (26 ** (len(needle) - 1))
            ) * 26 + (ord(haystack[i]) - ord("a"))
            hash_val %= prime
        if i >= len(needle) - 1 and hash_val == target:
            # print(target, hash_val)
            return i - len(needle) + 1
    # print(target, hash_val)
    return 0 if hash_val == target else -1
shixinlovey1314 commented 2 years ago

Title:28. Implement strStr()

Question Reference LeetCode

Solution

KMP

Code

class Solution {
public:
    int strStr(string haystack, string needle) {
        if (needle.length() == 0)
            return 0;

        vector<int> next(needle.length(), 0);
        next[0] = -1;

        // Generate next array
        for (int i = 1; i < needle.length(); i++) {
            int k = next[i - 1];
            while (k != -1 && needle[i-1] != needle[k]){
                k = next[k];
            }

            /*if (needle[i] == needle[k + 1])
                next[i] = next[k + 1];
            else */
                next[i] = k + 1;
        }

        int i = 0;
        int j = 0;

        // Match the string
        while (i < haystack.length() && j < (int) needle.length()) { 
            if (j == -1 || haystack[i] == needle[j]) {
                i++;
                j++;
            } else {
                j = next[j];
            }
        }

        if (j == needle.length())
            return i - needle.length();

        return -1;
    }
};

Complexity

Time Complexity and Explanation

O(m+n), m is the length of needle, o(m) is used to generate the next array; n is the length of haystack

Space Complexity and Explanation

O(m), used to store the next array.