leetcode3无重复字符的最长子串(java)

题外话:

决定把算法捡起来,没想到leetcode国际服居然上不去了,这垃圾宽带。只能转战国服了。

初步解题思路:

遍历入参s,并维护一个map,key为s[i],value为i。

为什么需要这个map呢?当然是为了便于后面查找哪个字符跟当前坐标的字符重复了,如果重复了,假设map.get(当前字符)=dupIndex,下次搜索区间应该从leftIndex = dupIndex+1开始。

这样我们保证了搜索区间里的数据是不重复的。所以不用担心map被覆盖的问题,因为太早的重复数据已经没意义了(这一句看不懂可以忽略,我也不知道我在讲什么)。

但是map拿出的数据一定有效吗?最初我没有仔细思考,反正我维护了一个有效搜索区间,只要map.get(当前字符)>leftIndex即可。后面仔细想了下,回文数可以作为反例。

=======================分割================================

下图表示了两个字符重复的情况。把preIndex+1即可

talk is cheap:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length() == 0) {
            return 0;
        }
        int leftIndex = 0;
        int rightIndex = 0;
        Map<Character,Integer> map = new HashMap<>();
        int resultLen = 0;
        char[] sArr = s.toCharArray();
        for(int i=0;i<sArr.length;i++) {
            char c = sArr[i];
            // 与s[i] 相同字符的 上个坐标
            Integer dupIndex = map.get(c);
            if(dupIndex != null && dupIndex >= leftIndex) {
                resultLen = Math.max(i-leftIndex,resultLen);
                // 下次搜索区间的起始坐标
                leftIndex = dupIndex+1;
            }
            map.put(c,i);
        }
        return Math.max(s.length()-leftIndex,resultLen);        
    }
}

但是这个代码只击败了50%+的人。emmm,我不服,想了想思路应该优化不了,那么数据结构可能有问题。于是把hashMap换作数组即可。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length() == 0) {
            return 0;
        }
        int leftIndex = 0;
        //Map<Integer,Integer> map = new HashMap<>();
        int[] map = new int[128];
        for(int i=0; i<128; i++) {
            map[i] = -1;
        }
        int resultLen = 0;
        char[] sArr = s.toCharArray();
        for(int i=0;i<sArr.length;i++) {
            char c = sArr[i];
            // 与s[i] 相同字符的 上个坐标
            int dupIndex = map[c];
            if(dupIndex != -1 && dupIndex >= leftIndex) {
                resultLen = Math.max(i-leftIndex,resultLen);
                // 下次搜索区间的起始坐标
                leftIndex = dupIndex+1;
            }
            //map.put(c,i);
            map[c] = i;
        }
        return Math.max(s.length()-leftIndex,resultLen);        
    }
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值