leecode刷题笔记-字符串

collections.Counter()

collections.Counter()用于快速设置哈希表,其中value的值是每个key出现的次数,举例如下:
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

示例:

s = “leetcode”
返回 0

s = “loveleetcode”
返回 2

class Solution:
    def firstUniqChar(self,s):
        dct = collections.Counter(s)
        for i, c in enumerate(s):
            if dct[c] == 1:
                return i
        return -1

“”.join(i.lower() for i in s if i.isalnum())

将一个包含大小写字母,数字,标点符号,空格等的数字转化为只有小写字母和数字的字符串
Python **join()**方法
描述
将序列中的元素以指定的字符连接生成一个新的字符串。

语法
语法: ‘sep’.join(seq)

参数说明:
sep:分隔符。可以为空
seq:要连接的元素序列、字符串、元组、字典

返回值
返回通过指定字符连接序列中元素后生成的新字符串。

>>> a="abcd"
>>> ",".join(a)
'a,b,c,d'

>>> "|".join(['a','b','c'])
'a|b|c'

>>> ",".join(('a','b','c'))
'a,b,c'

Python lower() 方法

Python lower() 方法转换字符串中所有大写字符为小写。


str = "THIS IS STRING EXAMPLE....WOW!!!";

print str.lower();

以上实例输出结果如下:

this is string example…wow!!!

Python字符串 isalnum()

用于验证字符串的组成。如果Python字符串isalnum()函数仅由字母数字字符组成,则返回True 。如果字符串为空,则isalnum()返回False

"".join(i.lower() for i in s if i.isalnum()) 中首先 ch.lower() for i in s if i.isalnum() 是对s的每个字符遍历,如果 i.isalnum()为True说明该字符是数字或者字母,此时调用i.lower将该字母变为小写,如果是数字,调用该函数后不变。前面的“”.join()是将这些处理后的字符一个一个连接,中间用“”连接,也就是直接相连。

自动机DFA

视频讲解链接详见:https://www.bilibili.com/video/BV1d54y127zc?from=search&seid=7731922146124169357

8. 字符串转换整数 (atoi)
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意:

本题中的空白字符只包括空格字符 ’ ’ 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

示例 1:

输入:s = “42”
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:“42”(当前没有读入字符,因为没有前导空格)
^
第 2 步:“42”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
^
第 3 步:“42”(读入 “42”)
^
解析得到整数 42 。
由于 “42” 在范围 [-231, 231 - 1] 内,最终结果为 42 。
示例 2:

输入:s = " -42"
输出:-42
解释:
第 1 步:" -42"(读入前导空格,但忽视掉)
^
第 2 步:" -42"(读入 ‘-’ 字符,所以结果应该是负数)
^
第 3 步:" -42"(读入 “42”)
^
解析得到整数 -42 。
由于 “-42” 在范围 [-231, 231 - 1] 内,最终结果为 -42 。
示例 3:

输入:s = “4193 with words”
输出:4193
解释:
第 1 步:“4193 with words”(当前没有读入字符,因为没有前导空格)
^
第 2 步:“4193 with words”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
^
第 3 步:“4193 with words”(读入 “4193”;由于下一个字符不是一个数字,所以读入停止)
^
解析得到整数 4193 。
由于 “4193” 在范围 [-231, 231 - 1] 内,最终结果为 4193 。
示例 4:

输入:s = “words and 987”
输出:0
解释:
第 1 步:“words and 987”(当前没有读入字符,因为没有前导空格)
^
第 2 步:“words and 987”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
^
第 3 步:“words and 987”(由于当前字符 ‘w’ 不是一个数字,所以读入停止)
^
解析得到整数 0 ,因为没有读入任何数字。
由于 0 在范围 [-231, 231 - 1] 内,最终结果为 0 。

此题采用DFA自动机求解:
思路

字符串处理的题目往往涉及复杂的流程以及条件情况,如果直接上手写程序,一不小心就会写出极其臃肿的代码。

因此,为了有条理地分析每个输入字符的处理方法,我们可以使用自动机这个概念:

我们的程序在每个时刻有一个状态 s,每次从序列中输入一个字符 c,并根据字符 c 转移到下一个状态 s’。这样,我们只需要建立一个覆盖所有情况的从 s 与 c 映射到 s’ 的表格即可解决题目中的问题。

算法

本题可以建立如下图所示的自动机:

我们也可以用下面的表格来表示这个自动机:
在这里插入图片描述

接下来编程部分就非常简单了:我们只需要把上面这个状态转换表抄进代码即可。

另外自动机也需要记录当前已经输入的数字,只要在 s’ 为 in_number 时,更新我们输入的数字,即可最终得到输入的数字。

