#leetcode刷题之路3-无重复字符的最长子串

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

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

字符数组和字符串的区别,C语言字符数组和字符串区别详解

开始的想法是在对字符数组设置两个指针,初始化一个在位置0一个在位置1,ans初始化为1(非空),然后1向后找,0不动,取0到1之间的字符串,判断是否重复(这里单独写一个函数,输入字符串,输出是否重复以及重复字符的后一个的位置),不重复的话用后位置减去前位置,再和ans比较,大的话就保留。如果有重复则前位置向后移动一位,后位置在其后面一位,接着判断之间的字符串是否重复。

#include <iostream>
using namespace std;

//判断是否有重复
bool re_or_not(string s)
{
    int len= s.length();
    for(int i=0;i<len;i++){
        for(int j=i+1;j<len;j++){
            if(s[i]==s[j]){
                std::cout <<  " true" << std::endl;
                return true;
            }
        }
    }
    std::cout <<  " false" << std::endl;
    return false;
}

int lengthOfLongestSubstring(string s) {
    //char* p1=(char*)s.data();
    //char*  p1=&s[0];
    //char* p2=p1+1;
    int len=s.length();
    //判空
    if(len==0)
        return 0;
    int num=1;
    int begin=0;
    int end=begin+1;
    int n=0;
    while(s[end]!=‘\0‘&&s[begin]!=‘\0‘){
        if(re_or_not(s.substr(begin,end-begin+1))){
            begin++;
            end=begin+1;
            std::cout <<  " 此时begin="<<begin<<  " 此时end="<<end<< std::endl;
        }
        else{
            if(end-begin+1>num)
                num=end-begin+1;
            std::cout <<  " 此时begin="<<begin<<  " 此时end="<<end<< std::endl;
            end++;
        }
    }
    return num;
}

int main() {
    string s="dewzyqprkqcmgfnrdfoflwsvkhylsfjxlhwlxne";
    int n=lengthOfLongestSubstring(s);
    std::cout << n << std::endl;
    return 0;
}

986 / 987 个通过测试用例
状态:超出时间限制

真的尴尬

再来:

优化,不用那个substring函数了

#include <iostream>
using namespace std;

//判断是否有重复
bool re_or_not(string s,int begin,int end)
{
    int len= begin-end+1;
    for(int i=begin;i<len;i++){
        for(int j=i+1;j<len;j++){
            if(s[i]==s[j]){
                std::cout <<  " true" << std::endl;
                return true;
            }
        }
    }
    std::cout <<  " false" << std::endl;
    return false;
}

int lengthOfLongestSubstring(string s) {
    //char* p1=(char*)s.data();
    //char*  p1=&s[0];
    //char* p2=p1+1;
    int len=s.length();
    //判空
    if(len==0)
        return 0;
    int num=1;
    int begin=0;
    int end=begin+1;
    int n=0;
    while(s[end]!=‘\0‘&&s[begin]!=‘\0‘){
        if(re_or_not(s,begin,end)){
            begin++;
            end=begin+1;
            std::cout <<  " 此时begin="<<begin<<  " 此时end="<<end<< std::endl;
        }
        else{
            if(end-begin+1>num)
                num=end-begin+1;
            std::cout <<  " 此时begin="<<begin<<  " 此时end="<<end<< std::endl;
            end++;
        }
    }
    return num;
}

int main() {
    string s="alqebriavxoo";
    int n=lengthOfLongestSubstring(s);
    std::cout << n << std::endl;
    return 0;
}

还是超时间;

再来:

因为所有字符只有256个,所以定义这样一个数组来判断重复就行了,同时,在遇到重复时,begin和end都后移一位

//判断是否有重复并输出位置
bool re_or_not(std::string s,int begin,int end)
{
int re[256]={0};
for(int i = begin; i<end+1; i++){
if(re[s[i]]==0){
re[s[i]]=1;
}
else return true;
}
return false;
}

int lengthOfLongestSubstring(string s) {
int len = s.length();
//判空
if (len == 0) return 0;
int num = 1;
int begin = 0;
int end = begin + 1;
int n = 0;
while (s[end] != ‘\0‘&&s[begin] != ‘\0‘){
if (re_or_not(s, begin, end)){
begin++;
end ++;
}
else{
if (end - begin + 1>num)
num = end - begin +1;
end++;
}
}
return num;
}

执行用时: 612 ms, 在Longest Substring Without Repeating Characters的C++提交中击败了0.98% 的用户

内存消耗: 332.3 MB, 在Longest Substring Without Repeating Characters的C++提交中击败了0.93% 的用户

这时间。。。。。,看来要大改了

还是上面的256的思路

#include <iostream>
#include <unordered_map>

using namespace std;

