最长不重复子串

本文介绍了一种求解字符串中最长不重复子串长度的高效算法。通过使用哈希表记录字符出现的位置,该算法能在一次遍历中找到最长不重复子串的长度。示例包括输入'abcabcbb'输出3等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最长不重复子串

题目描述

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
Explanation: The answer is “b”, with the length of 1.
Example 3:

Input: “pwwkew”
Output: 3
Explanation: The answer is “wke”, with the length of 3.
Note that the answer must be a substring, “pwke” is a subsequence and not a substri

代码

 int lengthOfLongestSubstring(string s) {
        if(s.size() == 0)
            return 0;
        vector<int> hash(256,-1);
        int currsum = 0;
        int maxsum = 0;
        for(size_t i = 0; i < s.size(); i++)
        {
            if(hash[s[i]] == -1 || currsum < i - hash[s[i]])
                currsum++;
            else
            {
                currsum = i - hash[s[i]];
            }
            maxsum = max(maxsum,currsum);
            hash[s[i]] = i;
        }
        return maxsum;
    }
### C++实现最长重复子算法 在C++中,可以通过滑动窗口的思路来实现最长重复子的算法。滑动窗口是一种高效解决此类问题的方法,时间复杂度为O(N)。以下是基于滑动窗口方法的一种实现方式: ```cpp #include <iostream> #include <unordered_set> #include <string> using namespace std; int lengthOfLongestSubstring(string s) { int ret = 0; // 记录最长长度 int left = 0; // 左指针 int right = 0; // 右指针 unordered_set<char> window; // 窗口内的字符集合 int string_size = s.length(); // 字符长度 for (right = 0; right < string_size; right++) { char c = s[right]; // 当前字符 while (window.count(c)) { // 如果窗口内已存在当前字符 window.erase(s[left]); // 移除左指针指向的字符 left++; // 左指针右移 } window.insert(c); // 将当前字符加入窗口 ret = max(ret, right - left + 1); // 更新最长长度 } return ret; } int main() { string str; cout << "请输入字符:"; getline(cin, str); int maxLength = lengthOfLongestSubstring(str); cout << "最长重复子的长度为:" << maxLength << endl; return 0; } ``` 上述代码使用了`unordered_set`来存储滑动窗口中的字符,确保窗口内没有重复字符[^4]。通过两个指针`left`和`right`控制窗口的扩展与收缩,当遇到重复字符时,移动`left`指针以排除重复字符。 此外,还可以使用数组模拟哈希表的方式实现,这种方法避免了`unordered_set`的额外开销,具体实现如下: ```cpp #include <iostream> #include <string> using namespace std; int lengthOfLongestSubstring(string s) { int n = s.size(); int len = 0; // 最长长度 int hash[128] = {0}; // 使用数组模拟哈希表 for (int left = 0, right = 0; right < n; right++) { hash[s[right]]++; // 进入窗口 while (hash[s[right]] > 1) { // 判断是否有重复字符 hash[s[left++]]--; // 出窗口 } len = max(len, right - left + 1); // 更新结果 } return len; } int main() { string str; cout << "请输入字符:"; getline(cin, str); int maxLength = lengthOfLongestSubstring(str); cout << "最长重复子的长度为:" << maxLength << endl; return 0; } ``` 这种实现方式通过数组`hash`记录每个字符出现的次数,当某个字符出现超过一次时,移动`left`指针以缩小窗口,直到窗口内再有重复字符[^4]。 ### 注意事项 - 滑动窗口的核心思想是通过双指针动态调整窗口大小,确保窗口内的字符无重复。 - 使用`unordered_set`或数组模拟哈希表都可以实现,但数组方式通常性能更优,因为避免了哈希冲突的开销[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值