Hash表无重复字符的最长字串

在这里插入图片描述

在计算机科学领域,字符串处理是编程中最常见的任务之一。其中一个经典的问题就是找到一个字符串中无重复字符的最长子串。这个问题不仅考察了数据结构的理解,还涉及到算法设计的灵活性。本文将深入探讨如何利用哈希表(Hash Table)来高效解决这一问题,并通过多个示例代码来展示其实现过程。

基本概念和作用说明

什么是哈希表?

哈希表是一种非常有效的数据结构,它通过使用哈希函数将键映射到特定的位置,从而实现快速查找。哈希表的主要优势在于平均情况下插入和查找的时间复杂度都接近于O(1)。

无重复字符最长子串问题描述

给定一个字符串 s,找到其中没有重复字符的最长子串的长度。例如,对于输入 "abcabcbb",最长无重复字符的子串是 "abc",其长度为3。

示例代码

示例一:基础版滑动窗口法

最直观的方法是使用滑动窗口技术。滑动窗口是一个抽象的概念,它可以帮助我们有效地解决此类问题。

def lengthOfLongestSubstring(s: str) -> int:
    charMap = {
   
   }  # 存储字符及其最近一次出现的位置
    left = 0  # 滑动窗口左边界
    maxLength = 0  # 最长子串长度
    
    for right in range(len(s)):
        if s[right] in charMap:
            left = max(charMap[s[right]] + 1, left)
        charMap[s[right]] = right
        maxLength = max(maxLength, right - left + 1)
    
    return maxLength

示例二:优化版滑动窗口法

此版本在处理字符已经存在于窗口内的情况时进行了优化,避免了不必要的计算。

def optimized_lengthOfLongestSubstring(s: str) -> int:
    seen = {
   
   }  # 字符最近出现的位置
    start =
在JavaScript中,找出字符串重复最长的子串可以通过多种算法实现,其中一个高效的方法是使用动态规划。下面提供一个基于动态规划的示例实现: ```javascript function longestDupSubstring(S) { const MOD = 1000000007; const base = 26; // 字母的总数 let n = S.length; let maxLen = 0; // 最长相等子串的长度 let startIndex = 0; // 最长相等子串的起始索引 let hash = 0; // 当前子串的哈希值 let basePower = 1; // base的幂,用于计算新的哈希值 // 计算大的base的n-1次幂 for (let i = 0; i < n; i++) { basePower = (basePower * base) % MOD; } // 计算字符串哈希值 for (let i = 0; i < n; i++) { hash = (hash * base + S.charCodeAt(i) - 'a'.charCodeAt(0)) % MOD; } // 存储每个字符出现的哈希值和对应的索引 const indexMap = new Map([[hash, 0]]); // 使用滚动哈希来计算子串的哈希值 for (let i = 1; i < n; i++) { hash = (hash * base + S.charCodeAt(i) - 'a'.charCodeAt(0)) % MOD; if (indexMap.has(hash)) { let j = indexMap.get(hash); if (S.slice(j, i) === S.slice(j + maxLen, i + maxLen)) { startIndex = j; maxLen = i - j; } } else { indexMap.set(hash, i); } } // 返回最长重复子串 return S.slice(startIndex, startIndex + maxLen); } // 测试用例 console.log(longestDupSubstring("banana")); // 应该返回 "an" ``` 这段代码首先计算了字符串哈希值,然后使用一个哈希来存储出现过的子串哈希值及其起始索引。通过滚动窗口的方法,我们可以在O(n)的时间复杂度内找到最长重复子串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DTcode7

客官,赏个铜板吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值