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

1、最长的重复子串

  寻找一个字符串中最长的重复子串

  最大后缀方法思路:

1. 用字符串指针数组保存用户输入的字符串的所有后缀字符串;

2. 将后缀字符串集合进行排序;

3. 比较相邻字符串的公共子串长度,找到长度最大值,保存相应字符串即为所求

  空间复杂度:求长度为n的字符串的后缀,需要O(n)的空间复杂度 
  时间复杂度:产生后缀数组-时间复杂度O(N)、对后缀数组排序是O(N*NlogN),第一个N表示字符串的比较,后面NlogN使用快排排序。依次检测相邻两个后缀的公共长度-时间复杂度O(N*N)、取出最大公共长度的前缀-时间复杂度O(N)。直接用sort排序,时间复杂度是nlog(n)。

总的时间复杂度是O(N*NlogN)

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include <vector>
#include<string>
#include<sstream>
#include<map>
#include<set>
#include <functional> // std::greater
using namespace std;

int getCommon(string s1, string s2)
{
    int i = 0;
    for (; i < s1.size()&& i<s2.size(); ++i)
    {
        if (s1[i] != s2[i])
            break;
    }
    return i;
}

int main()
{
    string str;
    cin >> str;
    vector<string> strs;
    for (int i = 0; i < str.size(); ++i)
    {
        strs.push_back(str.substr(i));
    }
    sort(strs.begin(),strs.end());
    int maxlen = 0;
    string res;
    for (int i = 1; i < strs.size(); ++i)
    {
        int len = getCommon(strs[i-1], strs[i]);
        if (maxlen < len)
        {
            maxlen = max(maxlen, len);
            res = strs[i - 1].substr(0,len);
        }
    }
    cout << res<<"\n" << maxlen << endl;

    return 0;
}

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

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

示例 1:

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

示例 2:

输入: "bbbbb"
输出: 1
解释: 无重复字符的最长子串是 "b",其长度为 1。

示例 3:

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

方法一、

  我们之前手动推导的方法实际上是维护了一个滑动窗口,窗口内的都是没有重复的字符,我们需要尽可能的扩大窗口的大小。由于窗口在不停向右滑动,所以我们只关心每个字符最后出现的位置,并建立映射。窗口的右边界就是当前遍历到的字符的位置,为了求出窗口的大小,我们需要一个变量left来指向滑动窗口的左边界,这样,如果当前遍历到的字符从未出现过,那么直接扩大右边界,如果之前出现过,那么就分两种情况,在或不在滑动窗口内,如果不在滑动窗口内,那么就没事,当前字符可以加进来,如果在的话,就需要先在滑动窗口内去掉这个已经出现过的字符了,去掉的方法并不需要将左边界left一位一位向右遍历查找,由于我们的HashMap已经保存了该重复字符最后出现的位置,所以直接移动left指针就可以了。我们维护一个结果res,每次用出现过的窗口大小来更新结果res,就可以得到最终结果啦。

  这里我们可以建立一个256位大小的整型数组来代替HashMap,这样做的原因是ASCII表共能表示256个字符,所以可以记录所有字符,然后我们需要定义两个变量res和left,其中res用来记录最长无重复子串的长度,left指向该无重复子串左边的起始位置,然后我们遍历整个字符串,对于每一个遍历到的字符,如果哈希表中该字符串对应的值为0,说明没有遇到过该字符,则此时计算最长无重复子串,i - left +1,其中i是最长无重复子串最右边的位置,left是最左边的位置,还有一种情况也需要计算最长无重复子串,就是当哈希表中的值小于left,这是由于此时出现过重复的字符,left的位置更新了,如果又遇到了新的字符,就要重新计算最长无重复子串。最后每次都要在哈希表中将当前字符对应的值赋值为i+1。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty())
            return 0;
        vector<int> m(256,0);
        int res = 0,left = 0;
        for(int i=0;i<s.size();++i)
        {
            left = max(left,m[s[i]]);
            m[s[i]] = i+1;//记录的位置都要+1,以区别默认的0
            res = max(res,i-left+1);
        }
        return res;
    }
};

 方法二:使用hash表记录位置

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty())
            return 0;
        unordered_map<char,int> m;
        int res = 0,left = 0; // 由于map不能初始化,所以默认为0
        for(int i=0;i<s.size();++i)
        {
            left = max(left,m[s[i]]);
            m[s[i]] = i+1; //此处记录的是第几个的位置
            res = max(res,i-left+1);//上面加1了,此处就要-1;
        }
        return res;
    }
};

原文地址:https://www.cnblogs.com/eilearn/p/9541232.html

时间: 2024-08-03 12:32:11

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

31:字符串中最长的连续出现的字符

31:字符串中最长的连续出现的字符 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 求一个字符串中最长的连续出现的字符,输出该字符及其出现次数.字符串中无空白字符(空格.回车和tab),如果这样的字符不止一个,则输出出现最早的字符. 输入 一行,一个不包含空白字符的字符串,字符串长度小于200. 输出 一行,输出最长的连续出现的字符及其最长的连续出现次数,中间以一个空格分开. 样例输入 aaaaadbbbbbcccccccdddddddddd 样例输出

leecode第三题(无重复字符的最长子串)

class Solution { public: int lengthOfLongestSubstring(string s) { int len=s.size(); if(len==0||len==1)//边界 return len; vector<int> is_here; for(int i=0;i<256;i++)//ASCII字符一共256个,建立一个辅助空间存储每个字符最后出现的位置 is_here.push_back(-1); int max_length=0; int j

lintcode 中等题:longest substring without repeating characters 最长无重复字符的子串

题目 最长无重复字符的子串给定一个字符串,请找出其中无重复字符的最长子字符串. 例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc",其长度为 3. 对于,"bbbbb",其无重复字符的最长子字符串为"b",长度为1. 解题 利用HashMap,map中不存在就一直加入,存在的时候,找到相同字符的位置,情况map,更改下标 public class Solution { /** * @param s: a s

【leetcode】 算法题3 无重复字符的最长子串

问题 给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 "bbbbb" ,最长的子串就是 "b" ,长度是1. 给定 "pwwkew" ,最长子串是 "wke" ,长度是3.请注意答案必须是一个子串,"pwke" 是 子序列  而不是子串 代码实现 class S

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

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

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

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

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

题目描述: 对于一个字符串,请设计一个高效算法,找到字符串的最长无重复字符的子串长度. 给定一个字符串A及它的长度n,请返回它的最长无重复字符子串长度.保证A中字符全部为小写英文字符,且长度小于等于500. 测试样例: "abcdbefgdchi",12 返回:8 这个题我研究了好半天,确实不好想,看了别人的思路,半天才把代码写出来 分析: 首先定义三个辅助变量: max_len:表示字符串中最长无重复字符的子串长度,也就是函数返回值 map<char, int>:用来存放

BAT面试算法进阶(2)- 无重复字符的最长子串(暴力法)

一.算法题 题目 Given a string, find the length of the longest substring without repeating characters. Example Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is "b", with the length

[LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串 C++语言 java语言实现

Given a string, find the length of the longest substring without repeating characters. Example 1: Input: "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3. Example 2: Input: "bbbbb" Output: 1 Explana