Leetcode 刷题第四周--字符串

Leetcode 38. 报数

报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1
11
21
1211
111221
1 被读作 "one 1" ("一个一") , 即 11。
11 被读作 "two 1s" ("两个一"), 即 21。
21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。
给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。
注意:整数顺序将表示为一个字符串。
示例 1:
输入: 1
输出: "1"
示例 2:
输入: 4
输出: "1211"

解题思路:三次遍历

class Solution:
    def countAndSay(self, n: int) -> str:
        s = '1' 
        # the number of output lines
        for i in range(n-1):
            
            output = ''
            j = 0
            # in the same line
            while j < len(s):
                k = j
                while k < len(s) and s[k] == s[j]:
                    k += 1
                output += str(k-j) + s[j] 
                j = k
                
            s = output
        return s

Leetcode 49. 字母异位词分组

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。

解题思路:
对每个词中的所有字母进行排序,排序后的词作为哈希表的索引,输出所有索引相同的词即可。

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        if len(strs) == 0:
            return None
        output = []
        dic = {}
        for word in strs:
            key = "".join((lambda x:(x.sort(),x)[1])(list(word)))
            if key in dic.keys():
                dic[key].append(word)
            else:
                dic[key] = [word]
        for k in dic.keys():
            output.append(dic[k])
        return output

Leetcode 151. 翻转字符串里的单词

给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

解题思路:
先翻转整个字符串,然后翻转每个单词。在Python中可以通过分割字符来移除多余空格。

class Solution:
    def reverseWords(self, s: str) -> str:
        # reverse the whole sentence
        s = self.reverse(s)
        result = [self.reverse(i) for i in s.split()]
        res = ''
        for i in result:
            res += i
            res += ' '
        return res.strip()
    
    def reverse(self, word):
        return word[::-1]

Leetcode 165. 比较版本号

比较两个版本号 version1 和 version2。
如果 version1 > version2 返回 1,如果 version1 < version2 返回 -1, 除此之外返回 0。你可以假设版本字符串非空,并且只包含数字和 . 字符。 . 字符不代表小数点,而是用于分隔数字序列。例如,2.5 不是“两个半”,也不是“差一半到三”,而是第二版中的第五个小版本。
你可以假设版本号的每一级的默认修订版号为 0。例如,版本号 3.4 的第一级(大版本)和第二级(小版本)修订号分别为 3 和 4。其第三级和第四级修订号均为 0。
示例 1:
输入: version1 = "0.1", version2 = "1.1"
输出: -1
示例 2:
输入: version1 = "1.0.1", version2 = "1"
输出: 1
示例 3:
输入: version1 = "7.5.2.4", version2 = "7.5.3"
输出: -1
示例 4:
输入:version1 = "1.01", version2 = "1.001"
输出:0
解释:忽略前导零,“01” 和 “001” 表示相同的数字 “1”。
示例 5:
输入:version1 = "1.0", version2 = "1.0.0"
输出:0
解释:version1 没有第三级修订号,这意味着它的第三级修订号默认为 “0”。
提示:
版本字符串由以点 (.) 分隔的数字字符串组成。这个数字字符串可能有前导零。
版本字符串不以点开始或结束,并且其中不会有两个连续的点。

解题思路:
用‘.’将版本号分开,将对较短的版本号末尾填充0,对比相应位数上的值。

class Solution:
    def compareVersion(self, version1: str, version2: str) -> int:
        v1 = version1.split('.')
        v2 = version2.split('.')
        a = len(v1)
        b = len(v2)
        while a < b:
            v1.append('0')
            a += 1
        while b < a:
            v2.append('0')
            b += 1
            
        for i in range(len(v1)):
            if int(v1[i]) < int(v2[i]):
                return -1
            elif int(v1[i]) > int(v2[i]):
                return 1  
        return 0

Leetcode 929. 独特的电子邮件地址

每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔。
例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名。除了小写字母,这些电子邮件还可能包含 '.' 或 '+'。如果在电子邮件地址的本地名称部分中的某些字符之间添加句点('.'),则发往那里的邮件将会转发到本地名称中没有点的同一地址。例如,"alice.z@leetcode.com” 和 “alicez@leetcode.com” 会转发到同一电子邮件地址。 (请注意,此规则不适用于域名。)如果在本地名称中添加加号('+'),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,例如 m.y+name@email.com 将转发到 my@email.com。 (同样,此规则不适用于域名。)可以同时使用这两个规则。给定电子邮件列表 emails,我们会向列表中的每个地址发送一封电子邮件。实际收到邮件的不同地址有多少?

