京东测试开发面试题:无重复字符的最长子串

📝 面试求职: 「面试试题小程序」内容涵盖 测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、性能测试、计算机网络知识、Jmeter、HR面试,命中率杠杠的。(大家刷起来…)

📝 职场经验干货:

软件测试工程师简历上如何编写个人信息(一周8个面试)

软件测试工程师简历上如何编写专业技能(一周8个面试)

软件测试工程师简历上如何编写项目经验(一周8个面试)

软件测试工程师简历上如何编写个人荣誉(一周8个面试)

软件测试行情分享(这些都不了解就别贸然冲了.)

软件测试面试重点,搞清楚这些轻松拿到年薪30W+

软件测试面试刷题小程序免费使用(永久使用)


题目描述:

无重复字符的最长子串问题是一个经典的字符串处理问题,旨在找到给定字符串中最长的不包含重复字符的子串。

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

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

示例三:输入: s = "pwwkew"输出: 3解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。

请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

示例4:输入: s = ""输出: 0

解法1:暴力法

思想:通过穷举所有可能的子串,检查每一个子串是否含有重复字符,记录最长的有效子串长度。

def length_of_longest_substring(s: str) -> int:
def is_unique(sub: str) -> bool:
return len(sub) == len(set(sub))  # 检查子串是否唯一  

    max_length = 0  # 记录最长子串的长度  
for i in range(len(s)):  
for j in range(i + 1, len(s) + 1):  
if is_unique(s[i:j]):  # 如果子串是唯一的  
                max_length = max(max_length, j - i)  # 更新最长长度  
return max_length  

# 示例用法  
print(length_of_longest_substring("abcabcbb"))  # 输出3

时间复杂度:O(n²)

解释:外层循环遍历字符串的每个字符,内层循环遍历所有可能的子串。对于每个子串,检查其是否包含重复字符的操作需要 O(k) 的时间,其中 k 是子串的长度。因此,整体复杂度为 O(n²)。

空间复杂度:O(1)

解释:只使用了常量空间来存储变量,没有使用额外的数据结构。

解法2:滑动窗口法

思想:使用两个指针来表示当前的子串范围,利用一个哈希集(或字典)来检查字符的重复情况。

def length_of_longest_substring(s: str) -> int:
    char_set = set()  # 用于存储当前子串的字符  
    left = 0  # 左指针  
    max_length = 0  # 记录最长子串的长度  

for right in range(len(s)):  
# 如果右边的字符已经在子串中,则移动左指针  
while s[right] in char_set:  
            char_set.remove(s[left])  # 移除左指针指向的字符  
            left += 1
        char_set.add(s[right])  # 添加右边的字符  
        max_length = max(max_length, right - left + 1)  # 更新最长长度  

return max_length  

# 示例用法  
print(length_of_longest_substring("abcabcbb"))  # 输出3

时间复杂度:O(n)

解释:每个字符最多被访问两次(一次由右指针访问,一次由左指针访问)。因此,整体复杂度为 O(n)。

空间复杂度:O(min(n, m))

解法3:使用哈希表

思想:利用哈希表记录字符的最后出现位置,减少了对字符的重复遍历。

def length_of_longest_substring(s: str) -> int:
    char_index = {}  # 字符及其最后出现位置的字典  
    max_length = 0  # 记录最长子串的长度  
    left = 0  # 左指针  

for right in range(len(s)):  
if s[right] in char_index and char_index[s[right]] >= left:  
            left = char_index[s[right]] + 1  # 更新左指针  
        char_index[s[right]] = right  # 更新字符的最后出现位置  
        max_length = max(max_length, right - left + 1)  # 更新最长长度  

return max_length  

# 示例用法  
print(length_of_longest_substring("abcabcbb"))  # 输出3

时间复杂度:O(n)

解释:每个字符最多被访问两次,因此整体复杂度为 O(n)。

空间复杂度:O(min(n, m))

解释:与方法 2 类似,最坏情况下,空间复杂度取决于字符集的大小。

解法4:优化的滑动窗口法

def length_of_longest_substring(s: str) -> int:  
    char_index = {}  # 存储字符最新出现位置的字典  
    max_length = 0
left = 0

for right in range(len(s)):  
        # 如果字符 s[right] 在当前窗口内,更新左指针  
if s[right] in char_index:  
left = max(left, char_index[s[right]] + 1)  
        char_index[s[right]] = right  # 更新字符的最新位置  
        max_length = max(max_length, right - left + 1)  # 更新最大长度  

return max_length  

# 示例用法  
print(length_of_longest_substring("abcabcbb"))  # 输出3

时间复杂度:O(n)

解释:与方法 2 相同,每个字符最多被访问两次,因此整体复杂度为 O(n)。

空间复杂度:O(min(n, m))

解释:同样,最坏情况下,空间复杂度取决于字符集的大小。

总结

这四种方法中,暴力法最简单但效率最低,时间复杂度为 O(n²)。滑动窗口法及哈希表的结合方法具有较高的效率,时间复杂度为 O(n),适合用于处理较大规模的字符串。


最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取 【保证100%免费】
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值