Skip to content

Commit 5abdadb

Browse files
authored
Create 0028-find-the-index-of-the-first-occurrence-in-a-string.kt
1 parent f8def2d commit 5abdadb

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* KMP algorithm
3+
*/
4+
class Solution {
5+
fun strStr(haystack: String, needle: String): Int {
6+
if(needle == "") return 0
7+
8+
val lps = IntArray(needle.length)
9+
var prevLPS = 0
10+
var i = 1
11+
while(i < needle.length) {
12+
if(needle[i] == needle[prevLPS]) {
13+
lps[i] = prevLPS + 1
14+
prevLPS++
15+
i++
16+
}else if(prevLPS == 0) {
17+
lps[i] = 0
18+
i++
19+
}else{
20+
prevLPS = lps[prevLPS - 1]
21+
}
22+
}
23+
24+
i = 0
25+
var j = 0
26+
while (i < haystack.length) {
27+
if(haystack[i] == needle[j]){
28+
i++
29+
j++
30+
}else if(j == 0){
31+
i++
32+
}else{
33+
j = lps[j - 1]
34+
}
35+
if(j == needle.length) {
36+
return i - needle.length
37+
}
38+
}
39+
40+
return -1
41+
}
42+
}
43+
44+
/*
45+
* Rabin-Karp string hashing with bad hash
46+
*/
47+
class Solution {
48+
fun strStr(haystack: String, needle: String): Int {
49+
if(needle.length > haystack.length) return -1
50+
51+
var needleHash = 0
52+
var hayHash = 0
53+
54+
for(i in 0..needle.lastIndex) {
55+
needleHash += needle[i] - 'a'
56+
hayHash += haystack[i] - 'a'
57+
}
58+
59+
for(i in 0..(haystack.length - needle.length)) {
60+
if(hayHash == needleHash) {
61+
for(j in 0..needle.lastIndex) {
62+
if(haystack[i + j] != needle[j])
63+
break
64+
if(j == needle.lastIndex)
65+
return i
66+
}
67+
}
68+
if(i == haystack.length - needle.length)
69+
break
70+
hayHash -= haystack[i] - 'a'
71+
hayHash += haystack[i + needle.length] - 'a'
72+
}
73+
74+
return -1
75+
}
76+
}
77+
78+
/*
79+
* Using Trie to match pattern
80+
*/
81+
class TrieNode() {
82+
val child = arrayOfNulls<TrieNode>(26)
83+
var isEnd = false
84+
}
85+
86+
class Solution {
87+
fun strStr(haystack: String, needle: String): Int {
88+
if(needle == "") return 0
89+
90+
var root: TrieNode? = TrieNode()
91+
92+
var current = root
93+
for(c in needle){
94+
if(current?.child?.get(c - 'a') == null)
95+
current?.child?.set(c - 'a', TrieNode())
96+
current = current?.child?.get(c - 'a')
97+
}
98+
current?.isEnd = true
99+
100+
var i = 0
101+
while(i < haystack.length + 1 - needle.length) {
102+
current = root?.child?.get(haystack[i] - 'a')
103+
var j = i
104+
while(current != null) {
105+
if(current.isEnd == true)
106+
return i
107+
j++
108+
if(j - i < needle.length)
109+
current = current?.child?.get(haystack[j] - 'a')
110+
else
111+
break
112+
}
113+
i++
114+
}
115+
116+
return -1
117+
}
118+
}
119+
120+
/*
121+
* Brute force
122+
*/
123+
class Solution {
124+
fun strStr(haystack: String, needle: String): Int {
125+
if(needle == "") return 0
126+
127+
for(i in 0..(haystack.length - needle.length)) {
128+
for(j in 0..needle.lastIndex) {
129+
if(haystack[i + j] != needle[j])
130+
break
131+
if(j == needle.lastIndex)
132+
return i
133+
}
134+
}
135+
136+
return -1
137+
}
138+
}

0 commit comments

Comments
 (0)