leetcode刷题之 无重复字符的最长子串(go实现)

4 篇文章 0 订阅

题目来自于LeetCode(https://leetcode-cn.com)。

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

          输入: "abcabcbb"
          输出: 3 
          解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

          输入: "bbbbb"
          输出: 1
          解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

          输入: "pwwkew"
          输出: 3
          解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
                   请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

解法一:暴力法(耗时468ms,内存6.6M)

两重循环对每个元素进行判断,若存在于map中,说明碰到相同的了,退出内层循环;反之则将元素加入map,计数加1;比较max和num,将最大值赋给max。

代码如下:

func lengthOfLongestSubstring(s string) int {
	slen := len(s)
	max := 0
    
	for i:=0;i<slen;i++ {
        res := make(map[string]string)
	    num := 0
		for j:=i;j<slen;j++{
			str := s[j:j+1]
			if _,ok:=res[str];!ok {
				res[str] = str
				num++
			}else{
				break
			}
		}
		if max < num{
			max = num
		}
	}
	return max
}

 解法二:设置标量,进行判断(耗时36ms,内存2.6M)

考虑到两层循环,时间复杂度肯定为O(n方),就思考用一个循环解决,于是设置两个标量,用来进行循环对比,时间复杂度降低到O(n)。思路看代码注释。strings.Index实际可能用到循环,所以时间复杂度还是可能为O(n方)

代码如下:

func lengthOfLongestSubstring(s string) int {
	slen := len(s)
	if slen == 1 || slen == 0 {
		return slen
	}
	max := 0
	start := 0
	end := 1
	for start < slen && end < slen {//循环条件
		var l = 0
		// fmt.Println("----",start,end,s[start:start+1],s[end:end+1],max)
		if s[start] == s[end]{//相等,说明不重复字串到此为止,算出长度
			l = end - start
			if max < l {
				max = l
			}
			start++
			end = start + 1
		}else{
			end++
			l = end - start
			if max < l {
				max = l
			}
			if max == slen {//最大的等于了长度,则说明,最长字串为自己
				break
			}
            if end >= slen{//如果end大于等于了截止条件,退出
				break
			}
			str := s[start:end]
			substr := s[end:end+1]
            index := strings.Index(str,substr)
			if  index != -1 {//前面的字串含有了新的字符,则说明有了,将start置为start+index+1,end置为start+1
				start = start + index +1
				end = start + 1
			}
		}
		// fmt.Println("++++",start,end,max)
	}
	return max
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值