3. 最长无重复子串Longest Substring Without Repeating Characters

本文介绍两种求解最长无重复子串的方法:一种使用C++实现,通过记录字符最后出现位置来高效寻找最长无重复子串;另一种采用Java实现,通过遍历所有可能的子串并检查其唯一性来解决问题。

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

Given a string, find the length of the longest substring without repeating characters. 找出字串S中最长无重复子串的长度。

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

 

法一:C++

 

class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            if(s.size()<2) return s.size(); //如果长度小于2 ,返回自身长度(有一个或零个元素)
            int d=1, maxLen=1;             //d存放两个相同元素的距离,如adlgdo,中d的相距距离是d = 3,所以有个无重复元素的串是“dlg”,长度是3
            unordered_map<char,int> map;  //存放元素最新出现的位置
            map[s[0]]=0;                  //第一个元素出现的位置自然是0
            for(int i=1;i<s.size();i++){ 
                if(map.count(s[i])==0 || map[s[i]]<i-d)  //如果这个元素出现次数为零。或者这个元素出现过,但是已经处理过(说明已经成对出现过)
                    d++;
                else    //表示这个元素出现过,从i开始,
                    d= i- map[s[i]];
                map[s[i]]=i;  //记录当前元素出现的位置
                if(d>maxLen)
                    maxLen = d;
            }
            return maxLen;
        }
    };

 

法二:

  1. 第一步:计算所有的子串,子串可以从S的下标 i 开始,到 j 结束(0≤i<j≤n )即 i 取值范围[ 0, n-1 ],j 取值范围[ 1, n ];
  2. 第二步:对S的所有子串“查重”。。方法是利用一个set集,每查重一个子串s,用一个新的空set。从 i 到 j 依次把子串s的字母存进set,存之前查看这个字母是否已存在于set,有的话,返回false,否则返回true
    Java
    
    public class Solution {
        public int lengthOfLongestSubstring(String s) {
            int n = s.length();
            int ans = 0;
            for (int i = 0; i < n; i++)
                for (int j = i + 1; j <= n; j++)
                    if (allUnique(s, i, j)) ans = Math.max(ans, j - i);     //ans存的是目前最大子串长度,j - i 代表当前子串长度
            return ans;
        }
    
        public boolean allUnique(String s, int start, int end) {    //相当于上边步骤2
            Set<Character> set = new HashSet<>();
            for (int i = start; i < end; i++) {
                Character ch = s.charAt(i);
                if (set.contains(ch)) return false;
                set.add(ch);
            }
            return true;
        }
    }

     

此方法时间复杂度,比较高,O(n​3​​)。

其他解题方法:http://www.cnblogs.com/grandyang/p/4480780.html 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值