int lengthOfLongestSubstring(std::string s) {
    int len=s.length();
    //判空
    if(len==0)
        return 0;
    int re[256]={0};
    int num=1;
    int begin=0;
    for(int i=0;i<len;i++)
    {
        if(re[s[i]]==0||begin>re[s[i]])//不重复,所以要尝试更新num
            //这里不仅要考虑对应位置的值为0,同时还要考虑这样的字符串”abbca“,按之前的方法,最后一个a被当作出现过处理了。但实际上这个a也要加入计算的,所以这里要再加上一个判断条件
            //那就是如果此时begin>re[s[i]]的左边,也就是说就算重复了,但是新的a出现时,旧的a已经不再最长字符串的考虑范围内了(因为新字符串的begin位置已经在旧a的右边了)
        {
            if(num<i-begin+1)
                num=i-begin+1;
        }
        else//重复了,所以要把begin的位置更新到re中对应的字符对应的位置
        {
            begin=re[s[i]];
        }
        re[s[i]]=i+1;//+1是为了防止出错,因为i是从0开始的,后面的都要判断是否为0,所以要区别开
        std::cout << " 此时i=" << i << " 此时num=" << num << std::endl;
    }
    return num;
}

int main() {
    std::string s="abbca";
    int n=lengthOfLongestSubstring(s);
    std::cout << n << std::endl;
    return 0;
}

执行用时: 32 ms, 在Longest Substring Without Repeating Characters的C++提交中击败了49.69% 的用户
内存消耗: 14.7 MB, 在Longest Substring Without Repeating Characters的C++提交中击败了0.93% 的用户

还可以吧

原文地址:https://www.cnblogs.com/biat/p/10432023.html

时间: 2024-10-07 15:12:57

#leetcode刷题之路3-无重复字符的最长子串的相关文章

leetcode力扣刷题系列python——3、无重复字符的最长子串

题目: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1. 解法: 采用哈希表法:设定左右双指针l和r,遍历字符串:哈希表存储某字符s[i]最新在字符串中出现的位置index + 1,key, value

LeetCode 第3题 无重复字符的最长子串

/*3. 无重复字符的最长子串给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb"输出: 1解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew"输出: 3解释: 因为无重复字符的最长子串是 &qu

Leetcode(3)无重复字符的最长子串

Leetcode(3)无重复字符的最长子串 [题目表述]: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 第一种方法:暴力 执行用时:996 ms: 内存消耗:12.9MB 效果:太差 class Solution(object): def lengthOfLongestSubstring(self, s): """ :type s: str :rtype: int """ Maxsize=0 res='' if len(s)

Leetcode(无重复字符的最长子串;删除排序链表中的重复元素II;加一;最后一个单词的长度;相同的树)

1.无重复字符的最长子串 这题需要用到滑动窗口法,有许多问题都可以考虑使用滑动窗口法:https://www.geeksforgeeks.org/tag/sliding-window/ 因为用c++,所以用到set容器:std::count 2.删除排序链表中的重复元素II 3.加一 1 class Solution { 2 public: 3 vector<int> plusOne(vector<int>& digits) { 4 int n=digits.size()-

【Leetcode】【Longest Substring Without Repeating Characters】【无重复字符的最长子串】【C++】

题目:给定一字符串,求其无重复字符的最长子串长度. 思路:for循环一次,时间复杂度为O(N).字符的ascii值为32~126.start表示当前无重复字符子串的初始位置,初始值为0:可定义一个位置数组pos[128]表示for循环索引到当前位置时相应的字符对应的位置.若当前字符s[i](其ascii值为cur_pos),若pos[cur_pos]>=start,说明在start之后已有该字符s[i],则以start开始的子串第一次遇到重复字符,打住.判断当前长度是否大于max_len,若大于

代码题(56)— 最长重复子串、无重复字符的最长子串

1.最长的重复子串 寻找一个字符串中最长的重复子串 最大后缀方法思路: 1. 用字符串指针数组保存用户输入的字符串的所有后缀字符串: 2. 将后缀字符串集合进行排序: 3. 比较相邻字符串的公共子串长度,找到长度最大值,保存相应字符串即为所求 空间复杂度:求长度为n的字符串的后缀,需要O(n)的空间复杂度  时间复杂度:产生后缀数组-时间复杂度O(N).对后缀数组排序是O(N*NlogN),第一个N表示字符串的比较,后面NlogN使用快排排序.依次检测相邻两个后缀的公共长度-时间复杂度O(N*N

[LeetCode]无重复字符的最长子串

给定一个字符串,找出不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 无重复字符的最长子串是 "abc",其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 无重复字符的最长子串是 "b",其长度为 1. 示例 3: 输入: "pwwkew" 输出: 3 解释: 无重复字符的最长子串是 "wke",其长度为 3.   请注

LeetCode 无重复字符的最长子串(探索字节跳动)

题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "w

leetcode 3. 无重复字符的最长子串(Longest Substring Without Repeating Characters)

目录 题目描述: 示例 1: 示例 2: 示例 3: 解法: 题目描述: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew"

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

难度: 中等 题目 Given a string, find the length of the longest substring without repeating characters. 给定一个字符串,请你找出其中不含有重复字符的?最长子串?的长度. 示例?1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字