剑指offer 专项突破版 16、不含重复字符的最长子字符串

题目链接

思路

哈希表+双指针

  • 通过一个哈希表来记录双指针间所有字符出现的次数
  • 当rigth移动后,如果某个字符出现次数不为0,那就向右移动left,直至这个字符出现次数是0,然后将right所对应字符放入表中
  • 计算此时的子数组长度
    class Solution {
        public int lengthOfLongestSubstring(String s) {
            int count = 0, left = 0;
            Map<Character, Integer> countNum = new HashMap<>();
    
            for (int right = 0; right < s.length(); right++) {
                //如果有重复
                while (left < right && 0 != countNum.getOrDefault(s.charAt(right), 0)) {
                    countNum.put(s.charAt(left), countNum.get(s.charAt(left++)) - 1);
                }
                countNum.put(s.charAt(right), 1);
                count = Math.max(count, right - left + 1);
            }
    
            return count;
        }
    }
    

可以优化一下,用哈希表保存所有遍历过的字符最后一次出现的位置,当遍历新字符时,如果没有在哈希表出现过,或者是出现过但是最后一次出现的位置比left小,那么就不用管,说明此时还是没有重复字符;如果在哈希表中出现过且比left大,那就把left更新为val+1

Go代码
func lengthOfLongestSubstring(s string) int {
	m := make(map[uint8]int)
	left, result := 0, 0

	for i := 0; i < len(s); i++ {
		appearIndex, ok := m[s[i]]
		if ok && appearIndex >= left {
			left = appearIndex + 1
		}
		result = max(result, i-left+1)
		m[s[i]] = i
	}

	return result
}

func max(m, n int) int {
	if m > n {
		return m
	}
	return n
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值