zoukankan      html  css  js  c++  java
  • LeetCode_03 无重复最长子串

    题目描述

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

    示例

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

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

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

    知识点

    • 字符串+子串
    • 集合
    • 滑动窗口

    滑动窗口

    滑动窗口是数组/字符串问题中常用的抽象概念。
    窗口通常是在数组/字符串中由开始和结束索引定义的一系列元素的集合,即 [i, j)[i,j)(左闭,右开)。而滑动窗口是可以将两个边界向某一方向“滑动”的窗口。

    可以把滑动窗口看成一个队列,向右滑动的时候,就是左边元素出队

    子串

    串中字符各不相同,则子串的个数为n(n+1)/2+1空串
    如果串中有重复数字,则子字符串的个数为n(n+1)/2+1-重复个数

    ublic char charAt(int index)
    返回指定索引处的 char 值。索引范围为从 0 到 length() - 1。序列的第一个 char 值在索引 0 处,第二个在索引 1 处,依此类推,这类似于数组索引。
    如果索引指定的 char 值是代理项,则返回代理项值。

    解法

    思路一 暴力破解

    逐个检查所有的子字符串,看它是否不含有重复的字符。
    需要枚举给定字符串的所有子字符串

     for (int i = 0; i < n; i++)
                for (int j = i + 1; j <= n; j++)
    

    检查一个字符串是否有重复字符,我们可以使用集合。我们遍历字符串中的所有字符,并将它们逐个放入 set 中。在放置一个字符之前,我们检查该集合是否已经包含它。如果包含,我们会返回 false。循环结束后,我们返回 true。

    //java
    //代码注释来自于‘学习那些事’场外援助
    public class Solution {
    //返回长度
        public int lengthOfLongestSubstring(String s) {
            int n = s.length();
            int ans = 0;
            for (int i = 0; i < n; i++)//遍历整个字符串s
                for (int j = i + 1; j <= n; j++)
                    if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
                    //allUnique 会返回一个字符串是否含有重复字符,如果有返回false,没有返回true,而字符串便是s从i位置到j位置的字符
                    //故,如果当此子串没有喊有重复字符,其长度为j-i,math.max()则是,比较ans,和(j-i),并选择最大的返回,以保证ans时刻为最大的不重复字符串长度
            return ans;
        }
    //检查一个字符串是否有重复字符
        public boolean allUnique(String s, int start, int end) {
            Set<Character> set = new HshSet<>();//?
            for (int i = start; i < end; i++) {
                Character ch = s.charAt(i);//charAt返回指定i处的 char 值
                if (set.contains(ch)) return false;//contains:判断集合是否包含ch
                set.add(ch);
            }
            return true;
        }
    }
    

    思路二 滑动窗口

    
    #include <iostream>
    #include <string>
        using namespace std;
        class Solution {
        public:
            // 查找是否重复,若有重复则返回重复数字下标,若没有重复,则返回-1
            int isRepeat(string s, string sub) {
                if (s.find(sub) == s.npos) {//没有重复;find返回字母sub在母串s中的位置(下标记录);npos表示不存在的位置
                    return -1;
                }
                else {
                    return s.find(sub);//重复数字下标
                }
            }
            int lengthOfLongestSubstring(string s) {//定义函数lengthOfLongestSubstring返回最大不重复的位数
                if (s.length() == 0 || s.length() == 1)//如果字符串长度是0或者1直接返回长度
                    return s.length();
                int maxSize(1);//=1!全部重复的时候,长为1;用maxSize来记录不重复的字符串最长长度
                string substring = s.substr(0, 1);//substr(0,1)从0开始向后截取一位,代表着字符串的第一位
                for (int i = 1; i < s.length(); ++i) {
                    string temp = s.substr(i, 1);//substr(i,1)从i开始截取一位
                    int repeatPosit = isRepeat(substring, temp);//开始比较substr字符串和遍历第i字符串,如果有重复,返回数字下标
                    if (repeatPosit == -1) {//如果没有重复
                        substring.append(temp);//append直接在substring后面添加字符串temp(从i开始截取一位)
                        if (substring.length() > maxSize) {//把substring的长度直接返回给maxSize
                            maxSize = substring.length();
                        }
                    }
                    else {//如果有重复,repeatPosit是重复数字下标
                        substring.append(temp);//append直接在substring后面添加字符串temp(从i开始截取一位)
                        substring = substring.substr(repeatPosit + 1);//更换无重复字符串;substr截取了重复字符数字下标repeatPosit+1一直到结尾
                    }
                }
                return maxSize;
            }
        };
    
        int main() {
            Solution solution;
            string s("asdf123"), s1("pwwkew");
            cout << solution.lengthOfLongestSubstring(s) << endl;
            cout << solution.lengthOfLongestSubstring(s1) << endl;
        }
    
    
    
  • 相关阅读:
    微信公众号扫一扫接口
    JDBC-用户登录验证(sql注入)
    JDBC
    Shell脚本
    java-变量总结
    java-那些方法不能被重写
    java-数组工具类
    java-类初始化与实例初始化
    java-static
    java-native修饰符
  • 原文地址:https://www.cnblogs.com/zhuomoyixia/p/12324321.html
Copyright © 2011-2022 走看看