본문 바로가기
LeetCode/Array & Hashing

[LeetCode][Kotlin] 28. Find the Index of the First Occurrence in a String

by jinwo_o 2024. 8. 29.

28. Find the Index of the First Occurrence in a String

Given two strings needle and haystack, return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

needle과 haystack이라는 두 문자열이 주어지면 haystack에서 needle이 처음 나타나는 인덱스를 반환하거나, needle이 haystack의 일부가 아닌 경우 -1을 반환합니다.

 

Example 1:

Input: haystack = "sadbutsad", needle = "sad"

Output: 0

Explanation: "sad" occurs at index 0 and 6.

The first occurrence is at index 0, so we return 0.

 

Example 2:

Input: haystack = "leetcode", needle = "leeto"

Output: -1

Explanation: "leeto" did not occur in "leetcode", so we return -1.

 

Constraints:

  • 1 <= haystack.length, needle.length <= 10^4
  • haystack and needle consist of only lowercase English characters.

코드 1

class Solution {
    fun strStr(haystack: String, needle: String): Int {
        return haystack.indexOf(needle)
    }
}

 

코드 2 (KMP: Knuth-Morris-Pratt)

  • 기존 알고리즘(이중 for문)에서는 needle 을 찾을 때 다른 문자가 나왔을 경우, 다시 돌아가서 검사할때 중복되는 경우가 존재한다.

  • needle(바늘)과 haystack(건초 더미) : haystack = "ababcabcabababd", needle = "ababd"
  • needle 에 대한 LPS(Longest Prefix Suffix) 를 만든다. [0, 0, 1, 2, 0]

  • haystack needle 을 비교할 때, 문자가 일치하지 않을 경우 처음으로 돌아가는 것이 아니라 LPS 배열을 활용하여 비교를 계속 진행한다.

class Solution {
    fun strStr(haystack: String, needle: String): Int {
        // if (needle.isEmpty()) return 0
        val lps = IntArray(needle.length)

        var prevLPS = 0
        var i = 1
        while (i < needle.length) {
            if (needle[i] == needle[prevLPS]) {
                lps[i] = prevLPS + 1
                prevLPS++
                i++
            } else if (prevLPS == 0) {
                lps[i] = 0
                i++
            } else {
                prevLPS = lps[prevLPS - 1]
            }
        }

        i = 0
        var j = 0
        while (i < haystack.length) {
            if (haystack[i] == needle[j]) {
                i++
                j++
            } else if (j == 0) {
                i++
            } else {
                j = lps[j - 1]
            }

            if (j == needle.length) {
                return i - needle.length
            }
        }

        return -1
    }
}