LEETCODE学习 -- 3.无重复字符的最长子串
LEETCODE-3.无重复字符的最长子串
题目-无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
方法一 滑动窗口+hash表
直接两层循环遍历复杂度为O(n^2),故不采用,而使用一个哈希表。哈希表signal每个元素的标号表示该元素与空格符的差值,每个元素的值表示出现在字符串内的位置。例如,在字符串abbacb中,字符‘c’出现在第4位(从0开始计算),其哈希值为c-‘ ’ = 99 - 32 = 67,那么设置signal[67] = 4。在这里表的大小只是个人习惯问题,也可以从ascii码为0的空字符开始。
首先初始化signal,将其每一个元素初始化为-1。随后对输入字符串s从头开始遍历,如果当前字符c的哈希值在signal表中的值为-1,那么将其更改为c在字符串中的位置。如果在signal中的值大于等于0,说明该元素在当前子串中出现过。统计当前子串的长度,如果超过之前的最大值,就将最大值更新。将遍历位置修改为c在signal表中元素值的位置重新开始新一个子串的查找,清空signal表,重复之前的过程。
int lengthOfLongestSubstring(char * s){ int signal[96] = {-1}; int longest_sub_length = 0; int cur_sub_length = 0; int cur_sub_position = 0; int i = 0; int j = 0; memset(signal,-1,sizeof(signal)); while(s[i] != '\0') { if(signal[s[i]-' '] == -1) //当前字符未重复过 { signal[s[i]-' '] = i; i++; cur_sub_length++; continue; } else //当前字符是重复字符 { longest_sub_length = cur_sub_length > longest_sub_length ? cur_sub_length : longest_sub_length; cur_sub_position = signal[s[i]-' '] ; cur_sub_length = 0; for(j = 0; j < 95; j++) signal[j] = -1; i = cur_sub_position + 1; } } longest_sub_length = cur_sub_length > longest_sub_length ? cur_sub_length : longest_sub_length; return longest_sub_length; }
方法二 优化滑动窗口
方法一有一个多余的部分,即当出现重复字符,需要重置哈希表,之前已经在表中存在的元素将被初始化,还需要对这些元素进行重复的录入。所以优化如下:
- start指针表示当前子串的开始位置,哈希表构建还是和原来一样,不过元素存储的值从1开始计算。
- i表示当前遍历到的元素位置
- 如果s[i] > start,说明当前遍历到的元素在目前的子串的前缀中出现过,所以该子串遍历结束,计算子串长度
- 最重要的修改:当出现重复字符时,当前遍历的位置不会前跳,而是继续向后遍历,相对的只要修改子串的起始位置即可。
例如:字符串‘ilovelty’,起初子串的开始位置为0,当遍历到第二个’l‘时满足重复条件,此时更新最大字串长度,然后将子串的开始位置设置为o,即开始位置为2。遍历结束后最长子串为’ovelty’,长度为6。
int lengthOfLongestSubstring(char * s){ int i, j = 0, length = 0, max_length = 0, signal[128] = {0}, start = 0; for(i=0;s[i]!='\0';i++) { if(signal[s[i]]>start) { length = i-start; if(length>max_length) { max_length = length; } start = signal[s[i]]; } signal[s[i]] = i+1; } length = i-start; return length>max_length?length:max_length; }
参考
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/cyu-yan-shuang-yi-bai-by-wu-sheng-23/
- 点赞 1
- 收藏
- 分享
- 文章举报
- LeetCode 3. 无重复字符的最长子串
- leetcode 3. 无重复字符的最长子串
- Leetcode3. 无重复字符的最长子串
- LeetCode 3. 无重复字符的最长子串 Python
- LeetCode 3. 无重复字符的最长子串
- LeetCode题目C++实现:3. 无重复字符的最长子串
- LeetCode——3. 无重复字符的最长子串
- leetcode 3. 无重复字符的最长子串
- LeetCode3. 无重复字符的最长子串(python)
- 【LeetCode】3. 无重复字符的最长子串(Longest Substring Without Repeating Characters,24.2%,中等)
- [Leetcode] 3.无重复字符的最长子串
- LeetCode3. python实现:无重复字符的最长子串问题☆☆
- 【LeetCode】3.无重复字符的最长子串 结题报告 (C++)
- Leetcode-3.无重复字符的最长子串(python)
- LeetCode 3. 无重复字符的最长子串
- LeetCode 3. 无重复字符的最长子串
- leetcode 3. 无重复字符的最长子串(Java 版)
- Leetcode 3. 无重复字符的最长子串
- LeetCode--3.无重复字符的最长子串
- 【leetcode】3. 无重复字符的最长子串