本文共 2006 字,大约阅读时间需要 6 分钟。
给定一个 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() 定义相符。写了三种方法,一个是原生,一个是所有元素循环遍历,一个是切片比较,目前可能提交样本不够,效率都差不多,几乎都是双100%
原生的strings.Index(haystack, needle)是我的第一反应,已经很简单了,如果要放弃原生来实现的话,就使用方法二或者方法三,注释里有详尽思路。
方法一:
执行用时 :0 ms, 击败了100.00% 的用户 内存消耗 :2.3 MB, 击败了65.96%的用户func strStr1(haystack string, needle string) int { return strings.Index(haystack, needle)}
方法二:
执行用时 :0 ms, 击败了100.00% 的用户 内存消耗 :2.3 MB, 击败了100.00%的用户func strStr2(haystack string, needle string) int { // 统计匹配次数 f := 0 // 首次匹配时的索引号 x := 0 // 由于循环时需要根据情况变化,因此在此先初始化 i := 0 j := 0 // 字符串长度 l_haystack := len(haystack) l_needle := len(needle) // 如果字符串为空,则返回0 if l_needle == 0 { return 0 } // 以匹配字符串作为外层循环 for ; i < l_needle; i++ { // 以待匹配字符串作为内层循环 for ; j < l_haystack; j++ { // 如果内外元素相同 if needle[i] == haystack[j] { // 首次匹配记录索引 if f == 0 { x = j } // 下次内层循环索引从j+1开始 j++ // 记录匹配成功的次数 f++ // 如果匹配成功的次数与匹配字符串长度相同,则返回首次匹配成功的索引 if l_needle == f { return x } // 结束本次内层循环 break } // 匹配次数大于0,但本次没有匹配成功,说明之前有匹配成功的字符,但没有完成全部匹配即断开到达本步骤 // 例如:haystack := "missshe" needle := "ssh" // s第一次匹配的位置在索引2,此后下一个s又在索引3匹配成功,但下一个h在索引4失败了, // 此时系统只能从第一次匹配成功的索引2,向后移动一位重新开始匹配, // 这样s第二次匹配的位置在索引3,此后下一个s在索引4匹配成功,再下一个h在索引5匹配成功了。 if f > 0 { // i从-1重新技术,跳到外层循环之前会先进行一次x++的操作,这样外层的i正好又可以从0开始循环 i = -1 // 本首次匹配成功的索引x向前移动一位,下次内层循环的j从最新的索引开始,而不是从0 j = x + 1 // 匹配成功的次数重置为0 f = 0 break } } } return -1}
方法三:
执行用时 :0 ms, 击败了100.00% 的用户 内存消耗 :2.3 MB, 击败了100.00%/63.89%的用户func strStr3(haystack string, needle string) int { lHaystack := len(haystack) lNeedle := len(needle) for i := 0; i <= lHaystack-lNeedle; i++ { if haystack[i:i+lNeedle] == needle { return i } } return -1}
转载地址:http://stkpi.baihongyu.com/