IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode打卡练习——第三题 无重复字符的最长字串 -> 正文阅读

[数据结构与算法]LeetCode打卡练习——第三题 无重复字符的最长字串

题目

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:
输入: s = “”
输出: 0
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官授权,非商业转载请注明出处。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:

做题经历

这个文章当中,我会比较详细的以我自身的做整道题的过程进行讲解,可能有些错误或是没有注意到的地方可能看起来有点蠢,请大佬勿喷,毕竟这是我第一次在力扣上做题。另外就是说,可能也有其它像我一样的小白,在做这道题的时候看一遍别人的题解,也明白,然后自己上手的时候,就会报这样那样的错误。所以这算是记录自己的做题经历,也是提供给其它和我一样的小白一些借鉴。
(如果感觉不需要过分看我的做题情况的话,可以直接跳到最后的总结)

分析

在这次练习中,从一直报错、更改、到运行成功,大概改了四次(可能更多,但我在本地编辑器里记录了四次),然后运行成功后,又进行了两次优化。先张贴一下我运行的情况
这是第一次运行成功第一次优化,时间降了20ms左右
这是后来的优化情况
最后还有一部分是简化代码的部分我就不张贴了。
最好情况是32ms,内存占用14.8(当然这俩不是同时出现的)
还要特别说明一下,我的全程是没有看过别人的题解的,所以绝对不是拿别人的东西写给大家!!!


开始分析

首先拿到这道题的时候,扫描一个最长字串,后来看题解的时候知道有一个滑动窗口的概念,力扣官网的网址,已经放在这了,有兴趣的可以自己看一下,在这我就不去讲这个了。还有就是我也不会去介绍所有情况吧,类似于用两重循环暴力求解这种,本身我们来刷题是提高自己算法优化的能力,那么就不适合在这写出这种东西。

回归正题,扫描一个最长字串,我的一个想法是,创建一个队列,遍历这个字符串,每一次遍历都往队列当中添加遍历的字符,当队列中存在相同的字符时,开始出队,直至队列里面没有相同的元素。然后用一个变量来记录队列最长时的长度。这个想法和滑动窗口意思差不多,只是我当时不知道,当家可以看一下视频,有动图展示会更生动,好理解。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第一次代码

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        
        string = ''+s[0]  #这个是创建的字符串队列
        length = []		#刚开始想的是用字典来记录每一次的长度,然后取出最大
        for i in range(1,len(s)):
            if s[i] in string:    #当加入的字符已经存在字符串队列中时
                string = string[1:]   #第一个字符出队,后边我有用lstrip来替换
            if string[-1] == s[i]:	#这里是两个相同字符连在一起的情况判断,是我的一个错误想法
                length.append(len(string))#记录下当前的长度
                string = ''			#因为两个挨着字符相同,所以清空前面的字符
            string = string + s[i]#入队

        length.append(len(string)) #记录最后的长度
        return max(length)
            
a = Solution()
print(a.lengthOfLongestSubstring('abcabcb'))
>>> 3
print(a.lengthOfLongestSubstring('bbbbb'))
>>> indexerror:string index of range line 9

很长而且很垃圾,但是我还是要说,嘿嘿,这段代码运行是没有错的,但是当把’bbbbbbb‘作为参数运行的时候会报一个indexerror的错误。虽然代码很垃圾,我现在看也是这么觉得的,但是当时运行过第一个案例我感觉贼厉害。我就先说一下我这段代码的思维,以及报错原因把。毕竟我敲字的时候也看不下去。

基本上我都注释在上边每一步是做什么了,但简单讲一下代码部分
为什么在string后边要加一个s[0]?

因为我是在循环的最后进行一个入队的操作,但是在第二个if那里有一个string[-1],如果string是空字符串的话,会报一个indexerror的错误

为什么’bbbbbb’作为参数时会报错?

可以看到第一个分支那里,因为都是’b’所以string删除了首个字符成了空字符串,所以会报错


第二次代码

对上次的修改,我发现其实第二个分支其实是属于第一次分支内所包含的,所以进行了如下调整

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        
        string = ''+s[0]
        length = [1]
        for i in range(1,len(s)):
            if s[i] in string:
                
                if string[-1] == s[i]:
                    print(string)
                    string = s[i]
                    continue

                string = string[1:]
            string = string + s[i]
            length.append(len(string))
            print(string)   #输出错误,查看string情况
        return max(length)
        
a = Solution()
print(a.lengthOfLongestSubstring('ckilbkd'))
> ck
> cki
> ckil
> ckilb
> kilbk
> kilbkd
> 6

此次调整后’bbbbb‘的结果运行成功,但是在该参数中,结果输出错误,很明显结果应该是5,但是输出了6,然后我用print打印了一下过程,可以发现在第二个k出现的时候,程序只做了一次出队的操作,但是呢,第一个k是的位置在1(设队首为0),所以在后续的length中添加的情况实际是有两个k的,那么造成结果错误。


第三次代码

