小white刷题记——LeetCodeHot100_3

读题心路历程:这道题意思感觉就是,给你一个字符串,然后找出无重复的最长字串,这个无重复的最长字串由题目来看包含两个特点:(1)无重复字母出现;(2)要是连续的。分析到这之后,脑海中就冒出了先遍历,然后定义个集合,利用集合可以find的优点,在遍历的过程中,把无重复的字符串存进集合,最后再size()一下集合的长度,整个一个okk。

但是自己写的过程中总是没法把例子全部跑对,还是结合了题解,进行了最终的代码编写。(这是现阶段没有办法的办法,好像还没有那个能力把自己的全部思路实现,标记一下,等回过头来,能力升上去了,再过来做这道题)

解题过程:

unordered_set<char> s1;//定义一个无序集合,这里不用set,也是因为set会自动排序的,不能用到这道题里
int left = 0;
int maxStr = 0;
//遍历题目给的字符串s
for(int i=0 ; i<s.size() ; i++)//
{    
    //这里只需要在遍历的过程中判断我们建的集合s1里边有没有字符串s中的字符s[i]
    //这是我一开始的代码if(s1.count(s[i])==0){};
    //这里只去判断一遍集合中是否有s[i],在正常解题的时候,就会遇到"pwwkew"例子过不了,仔细看一下就会发现原因,当s1中已经存进"pw"的时候,遍历到第s[2]的时候,就会发现s1中已经有w了,然后就erase掉s1的开头。在只判断一遍的情况下,这个时候s1里边实际存的是ww,这里就已经开始错误了。所以要在while循环里进行集合判断。
    while(s1.count(s[i])!=0)//当s1中s[i]的数量不等于0的时候——s1中已经存在s[i]的时候
    {
        s1.erase(s[left]); //这里就涉及到滑动窗口这个解题方法了,这个滑动窗口我觉得就是把我们建立的集合s1看成是一个边界会变的窗口,不停的改变集合s1的内部元素的过程就是滑动窗口在字符串s上滑动的过程。所以这里是需要一个left左指针(滑动窗口左边界,用来控制集合s1的左边界元素)。所以这里的left初始值可以定义为0;left=0的时候,意思就是集合s1中开头元素就是字符串中的第一个元素,如果遍历过程中,出现重复字符串,这时left就要加1;left=1的意思就是,我现在要删除此时集合s1中的第一个元素,这个元素就是字符串s[1]元素。
        left++;//这里left++的意思,显然就是在集合s1中的s[left]这个元素之后,需要让这个左指针指向s中的下一个元素了,所以要left++
    }
    //当判定集合s1中没有s[i]之后,这个时候就需要把s[i]插入到集合
    s1.insert(s[i]);
    //定义一个临时变量tmp用来存放集合s1的大小
    int tmp = s1.size();
    maxStr = max(maxStr,tmp);//这里是在移动序列s1的过程中,总会取得最大的值maxStr
}
return maxStr;

PS(补充知识点)文章参考:

http://t.csdn.cn/Mngr2

set和unordered_set的不同:

1)set基于红黑树,set里边的元素是会进行自动排序的,而unordered_set是基于哈希表的,它是无序的,如下图(1)所示。


图(1)

2)set进行搜索、插入、删除操作的时间复杂度为O(logn)。unordered_set实现起来的时间复杂度为O(1),但是由于unordered_set是基于哈希表的,所以空间复杂度高于set 的。

如果需要自动排序集合就用set,不需要的话unordered_set的效率高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值