myesn

myEsn2E9

hi
github

在一个字符串中取最大不重复子串(求长度和最长子串)

问题#

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

解法一:滑动窗口 + 哈希表#

image

求最大长度#

Console.WriteLine(LengthOfLongestSubstring("abcabcbb"));
Console.WriteLine(LengthOfLongestSubstring("bbbbb"));
Console.WriteLine(LengthOfLongestSubstring("pwwkew"));

// 得到给定字符串中最大不重复的子字符串的长度
int LengthOfLongestSubstring(string str)
{
    if (string.IsNullOrWhiteSpace(str)) return 0;

    // 哈希表统计字符 str[right] 最后一次出现的索引
    Dictionary<char, int> dic = new();
    // 定义左指针(-1和0都可以),最大不重复子字符串的长度
    int left = -1, res = 0;

    // 不断地增加 right 扩大窗口
    for (int right = 0; right < str.Length; right++)
    {
        //Console.WriteLine($"向右扩大区间: [{left}, {right}]");
        var currentChar = str[right];
        if (dic.ContainsKey(currentChar))
        {
            // 不断增加 left 缩小窗口,因为遇到了重复的字符,更新左指针为重复值的索引
            left = dic[currentChar];
            //Console.WriteLine($"向右缩小区间: [{left}, {right}]");
        }

        // 更新哈希表记录:当前遍历的字符最后一次在字符串中的出现的索引            
          dic[currentChar] = right;

        // 更新结果:用右指针减去左指针,得到双闭区间内最大不重复子串的长度
        // 再用 Max 函数取上轮 res 和本轮双指针区间 [left+1, right] 的宽度(即 right -left)中的最大值
        res = Math.Max(res, right - left);
        //Console.WriteLine($"------第 {right} 轮结果: {res}------{Environment.NewLine}");
    }

    return res;
}

求最大连续子串#

Console.WriteLine($"结果: {MaxChild("abca2f")}");
Console.WriteLine($"结果: {MaxChild("aabbcc")}");
Console.WriteLine($"结果: {MaxChild("aaaaa")}");

// 最长不重复子串(连续)
string MaxChild(string str)
{
    if (string.IsNullOrWhiteSpace(str)) return string.Empty;

    Dictionary<char, int> dic = new();
    int left = 0;
    string res = "";

    // [left, right]
    for (int right = 0; right < str.Length; right++)
    {
        // 当前遍历的字符
        char currentChar = str[right];
        // 是否已出现过,如果已出现就将左边界缩小为重复出现的索引
        if (dic.ContainsKey(currentChar))
        {
            // 当包含时代表出现重复字符串,缩小窗口
            left = dic[currentChar] + 1;

            //Console.WriteLine($"update {currentChar} {right}");
            // 更新索引
            //dic[currentChar] = right;
            dic.Clear();
        }

        dic[currentChar] = right;

        // 更新结果
        string sub = str.Substring(left, right - left + 1);
        if (sub.Length > res.Length)
        {
            res = sub;
        }
    }

    return res;
}

(待学习)解法二:动态规划 + 哈希表#

(看 K 神图解)

参考:#

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。