代码

Max=2**31-1
Min=-2**31
class Automation:
    def __init__(self):
        self.state="start"
        self.sign=1
        self.ans=0
        self.table={"start":["start","signed","In_number","end"],
                    "signed":["end","end","In_number","end"],
                    "In_number":["end","end","In_number","end"],
                    "end":["end","end","end","end"]
                    }
    def get_c(self,c):
        if c.isspace(): #字符串内置库函数判断是否为空格
            return 0
        if c=="+" or c=="-":
            return 1
        if c.isdigit():#字符串内置库函数判断是否为数字
            return 2
        return 3   
        
    def get(self,c):
        self.state=self.table[self.state][self.get_c(c)]
        if self.state=="In_number":
            self.ans=self.ans*10+int(c)
            self.ans=min(self.ans,Max) if self.sign==1 else min(self.ans,-Min)
        elif self.state=="signed":
            self.sign=1 if c=="+" else -1

class Solution:
    def myAtoi(self, str):
        a=Automation()
        for i in str:
            a.get(i)
        return a.sign*a.ans

242.有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

示例 1:

输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:

输入: s = “rat”, t = “car”
输出: false
说明:

解法:
采用哈希表(字典),方法是在哈希表中存入第一个字符串s的每个字符和其对应出现的频率,采用dic[i]=dic.get(i,0)+1 来实现。之后在dic中遍历t,对t中的每个dic有的字符频率-1。
最后对dic遍历,如果有字符的频率不是0.说明不相同,输出false

class Solution(object):
    def isAnagram(self, s, t):
        if len(s)==len(t)==0:
            return True
        if len(s)==len(t):
            dic={}
            for i in s:
                dic[i]=dic.get(i,0)+1 # dic中i是label,Value是对应的各字符出现的频率
            for i in t:
                if i in s:
                    dic[i]=dic.get(i)-1
                else:
                    return False       # i不在s中,说明t中有s所没有的字符,直接输出False
            for i in dic.values():
                if i!=0:
                    return False
                else:
                    return True
        else:
            return False

28. 实现 strStr()

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。

示例 1:

输入: haystack = “hello”, needle = “ll”
输出: 2
示例 2:

输入: haystack = “aaaaa”, needle = “bba”
输出: -1
说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

滑动窗口解决

class Solution(object):
    def strStr(self, haystack, needle):
        l1,l2=len(haystack),len(needle)
        for i in range(l1-l2+1):
            if haystack[i:i+l2]==needle[:]:
                return i
        return -1

38. 外观数列

给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

countAndSay(1) = “1”
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:

  1. 1
    
  2. 11
    
  3. 21
    
  4. 1211
    
  5. 111221
    

第一项是数字 1
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 “11”
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 “21”
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 “1211”
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 “111221”
要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

例如,数字字符串 “3322251” 的描述如下图:

在这里插入图片描述

代码

class Solution:
    def countAndSay(self, n):
        pre='1'
        s,e=0,0
        cur=[]
        if n==1:
            return pre
        while n>1:
            while e<len(pre):
                while e<len(pre) and pre[s]==pre[e]:
                    e+=1
                l=e-s
                cur.extend([str(l),pre[s]]) #用extend()不用append()是因为extend可以一次往list中加入多个元素,比如这里加了两个元素:数字出现的次数和该数字
                s=e
            pre=cur
            s,e=0,0
            cur=[]
            n-=1
        return ''.join(pre)#比如pre=['0','1'] 那么'!'.join(pre)结果就是'0!1' 所以''.join(s)作用是将s里的字符串的每个元素用''里的字符进行连接

49. 字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。

示例 1:

输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]
示例 2:

输入: strs = [""]
输出: [[""]]
示例 3:

输入: strs = [“a”]
输出: [[“a”]]

class Solution:
    def groupAnagrams(self, list):
        dic = {}
        for s in strs:
            keys = "".join(sorted(s))#b =sorted(s) b=['a', 'e', 't'] keys='aet'

            if keys not in dic:
                dic[keys] = [s]
            else:
                dic[keys].append(s)
        return list(dic.values())

sort()与sorted()的区别见:https://blog.csdn.net/zhouxbr/article/details/103233817
简单来说sorted()是更高级的sort 可以定义按照什么排序 比如按照每个元素的长度等,也可以直接对数字字符串的值进行排序 这里将每个单词用sorted()排序后得到一个字符数组,用“”.join拼接后得到一个字符串也作为key 原理是如果是符合要求的单词 那么他的单词排序后得到的结果一定是相同的,如eat和ate的排序后结果都是‘aet’(排序是按ascii值排序),这里最后得到的字典就是[{‘aet’:‘eat’,‘ate’}]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值