class Solution(object):
    def numUniqueEmails(self, emails):
        """
        :type emails: List[str]
        :rtype: int
        """
        new_emails = {}
        for email in emails:
            name, domain = email.split('@')
            name = name.split('+')[0]
            name = name.replace('.', '')
            new_email = name + '@' + domain
            
            if new_email not in new_emails.keys():
                new_emails[new_email] = 1
        
        return len(new_emails.keys())

Leetcode 5. 最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"

解题思路:暴力解法,从头开始遍历枚举所有中心节点,看这个中心节点两段的最长回文字符串,取最大值即可。

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        res = ""
        i = 0
        while i < len(s):
            k = i
            j = i
            while k >= 0 and j < len(s) and s[k] == s[j]:
                if len(res) < j - k + 1:
                    res = s[k:j+1]
                k -= 1
                j += 1
            
            k = i
            j = i + 1
            while k >= 0 and j < len(s) and s[k] == s[j]:
                if len(res) < j - k + 1:
                    res = s[k:j+1]
                k -= 1
                j += 1
            i += 1
        return res

Leetcode 6. Z字形变换

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

解题思路:
把这个问题看做一个找规律的问题:可以看到,第一行和最后一行都是等差数列。中间的行是交错的等差数列,如:1, 9;7, 15。找到其中的规律,然后按顺序输出等差数列。

图片.png
class Solution(object):
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if numRows == 1:
            return s
        n = numRows
        res = ""
        for i in range(n):
            if i == 0 or i == n - 1:
                j = i
                while j < len(s):
                    res += s[j]
                    j += 2 * (n - 1)
            else:
                j = i
                k = 2 * (n - 1) - i
                while j < len(s) or k < len(s):
                    if j < len(s):
                        res += s[j]
                    if k < len(s):
                        res += s[k]
                    j += 2 * (n - 1)
                    k += 2 * (n - 1)
        return res

Leetcode 3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。

解题思路:
从头开始遍历,建立哈希表储存字符的位置,如果当前遍历到的字符在哈希表中没有出现过,则添加该字符;如果出现过,则原先不重复字符的起点需要加1,然后更新重复字符的出现位置。当新的不重复字符串长度大于原先字符串长度时,更新字符串长度。

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        l = 0
        start = 0
        dic = {}
        
        for i in range(len(s)):
            cur = s[i]
            if cur not in dic.keys():
                dic[cur] = i
            else:
                if dic[cur] + 1 > start:
                    start = dic[cur] + 1
                dic[cur] = i
            
            if i - start + 1 > l:
                l = i - start + 1
        return l

Leetcode 273. 整数转英文表示

将非负整数转换为其对应的英文表示。可以保证给定输入小于 231 - 1 。
示例 1:
输入: 123
输出: "One Hundred Twenty Three"
示例 2:
输入: 12345
输出: "Twelve Thousand Three Hundred Forty Five"
示例 3:
输入: 1234567
输出: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"

class Solution(object):
    def __init__(self):
        self.small = ['Zero','One ', 'Two ', 'Three ', 'Four ', 'Five ', 'Six ', 'Seven ', 'Eight ', 'Nine ', 'Ten ', 'Eleven ', 'Twelve ', 'Thirteen ', 'Fourteen ', 'Fifteen ', 'Sixteen ', 'Seventeen ', 'Eighteen ', 'Nineteen ']
        self.decade = ['', '', 'Twenty ', 'Thirty ', 'Forty ', 'Fifty ', 'Sixty ', 'Seventy ', 'Eighty ', 'Ninety ']
        self.big = ['Billion ', 'Million ', 'Thousand ', '']
    
    def numberToWords(self, num):
        """
        :type num: int
        :rtype: str
        """
        i = 1000000000
        j = 0
        res = ''
        while i > 0:
            if num >= i:
                res += self.part(int(num/i)) + self.big[j]
                num %= i
            i /= 1000
            j += 1
        return res.strip()
                
    def part(self, num):
        res = ''
        if num >= 100:
            res += self.small[int(num / 100)] + 'Hundred ' 
            num %= 100
        if num == 0:
            return res
        if num >= 20:
            res += self.decade[int(num / 10)]
            num %= 10
        if num == 0:
            return res
        res += self.small[int(num)]
        return res
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容