程序员的资源宝库

网站首页 > gitee 正文

3.无重复字符的最长子串 无重复最长子串长度

sanyeah 2024-03-29 17:58:38 gitee 11 ℃ 0 评论

题目:

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

 

示例 1:

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

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

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

提示:

0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

错误思路,没有看清题目,寻找的是最长子串,一下程序只能寻找从头部开始的子串

思路:

      一开始思路为利用第一题时的哈希表能快速查找Key是否存在的特性,将每一个字符按顺序存入哈希表中,字符为Key,当前位置+1为value。如果key值存在,则输出该key值得value就行。时间复杂度为n,但是用到了哈希表,空间占用可能会很大。

问题:

      题目中的String是一个类,而不是指针,使用了*(s+i-1),报错;如同数组s[i]即可获取当前字符,另外也可以使用c_str()或者data(),即可返回一个*char指针;

 

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char,int> map;
        for(int i=1;i<=s.length();i++){
            if(map.count(s[i-1])==0)
                 map.emplace(s[i-1],i);
            else return i-1; 
        }
        return 0;
    }
};

 

测试结果:

通过测试用例:117 / 987
输入:
"pwwkew"
输出:
2
预期结果:
3
问题:子串遍历错误

新思路

新思路:

         在了解string类时意外发现了size_t find()函数,可以方便的查找子串是否存在,同样也可以查找字符是否存在。这样就把不用舍本逐末去使用哈希表。

         下面是对size_t的学习:

          初步了解:size_t在32位系统中位4字节,在64位系统中位8字节。emmm,就这些,在深入涉及会无穷无尽,及时跳出本秃头接班人的学习之道。

          string的学习:

          构造函数 string s("string")      string s(int ,char)          string s(string,int,int)

          常用方法:

                 插入    string s.insert(int , string)        删除   string s.erase(int ,int )

                查找     string s.find(string)          比较   string s.conpare(string) 或者> < != ==等

                连接     +                   求子串      string s.substr(int ,int );

 

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        string Max;
        string com;
        for(int i=0;i<s.length();i++){
            if(com.find(s[i])==string::npos){
                com=com+s[i];
            }
            else{
                com=com.erase(0,com.find(s[i])+1);//erase (int 1,int 2) int2不会删除
                com=com+s[i];
            }
            if(com.size()>Max.size()){
                Max=com;
            }
        }
        return Max.size();
    }
};

运行结果

执行用时:32 ms, 在所有 C++ 提交中击败了28.09%的用户
内存消耗:20.2 MB, 在所有 C++ 提交中击败了7.92%的用户
通过测试用例:987 / 987

 

标准答案:

 思路:

        

这样一来,我们就可以使用「滑动窗口」来解决这个问题了:

我们使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着上文中「枚举子串的起始位置」,而右指针即为上文中的 r_kr
k
?

在每一步的操作中,我们会将左指针向右移动一格,表示 我们开始枚举下一个字符作为起始位置,然后我们可以不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。在移动结束后,这个子串就对应着 以左指针开始的,不包含重复字符的最长子串。我们记录下这个子串的长度;

在枚举结束后,我们找到的最长的子串的长度即为答案。

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-leetc-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分析: 从思路上看与我的思路一致,但是在代码实现上存在区别;

使用unorderd_set ,同样是一个哈希集合,不同的是unorderd_set没有key,可以说value就是他的key,这与unorderd_map不同,方法上大致相同

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表