1.题目
对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1。
2.样例
如果 source = “source” 和 target = “target”,返回 -1。
如果 source = “abcdabcdefg” 和 target = “bcd”,返回 1。
3.分析
在面试中我是否需要实现KMP算法?
这是题目中的说明,KMP算法被戏称为“看毛片”算法,我只是记住了,可是我还不会 >)(<。
解题思路:我的思路是,先排除异常情况,null,”“,source长度小于target长度,然后进入正常判断,定义一个指针,遍历循环source,如果两个字符串能匹配的话,则指针+1,如果指针长度能等于target长度,则符合,返回首位的位置,否则重置为0,并且判断不等时target的首位是否和当前source的当前位相等。
不知道我这算法的复杂度事多少,我感觉是O(n)呀!
class Solution {
/**
* Returns a index to the first occurrence of target in source,
* or -1 if target is not part of source.
* @param source string to be scanned.
* @param target string containing the sequence of characters to match.
*/
public int strStr(String source, String target) {
// write your code here
//判断是否为null
if (source == null || target == null) return -1;
int n = source.length();
int m = target.length();
if (n < m) return -1;
//是否为""
if (m == 0) return 0;
//定义一个指针
int tIndex = 0;
for (int i = 0; i < n; i++){
if (source.charAt(i) == target.charAt(tIndex)){//匹配判断
//符合则指针后移一位
tIndex++;
//如果长度等于目标字符串长度,则返回位置
if (tIndex == m) return i - tIndex + 1;
}else {
//重置为0
tIndex = 0;
//如果符合首位则+1
if (source.charAt(i) == target.charAt(tIndex)){
tIndex++;
}
}
}
return -1;
}
}
4.延伸
查资料看到一个比较好的常规的算法,这里也贴出来,主要就是进行两次遍历循环
class Solution {
public int strStr(String source, String target) {
//write your code here
if (source == null | target == null) {
return -1;
}
int i, j;
for (i = 0; i < source.length() - target.length() +1; i++) {
for (j = 0; j < target.length(); j++) {
if (source.charAt(i+j) != target.charAt(j)) {
break;
}
}
if (j == target.length()) {
return i;
}
}
return -1;
}
}
还有比较牛逼的KMP算法,这个算法我没研究过具体思路,以后接触了再讨论。
class Solution {
public int strStr(String source, String target) {
//write your code here
if (source == null || target == null) {
return -1;
}
if (target.length() == 0) {
return 0;
}
int[] prefix = new int[target.length()];
int k = 0;
for (int i = 1; i < target.length(); i++) {
while (k > 1 && target.charAt(k) != target.charAt(i)) {
k = prefix[k-1];
}
if (target.charAt(i) == target.charAt(k)) k++;
prefix[i] = k;
}
k = 0;
for (int i = 0; i < source.length(); i++) {
while (k > 1 && source.charAt(i) != target.charAt(k)) {
k = prefix[k-1];
}
if (target.charAt(k) == source.charAt(i)) {
k++;
}
if (k == target.length()) {
return i - k + 1;
}
}
return -1;
}
}