无重复字符的最长字串算法


1、问题描述

1. 问题

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

2. 例子

示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:
输入: s = “”
输出: 0


2、暴力算法

首先,题目要求无重复,那么就涉及到比较,所有就需要两个指针 l e f t , r i g h t left,right left,right。首先,两个指针初始指向0号位,当right<n(n为字串长度)时,right与其左边的字串一一比较(也要进行循环判断),如果right与第i个字符相等,那么此时right右边字串长度length=right-left;下次循环时候,left=i+1。

1. 代码如下

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int left = 0;
        int right = 0;
        int count = 0;//最长字串
        int length = 0;//中间段的无重复字串长度
        int n = s.size();
        while(right < n) {
        //right与其左边字符一一比较
        	for(int i = left; i < right; i++) {//left为与right没重复的字串起始点
        		if(s[i] == s[right]) {
					left = i+1;//下次left与right没重复的字串起始点
                    break;//遇到相等,退出循环
				}
				//如果不相等,那么继续循环
			}
			//当循环结束,即可找到中间段最长无重复字串,将其与前面得到的最长字串进行比较,长的赋值给count
            length = right-left+1;
			count = max(count,length);
			right++;//right右移,进行下一段循环
        }
        return count;
    }
};

2. 复杂度:

时间复杂度小于 O ( n 2 ) O(n^2) O(n2),大于 O ( n ) O(n) O(n)
空间复杂度 O ( 1 ) O(1) O(1)

3、容器–哈希表法

算法思想和上面一样,只是这里使用容器unordered_map来处理;

1. unordered_map容器介绍参考来源

unordered_map 容器底层采用的是哈希表存储结构,根据关键字是否已经存在来判断字串长度。

2. 代码如下

class Solution
{
public:
    int lengthOfLongestSubstring(string s)
    {
        int left = 0;//第一个指针
        int right = 0;//第二个指针
        int length = 0;//中间段字串长度
        int count = 0;//最长字串长度
        int n = s.size();//字串总长度
        //c++的容器——unordered_map,它是一个关联容器,内部采用的是hash表结构,拥有快速检索的功能。
        unordered_map<char,int>hash;//创建一个空容器
        while(right < n){
        	char tempChar = s[right];
        	//当容器内key有重复,即新输入tempChar值和容器里面已存在的值(除最后一个=最后输入的值)相等,并且限制在left和right之间搜索
        	if(hash.find(tempChar) != hash.end() && hash[tempChar] >= left) {
				left= hash[tempChar] + 1;//下次循环的计算起点(左值)
			}
			hash[tempChar] = right;//下次循环起点(右值)
			length = right - left + 1;//中间字串长度
			count = max(count,length);//更新最长的字串
			right++;//进入下次循环
		}
		return count;
    }
};

3. 复杂度:

时间复杂度小于 O ( n ) O(n) O(n)
空间复杂度 O ( n ) O(n) O(n)

总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值