无重复字符最长子串

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

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

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

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

解析

当然暴力求解法是可以的,对这个字符串的首尾都进行遍历,并且判断每个子串是否无重复,此时的时间复杂度为O(n^3),提交后超出时间限制,所以要进行优化,

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int maxlen=1;
        if(s=="")     //为空时判断
            maxlen=0;
        for(int i=0;i<s.length();i++)  
            for(int j=i+1;j<s.length();j++)
                if(ISUnique(s,i,j))               
                    maxlen=maxlen<j-i+1?j-i+1:maxlen;
                else
                    break;     
        return maxlen;
    }
    
    bool ISUnique(string s,int start,int end) {
        vector<char> charset;
        for(int i=start;i<=end;i++){
                if(find(charset.begin(),charset.end(),s[i])!=charset.end())
                         return false;
                charset.push_back(s[i]);       
        }
         return true;        
    } 
};

优化一

对字符串首尾进行遍历时,遇到子串重复时,则进行下一个子串的检测,这时对下一个子串的选取就很重要了,去除一些冗余的选择,可以提高我们的运行速度。
比如我们的头部遍历到i、尾部遍历到j时,发现它不是无重复字符串,换句话说就是第j个字符和前面i~j的字符里的某个重复了,那此时,将头部索引+1即变成i+1,是多余的,因为这个重复的字符在i-j之间,只要不是i,那此时的字符串依旧是重复的。
所以我们选取下一个待检查的字符串可选择i等于和j重复的那个字符的位置的后一个,j从当前j开始,不用从i+1开始重新遍历

优化二

对子串检查是否重复可利用map,构建哈希表,提高搜索速度

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
              int maxlen = 0;
              int j = 0,i=0;
 if (s == ""){
 maxlen = 0;
 return 0;
  }
 map<char, int> map1;
 while (i<s.length() -maxlen&& j < s.length())
  if (map1.find(s[j]) == map1.end() || (map1.find(s[j]) != map1.end()&& map1.find(s[j])->second < i)){
                  map1[s[j]] = j;
                  maxlen = maxlen < j - i + 1 ? j - i + 1 : maxlen;
   j++;
   }
  else{
   i = map1.find(s[j])->second + 1;
                                                     } 
 return maxlen;
}
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值