这次代码我就只针对这次情况投机取巧了一下,用了一下集合的性质,但不建议大家像我这么做,还是踏踏实实做。但是当输入下一个测试案例的时候我发现我的全盘都需要改

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        
        string = ''+s[0]
        length = [1]
        for i in range(1,len(s)):
            if s[i] in string:
                
                if string[-1] == s[i]:
                    print(string)
                    string = s[i]
                    continue

                string = string[1:]
            string = string + s[i]
            length.append(len(set(string)))   #没啥变化就是这里变成了集合
            print(string)
        return max(length)
a = Solution()
print(a.lengthOfLongestSubstring(“”))

> indexerror

输入一个空字符串,很显然在声明string和赋值的时候会报这个错误,因为我后来的分支有必须要那么去定义这个变量,就说明我的这个思路有问题的,但是我还是挣扎了一下,我把空字符串当成一种特殊情况,直接返回0,但是也对其它的部分进行一点点修改,而且为了节省空间改用一个变量储存长度。而且也去掉了那个集合的投机行为,以为之后我也有因为没有处理好那个而报错


第四次代码

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if s == "":
            return 0

        
        string =""+s[0]
        temp = len(string)
        for i in range(1,len(s)):
            while s[i] in string and string != '':         
                if string[-1] == s[i]:
                    string = string.lstrip(string[0])
                    break

                string = string.lstrip(string[0])
                

            string = string + s[i]
            if len(string)>temp:
                temp = len(string)

        return temp
a = Solution()
print(a.lengthOfLongestSubstring('pwwkew'))
> 4

结果应该是3但是这里输出了4。关键点在于while循环里的分支终止。因为这个分支是对两个相同字符挨在一起的情况进行处理,那么也就是应该,删除掉之前所有的元素,但是这里的break就只是删除了一次。所以说应该把break改为continue,那么改为continue之后,就运行成功了


运行成功

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if s == "":
            return 0

        
        string =""+s[0]
        temp = len(string)
        for i in range(1,len(s)):
            while s[i] in string and string != '':         
                if string[-1] == s[i]:
                    string = string.lstrip(string[0])
                    continue

                string = string.lstrip(string[0])
                

            string = string + s[i]
            if len(string)>temp:
                temp = len(string)

        return temp

在这里插入图片描述
左边的都是这段代码的运行情况,我们就运行成功了!!![撒花] [撒花]


简化代码

这段代码虽然运行成功了,但是我感觉可读性和简洁程度都有很大的改善,而且有些多余的条件判断可以去掉来提高性能,我就直接贴代码了。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        
        string =""
        temp = len(string)

        for i in s:
            
            while i in string and string != '':                
                string = string.lstrip(string[0])
                
            string = string + i
            if len(string)>temp:
                temp = len(string)

        return temp

那么这段代码就相比较之前那一个更加pythonic,思路的话就是我最开始所讲的思路,也都呈现在了这里,然后在写这篇文章时,又运行了一次给大家看一下效果。然后如果有大佬认为还可以继续改进优化,可以私信我或评论。
在这里插入图片描述


总结

简单总结一下,我在这道题中的体会。

第一个:关于题目
其实大家要是像我一样每一次这种思路的话,其实可以发现,每一次我们所遇见的都是一个新的问题,而我只是针对每一次问题进行了解答。但是我们需要做的是一个通解。
比如’bbbbb‘ 是要求每一次队列里只有一个
’ckilbkd‘,是要求你不能出一个进一个
’‘空字符,也是检验你的程序情况等
其实每一个测试都是反映了一种特殊情况,只不过我这是隔天写的,也就忘了当天的一些总结。如果有同学和我一样幸运,几乎每一个新的测试案例都会报错,那么你应该也会知道每个点都在哪。
但是最后思想都是我最开始的那个思想,就是利用队列,或者说是滑动窗口,可能官方还有更好的题解,但那不是我的,所以我没有列出来

第二个:关于代码
大家可以发现,我最开始的代码看起来可读性很差,以及逻辑思路不清晰,甚至对于一些基本操作用了很奇怪的方法,这就是emmm…,没有一个好的编程习惯,我指的是经常敲,那么就让我的一些这种能力很差,以至于写出来的代码也很让人头疼。甚至说我在里边因为lstrip()函数的使用,都用了很长时间,才发现,她并不会去修改原字符串,需要重新赋值,所以我最开始用的切片操作。所以还是经常敲一敲代码,养成一个好的习惯。


再BB两句

这是我第一次刷力扣的题,其实曾经也尝试过,因为不是计算机专业,没有学过数据结构所以很吃力,甚至说都看不懂别人的题解,然后现在因为是开学大三,有准备跨考计算机的打算,所以说呢暑期看了看数据结构(写这篇文章的时候还没看完,刚到二叉树),那么也想尝试一下,所以我能做出来还是很有成就感的,而且一次次优化,看着运行时间一次次减少,真的很兴奋。现在也是有这么一个打算,会定期的开始更新一些力扣题库的做题记录,算是在这打卡把。我也不知道我能坚持多久,因为好像写这个文章好像也很费时间,我也希望大家可以私信我或者多多评论交流,让我保持着这么一份热情,能够一直写下去。同时也希望大家可以对我的错误指正或者拓展一些知识,万分感谢~~~

谢谢大家~

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 08:04:35  更:2021-07-28 08:05:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 20:26:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码