LeetCode刷题笔记3——java-求最长子串(哈希表)

题目:

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

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

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

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

来源:力扣(LeetCode)

重点:

哈希表、滑块

代码

时间复杂度o(n2)的方法:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        String maxStr;
        int maxLen=0,exchang_1;
        int len=1,startIndex=0,endIndex=1;
        if(s.length()==1)
            return 1;
        while(endIndex<=s.length()){
            if(ifRepeat(s.substring(startIndex,endIndex))==100){//如果不重复
                if(s.substring(startIndex,endIndex).length()>maxLen){ //如果目前滑块的长度比最长的记录长则替换
                    maxStr=s.substring(startIndex,endIndex);
                    maxLen=s.substring(startIndex,endIndex).length();
                }
                endIndex++;
            }
            else{//如果有重复则把滑块开始坐标移动到第一个重复字符的下一个位置,保持滑块长度不变的前提下右移尾坐标
                System.out.println("此时startIndex="+startIndex+" endIndex="+endIndex);
                //窗口滑动
                exchang_1=startIndex;
                startIndex=startIndex+ifRepeat(s.substring(startIndex,endIndex))+1;
                endIndex=endIndex+ifRepeat(s.substring(exchang_1,endIndex))+1;
                System.out.println("滑动后startIndex="+startIndex+" endIndex="+endIndex);
            }
        }
        return maxLen;
    }
    //判断是否有字符重复
    public int ifRepeat(String s){
        Map<Character,Integer> m1=new HashMap();
        for(int i=0;i<s.length();i++){
            if(m1.containsKey(s.charAt(i)))
                return m1.get(s.charAt(i));//有重复并输出重复的字符的第一次出现位置
            else
                m1.put(s.charAt(i),i);
        }
        return 100;//表示无重复
    }
}

时间复杂度o(n)的方法:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character,Integer> m1=new HashMap();  //哈希表存放当前子串中的每个字符和其相当位置
        int starIndex=0,endIndex=0,maxLen=0,len=0;   //滑块头坐标、尾坐标、最大滑块长度、当前滑块长度
        while(endIndex<s.length()){                  //当滑块尾坐标在字符串长度范围内则循环
            if(m1.containsKey(s.charAt(endIndex)) && m1.get(s.charAt(endIndex))>=starIndex){  //易错点
                starIndex=m1.get(s.charAt(endIndex))+1;   //找到原子串重复字符的位置,把其下一个位置的坐标作为滑块首坐标
                m1.put(s.charAt(endIndex),endIndex++);  //把当前重复字符修改成最新的坐标值
            }
            else{             //如果新的字符在原字符串里没有,或者有但是在滑块首坐标之前,则把这个字符添加进滑块
                m1.put(s.charAt(endIndex),endIndex++);
                len=endIndex-starIndex;   //首位坐标差及时当前子串长度
            }
            maxLen=len>maxLen?len:maxLen;  //一旦当前子串长度比maxLen大则修改
        }
        return maxLen;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值