Golang面试考题记录 ━━ 实现 strStr() 函数,截然不同三种方案,效率都差不多,双100%

===问:

给定一个 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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值