LeetCode算法-字符串-简单 P2

788. 旋转数字

我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后,我们仍可以得到一个有效的,且和 X 不同的数。要求每位数字都要被旋转。

如果一个数的每位数字被旋转以后仍然还是一个数字, 则这个数是有效的。0, 1, 和 8 被旋转后仍然是它们自己;2 和 5 可以互相旋转成对方(在这种情况下,它们以不同的方向旋转,换句话说,2 和 5 互为镜像);6 和 9 同理,除了这些以外其他的数字旋转以后都不再是有效的数字。

现在我们有一个正整数 N, 计算从 1 到 N 中有多少个数 X 是好数?

示例:

输入: 10

输出: 4

解释:

在[1, 10]中有四个好数: 2, 5, 6, 9。

注意 1 和 10 不是好数, 因为他们在旋转之后不变。

class Solution(object):
    def rotatedDigits(self, N):
        """
        :type N: int
        :rtype: int
        """
        count = 0
        f = False
        for i in range(1,N+1):
            for c in str(i):
                if c in '347':
                    f = False
                    break
                if c in '2569':
                    f = True
            if f:
                count += 1
                f = False
        return count

804. 唯一摩尔斯密码词

国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a" 对应 ".-", "b" 对应 "-...", "c" 对应 "-.-.", 等等。

为了方便,所有26个英文字母对应摩尔斯密码表如下:

[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]

给定一个单词列表,每个单词可以写成每个字母对应摩尔斯密码的组合。例如,"cab" 可以写成 "-.-..--...",(即 "-.-." + ".-" + "-..." 字符串的结合)。我们将这样一个连接过程称作单词翻译。

返回我们可以获得所有词不同单词翻译的数量。

例如:

输入: words = ["gin", "zen", "gig", "msg"]

输出: 2

解释:

各单词翻译如下:

"gin" -> "--...-."

"zen" -> "--...-."

"gig" -> "--...--."

"msg" -> "--...--."

共有 2 种不同翻译, "--...-." 和 "--...--.".

class Solution(object):
    def uniqueMorseRepresentations(self, words):
        """
        :type words: List[str]
        :rtype: int
        """
        table = {'a':".-",'b':"-...",'c':"-.-.",'d':"-..",'e':".",
                'f':"..-.",'g':"--.",'h':"....",'i':"..",'j':".---",
                'k':"-.-",'l':".-..",'m':"--",'n':"-.",'o':"---",
                'p':".--.",'q':"--.-",'r':".-.",'s':"...",'t':"-",
                'u':"..-",'v':"...-",'w':".--",'x':"-..-",'y':"-.--",
                'z':"--.."}
        res = set()
        for w in words:
            s = ''
            for c in w:
                s += table[c]
            res.add(s)
        return len(res)

819. 最常见的单词

给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。

题目保证至少有一个词不在禁用列表中,而且答案唯一。

禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。答案都是小写字母。

示例:

输入:

paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."

banned = ["hit"]

输出: "ball"

解释:

"hit" 出现了3次,但它是一个禁用的单词。

"ball" 出现了2次 (同时没有其他单词出现2次),所以它是段落里出现次数最多的,且不在禁用列表中的单词。

注意,所有这些单词在段落里不区分大小写,标点符号需要忽略(即使是紧挨着单词也忽略, 比如 "ball,"),

"hit"不是最终的答案,虽然它出现次数更多,但它在禁用单词列表中。

class Solution(object):
    def mostCommonWord(self, paragraph, banned):
        """
        :type paragraph: str
        :type banned: List[str]
        :rtype: str
        """
        d = {}
        for c in string.punctuation:
			paragraph = paragraph.replace(c," ")
        for w in paragraph.split():
            w = w.lower()
            d[w] = d.get(w,0) + 1
        l = sorted(d.items(),key=lambda x:x[1],reverse=True)
        for k,v in l:
            if k not in banned:
                return k

824. 山羊拉丁文

给定一个由空格分割单词的句子 S。每个单词只包含大写或小写字母。

我们要将句子转换为 “Goat Latin”(一种类似于 猪拉丁文 - Pig Latin 的虚构语言)。

山羊拉丁文的规则如下:

如果单词以元音开头(a, e, i, o, u),在单词后添加"ma"。

例如,单词"apple"变为"applema"。

如果单词以辅音字母开头(即非元音字母),移除第一个字符并将它放到末尾,之后再添加"ma"。

例如,单词"goat"变为"oatgma"。

根据单词在句子中的索引,在单词最后添加与索引相同数量的字母'a',索引从1开始。

例如,在第一个单词后添加"a",在第二个单词后添加"aa",以此类推。

返回将 S 转换为山羊拉丁文后的句子。

示例 1:

输入: "I speak Goat Latin"

输出: "Imaa peaksmaaa oatGmaaaa atinLmaaaaa"

示例 2:

输入: "The quick brown fox jumped over the lazy dog"

输出: "heTmaa uickqmaaa rownbmaaaa oxfmaaaaa umpedjmaaaaaa overmaaaaaaa hetmaaaaaaaa azylmaaaaaaaaa ogdmaaaaaaaaaa"

class Solution(object):
    def toGoatLatin(self, S):
        """
        :type S: str
        :rtype: str
        """
        vowels = 'aeiou'
        res = []
        for i,w in enumerate(S.split()):
            c = w[0]
            if c.lower() in vowels:
                w += 'ma'
            else:
                w = w[1:] + c + 'ma'
            w = w + 'a' * (i+1)
            res.append(w)
        return ' '.join(res)

859. 亲密字符串

给定两个由小写字母构成的字符串 A 和 B ,只要我们可以通过交换 A 中的两个字母得到与 B 相等的结果,就返回 true ;否则返回 false 。

示例 1:

输入: A = "ab", B = "ba"

输出: true

示例 2:

输入: A = "ab", B = "ab"

输出: false

示例 3:

输入: A = "aa", B = "aa"

输出: true

示例 4:

输入: A = "aaaaaaabc", B = "aaaaaaacb"

输出: true

示例 5:

输入: A = "", B = "aa"

输出: false

class Solution(object):
    def buddyStrings(self, A, B):
        """
        :type A: str
        :type B: str
        :rtype: bool
        """
        if len(A)<2 or len(A)!=len(B):
            return False
        if A == B and len(A)>len(set(A)):
            return True
        count = 0
        for i in range(len(A)):
            if A[i] != B[i]:
                if count == 0:
                    swap = [A[i],B[i]]
                    count += 1
                elif count == 1 and A[i] == swap[1] and B[i] == swap[0]:
                    count += 1
                else:
                    return False
        if count == 2:
            return True
        else:
            return False

893. 特殊等价字符串组

你将得到一个字符串数组 A。

每次移动都可以交换 S 的任意两个偶数下标的字符或任意两个奇数下标的字符。

如果经过任意次数的移动,S == T,那么两个字符串 S 和 T 是 特殊等价 的。

例如,S = "zzxy" 和 T = "xyzz" 是一对特殊等价字符串,因为可以先交换 S[0] 和 S[2],然后交换 S[1] 和 S[3],使得 "zzxy" -> "xzzy" -> "xyzz" 。

现在规定,A 的 一组特殊等价字符串 就是 A 的一个同时满足下述条件的非空子集:

该组中的每一对字符串都是 特殊等价 的

该组字符串已经涵盖了该类别中的所有特殊等价字符串,容量达到理论上的最大值(也就是说,如果一个字符串不在该组中,那么这个字符串就 不会 与该组内任何字符串特殊等价)

返回 A 中特殊等价字符串组的数量。

示例 1:

输入:["abcd","cdab","cbad","xyzz","zzxy","zzyx"]

输出:3

解释:

其中一组为 ["abcd", "cdab", "cbad"],因为它们是成对的特殊等价字符串,且没有其他字符串与这些字符串特殊等价。

另外两组分别是 ["xyzz", "zzxy"] 和 ["zzyx"]。特别需要注意的是,"zzxy" 不与 "zzyx" 特殊等价。

示例 2:

输入:["abc","acb","bac","bca","cab","cba"]

输出:3

解释:3 组 ["abc","cba"],["acb","bca"],["bac","cab"]

class Solution(object):
    def numSpecialEquivGroups(self, A):
        """
        :type A: List[str]
        :rtype: int
        """
        return len({(''.join(sorted(str[::2]) +sorted(str[1::2]))) for str in A})

917. 仅仅反转字母

给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。

示例 1:

输入:"ab-cd"

输出:"dc-ba"

示例 2:

输入:"a-bC-dEf-ghIj"

输出:"j-Ih-gfE-dCba"

示例 3:

输入:"Test1ng-Leet=code-Q!"

输出:"Qedo1ct-eeLg=ntse-T!"

class Solution(object):
    def reverseOnlyLetters(self, S):
        """
        :type S: str
        :rtype: str
        """
        p,q = 0,len(S)-1
        s = list(S)
        while p < q:
            if not s[p].isalpha():
                p += 1
            elif not s[q].isalpha():
                q -= 1
            else:
                s[p],s[q] = s[q],s[p]
                p += 1
                q -= 1
        return ''.join(s)

925. 长按键入

你的朋友正在使用键盘输入他的名字 name。偶尔,在键入字符 c 时,按键可能会被长按,而字符可能被输入 1 次或多次。

你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),那么就返回 True。

示例 1:

输入:name = "alex", typed = "aaleex"

输出:true

解释:'alex' 中的 'a' 和 'e' 被长按。

示例 2:

输入:name = "saeed", typed = "ssaaedd"

输出:false

解释:'e' 一定需要被键入两次,但在 typed 的输出中不是这样。

示例 3:

输入:name = "leelee", typed = "lleeelee"

输出:true

示例 4:

输入:name = "laiden", typed = "laiden"

输出:true

解释:长按名字中的字符并不是必要的。

class Solution(object):
    def isLongPressedName(self, name, typed):
        """
        :type name: str
        :type typed: str
        :rtype: bool
        """
        p=q=0
        while p<len(name) and q<len(typed):
            if name[p] == typed[q]:
                p+=1
                q+=1
            else:
                if q>0 and typed[q] == typed[q-1]:
                    q+=1
                else:
                    return False
        if p<len(name):
            return False
        if q<len(typed) and len(set(typed[q:]))>1:
            return False
        else:
            return True

929. 独特的电子邮件地址

每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔。

例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名。

除了小写字母,这些电子邮件还可能包含 '.' 或 '+'。

如果在电子邮件地址的本地名称部分中的某些字符之间添加句点('.'),则发往那里的邮件将会转发到本地名称中没有点的同一地址。例如,"alice.z@leetcode.com” 和 “alicez@leetcode.com” 会转发到同一电子邮件地址。 (请注意,此规则不适用于域名。)

如果在本地名称中添加加号('+'),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,例如 m.y+name@email.com 将转发到 my@email.com。 (同样,此规则不适用于域名。)

可以同时使用这两个规则。

给定电子邮件列表 emails,我们会向列表中的每个地址发送一封电子邮件。实际收到邮件的不同地址有多少?

示例:

输入:["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]

输出:2

解释:实际收到邮件的是 "testemail@leetcode.com" 和 "testemail@lee.tcode.com"。

class Solution(object):
    def numUniqueEmails(self, emails):
        """
        :type emails: List[str]
        :rtype: int
        """
        email_set = set()
        for i in range(len(emails)):
            email_pre,email_suf = emails[i].split('@')
            if '+' in email_pre:
                email_pre = email_pre[:email_pre.index('+')]
            email_pre = email_pre.replace('.','')
            email_set.add(email_pre+'@'+email_suf)
            
        return len(email_set)

937. 重新排列日志文件

你有一个日志数组 logs。每条日志都是以空格分隔的字串。

对于每条日志,其第一个字为字母与数字混合的 标识符 ,除标识符之外的所有字为这一条日志的 内容 。

除标识符之外,所有字均由小写字母组成的,称为 字母日志

除标识符之外,所有字均由数字组成的,称为 数字日志

题目所用数据保证每个日志在其标识符后面至少有一个字。

请按下述规则将日志重新排序:

所有 字母日志 都排在 数字日志 之前。

字母日志 在内容不同时,忽略标识符后,按内容字母顺序排序;在内容相同时,按标识符排序;

数字日志 应该按原来的顺序排列。

返回日志的最终顺序。

示例 :

输入:["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo"]

输出:["g1 act car","a8 act zoo","ab1 off key dog","a1 9 2 3 1","zo4 4 7"]

class Solution(object):
    def reorderLogFiles(self, logs):
        """
        :type logs: List[str]
        :rtype: List[str]
        """
        return sorted(logs, key=self.getKey)

    def getKey(self, ele):
        sign, content = ele.split(' ', 1)
        return (0, content, sign) if content[0].isalpha() else (1,)

1071. 字符串的最大公因子

对于字符串 S 和 T,只有在 S = T + ... + T(T 与自身连接 1 次或多次)时,我们才认定 “T 能除尽 S”。

返回最长字符串 X,要求满足 X 能除尽 str1 且 X 能除尽 str2。

示例 1:

输入:str1 = "ABCABC", str2 = "ABC"

输出:"ABC"

示例 2:

输入:str1 = "ABABAB", str2 = "ABAB"

输出:"AB"

示例 3:

输入:str1 = "LEET", str2 = "CODE"

输出:""

class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        candidate_len = math.gcd(len(str1), len(str2))
        candidate = str1[: candidate_len]
        if str1 + str2 == str2 + str1:
            return candidate
        return ''

1108. IP 地址无效化

给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本。

所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 "."。

示例 1:

输入:address = "1.1.1.1"

输出:"1[.]1[.]1[.]1"

示例 2:

输入:address = "255.100.50.0"

输出:"255[.]100[.]50[.]0"

class Solution:
    def defangIPaddr(self, address: str) -> str:
        return address.replace('.','[.]')

1170. 比较字符串最小字母出现频次

我们来定义一个函数 f(s),其中传入参数 s 是一个非空字符串;该函数的功能是统计 s  中(按字典序比较)最小字母的出现频次。

例如,若 s = "dcce",那么 f(s) = 2,因为最小的字母是 "c",它出现了 2 次。

现在,给你两个字符串数组待查表 queries 和词汇表 words,请你返回一个整数数组 answer 作为答案,其中每个 answer[i] 是满足 f(queries[i]) < f(W) 的词的数目,W 是词汇表 words 中的词。

示例 1:

输入:queries = ["cbd"], words = ["zaaaz"]

输出:[1]

解释:查询 f("cbd") = 1,而 f("zaaaz") = 3 所以 f("cbd") < f("zaaaz")。

示例 2:

输入:queries = ["bbb","cc"], words = ["a","aa","aaa","aaaa"]

输出:[1,2]

解释:第一个查询 f("bbb") < f("aaaa"),第二个查询 f("aaa") 和 f("aaaa") 都 > f("cc")。

class Solution:
    def numSmallerByFrequency(self, queries: List[str], words: List[str]) -> List[int]:
        wf = [self.f(w) for w in words]
        res = []
        for w in queries:
            tmp = self.f(w)
            wf.append(tmp)
            wf = sorted(wf,reverse=True)
            r = wf.index(tmp)
            res.append(r)
            wf.remove(tmp)
        return res

    def f(self,s):
        return s.count(min(s))

1189. “气球” 的最大数量

给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 "balloon"(气球)。

字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 "balloon"。

示例 1:

输入:text = "nlaebolko"

输出:1

示例 2:

输入:text = "loonbalxballpoon"

输出:2

示例 3:

输入:text = "leetcode"

输出:0

class Solution:
    def maxNumberOfBalloons(self, text: str) -> int:
        d = {'a':1, 'b':1, 'l':2, 'n':1, 'o':2}
        l = [text.count(c)//d[c] for c in 'ablno']
        return min(l)

1221. 分割平衡字符串

在一个「平衡字符串」中,'L' 和 'R' 字符的数量是相同的。

给出一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。

返回可以通过分割得到的平衡字符串的最大数量。

示例 1:

输入:s = "RLRRLLRLRL"

输出:4

解释:s 可以分割为 "RL", "RRLL", "RL", "RL", 每个子字符串中都包含相同数量的 'L' 和 'R'。

示例 2:

输入:s = "RLLLLRRRLR"

输出:3

解释:s 可以分割为 "RL", "LLLRRR", "LR", 每个子字符串中都包含相同数量的 'L' 和 'R'。

示例 3:

输入:s = "LLLLRRRR"

输出:1

解释:s 只能保持原样 "LLLLRRRR".

class Solution:
    def balancedStringSplit(self, s: str) -> int:
        res = 0
        balance = 0
        for c in s:
            if balance == 0:
                tmp = c
                res += 1
            if c == tmp:
                balance += 1
            else:
                balance -= 1
        return res

1309. 解码字母到整数映射

给你一个字符串 s,它由数字('0' - '9')和 '#' 组成。我们希望按下述规则将 s 映射为一些小写英文字符:

字符('a' - 'i')分别用('1' - '9')表示。

字符('j' - 'z')分别用('10#' - '26#')表示。

返回映射之后形成的新字符串。

题目数据保证映射始终唯一。

示例 1:

输入:s = "10#11#12"

输出:"jkab"

解释:"j" -> "10#" , "k" -> "11#" , "a" -> "1" , "b" -> "2".

示例 2:

输入:s = "1326#"

输出:"acz"

示例 3:

输入:s = "25#"

输出:"y"

示例 4:

输入:s = "12345678910#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#"

输出:"abcdefghijklmnopqrstuvwxyz"

class Solution:
    def freqAlphabets(self, s: str) -> str:
        d = {}
        for i in range(1,27):
            if i < 10:
                d[str(i)] = chr(i+96)
            else:
                d[str(i)+'#'] = chr(i+96)
        res = ''
        p = 0
        while p<len(s):
            if p+2<len(s) and s[p+2] == '#':
                res += d[s[p:p+3]]
                p += 3
            else:
                res += d[s[p]]
                p += 1
        return res

1332. 删除回文子序列

给你一个字符串 s,它仅由字母 'a' 和 'b' 组成。每一次删除操作都可以从 s 中删除一个回文 子序列。

返回删除给定字符串中所有字符(字符串为空)的最小删除次数。

「子序列」定义:如果一个字符串可以通过删除原字符串某些字符而不改变原字符顺序得到,那么这个字符串就是原字符串的一个子序列。

「回文」定义:如果一个字符串向后和向前读是一致的,那么这个字符串就是一个回文。

示例 1:

输入:s = "ababa"

输出:1

解释:字符串本身就是回文序列,只需要删除一次。

示例 2:

输入:s = "abb"

输出:2

解释:"abb" -> "bb" -> "".

先删除回文子序列 "a",然后再删除 "bb"。

示例 3:

输入:s = "baabb"

输出:2

解释:"baabb" -> "b" -> "".

先删除回文子序列 "baab",然后再删除 "b"。

示例 4:

输入:s = ""

输出:0

class Solution:
    def removePalindromeSub(self, s: str) -> int:
        if not s:
            return 0
        return 1 if s==s[::-1] else 2

1370. 上升下降字符串

给你一个字符串 s ,请你根据下面的算法重新构造字符串:

从 s 中选出 最小 的字符,将它 接在 结果字符串的后面。

从 s 剩余字符中选出 最小 的字符,且该字符比上一个添加的字符大,将它 接在 结果字符串后面。

重复步骤 2 ,直到你没法从 s 中选择字符。

从 s 中选出 最大 的字符,将它 接在 结果字符串的后面。

从 s 剩余字符中选出 最大 的字符,且该字符比上一个添加的字符小,将它 接在 结果字符串后面。

重复步骤 5 ,直到你没法从 s 中选择字符。

重复步骤 1 到 6 ,直到 s 中所有字符都已经被选过。

在任何一步中,如果最小或者最大字符不止一个 ,你可以选择其中任意一个,并将其添加到结果字符串。

请你返回将 s 中字符重新排序后的 结果字符串 。

示例 1:

输入:s = "aaaabbbbcccc"

输出:"abccbaabccba"

解释:第一轮的步骤 1,2,3 后,结果字符串为 result = "abc"

第一轮的步骤 4,5,6 后,结果字符串为 result = "abccba"

第一轮结束,现在 s = "aabbcc" ,我们再次回到步骤 1

第二轮的步骤 1,2,3 后,结果字符串为 result = "abccbaabc"

第二轮的步骤 4,5,6 后,结果字符串为 result = "abccbaabccba"

示例 2:

输入:s = "rat"

输出:"art"

解释:单词 "rat" 在上述算法重排序以后变成 "art"

示例 3:

输入:s = "leetcode"

输出:"cdelotee"

示例 4:

输入:s = "ggggggg"

输出:"ggggggg"

示例 5:

输入:s = "spo"

输出:"ops"

class Solution:
    def sortString(self, s: str) -> str:
        str_counter = collections.Counter(s)
        result = []
        flag = False
        while str_counter:
            keys = list(str_counter.keys())
            keys.sort(reverse=flag)
            flag = not flag
            result.append(''.join(keys))
            str_counter -= collections.Counter(keys)
        return ''.join(result)

1374. 生成每种字符都是奇数个的字符串

给你一个整数 n,请你返回一个含 n 个字符的字符串,其中每种字符在该字符串中都恰好出现 奇数次 。

返回的字符串必须只含小写英文字母。如果存在多个满足题目要求的字符串,则返回其中任意一个即可。

示例 1:

输入:n = 4

输出:"pppz"

解释:"pppz" 是一个满足题目要求的字符串,因为 'p' 出现 3 次,且 'z' 出现 1 次。当然,还有很多其他字符串也满足题目要求,比如:"ohhh" 和 "love"。

示例 2:

输入:n = 2

输出:"xy"

解释:"xy" 是一个满足题目要求的字符串,因为 'x' 和 'y' 各出现 1 次。当然,还有很多其他字符串也满足题目要求,比如:"ag" 和 "ur"。

示例 3:

输入:n = 7

输出:"holasss"

class Solution:
    def generateTheString(self, n: int) -> str:
        if n%2==0:
            return 'a'*(n-1)+'b'
        else:
            return 'a'*n

1408. 数组中的字符串匹配

给你一个字符串数组 words ,数组中的每个字符串都可以看作是一个单词。请你按 任意 顺序返回 words 中是其他单词的子字符串的所有单词。

如果你可以删除 words[j] 最左侧和/或最右侧的若干字符得到 word[i] ,那么字符串 words[i] 就是 words[j] 的一个子字符串。

示例 1:

输入:words = ["mass","as","hero","superhero"]

输出:["as","hero"]

解释:"as" 是 "mass" 的子字符串,"hero" 是 "superhero" 的子字符串。

["hero","as"] 也是有效的答案。

示例 2:

输入:words = ["leetcode","et","code"]

输出:["et","code"]

解释:"et" 和 "code" 都是 "leetcode" 的子字符串。

示例 3:

输入:words = ["blue","green","bu"]

输出:[]

class Solution:
    def stringMatching(self, words: List[str]) -> List[str]:
        res = set()
        for i in range(len(words)):
            for j in range(len(words)):
                if i!=j and words[i] in words[j]:
                    res.add(words[i])
        return list(res)

1417. 重新格式化字符串

给你一个混合了数字和字母的字符串 s,其中的字母均为小写英文字母。

请你将该字符串重新格式化,使得任意两个相邻字符的类型都不同。也就是说,字母后面应该跟着数字,而数字后面应该跟着字母。

请你返回 重新格式化后 的字符串;如果无法按要求重新格式化,则返回一个 空字符串 。

示例 1:

输入:s = "a0b1c2"

输出:"0a1b2c"

解释:"0a1b2c" 中任意两个相邻字符的类型都不同。 "a0b1c2", "0a1b2c", "0c2a1b" 也是满足题目要求的答案。

示例 2:

输入:s = "leetcode"

输出:""

解释:"leetcode" 中只有字母,所以无法满足重新格式化的条件。

示例 3:

输入:s = "1229857369"

输出:""

解释:"1229857369" 中只有数字,所以无法满足重新格式化的条件。

示例 4:

输入:s = "covid2019"

输出:"c2o0v1i9d"

示例 5:

输入:s = "ab123"

输出:"1a2b3"

class Solution:
    def reformat(self, s: str) -> str:
        if not s:
            return ''
        letters = []
        nums = []
        res = ''
        for c in s:
            if c.isalpha():
                letters.append(c)
            else:
                nums.append(c)
        if abs(len(letters)-len(nums))>1:
            return ''
        res = ''.join([i + j for i,j in zip(letters,nums)])
        if len(letters)<len(nums):
            return nums[-1] + res
        elif len(letters)>len(nums):
            return res + letters[-1]
        else:
            return res

1422. 分割字符串的最大得分

给你一个由若干 0 和 1 组成的字符串 s ,请你计算并返回将该字符串分割成两个 非空 子字符串(即 左 子字符串和 右 子字符串)所能获得的最大得分。

「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1 的数量。

示例 1:

输入:s = "011101"

输出:5

解释:

将字符串 s 划分为两个非空子字符串的可行方案有:

左子字符串 = "0" 且 右子字符串 = "11101",得分 = 1 + 4 = 5

左子字符串 = "01" 且 右子字符串 = "1101",得分 = 1 + 3 = 4

左子字符串 = "011" 且 右子字符串 = "101",得分 = 1 + 2 = 3

左子字符串 = "0111" 且 右子字符串 = "01",得分 = 1 + 1 = 2

左子字符串 = "01110" 且 右子字符串 = "1",得分 = 2 + 1 = 3

示例 2:

输入:s = "00111"

输出:5

解释:当 左子字符串 = "00" 且 右子字符串 = "111" 时,我们得到最大得分 = 2 + 3 = 5

示例 3:

输入:s = "1111"

输出:3

class Solution:
    def maxScore(self, s: str) -> int:
        res = 0
        for i in range(1,len(s)):
            l = s[:i]
            r = s[i:]
            score = l.count('0') + r.count('1')
            if score > res:
                res = score
        return res

1436. 旅行终点站

给你一份旅游线路图,该线路图中的旅行线路用数组 paths 表示,其中 paths[i] = [cityAi, cityBi] 表示该线路将会从 cityAi 直接前往 cityBi 。请你找出这次旅行的终点站,即没有任何可以通往其他城市的线路的城市。

题目数据保证线路图会形成一条不存在循环的线路,因此只会有一个旅行终点站。

示例 1:

输入:paths = [["London","New York"],["New York","Lima"],["Lima","Sao Paulo"]]

输出:"Sao Paulo"

解释:从 "London" 出发,最后抵达终点站 "Sao Paulo" 。本次旅行的路线是 "London" -> "New York" -> "Lima" -> "Sao Paulo" 。

示例 2:

输入:paths = [["B","C"],["D","B"],["C","A"]]

输出:"A"

解释:所有可能的线路是:

"D" -> "B" -> "C" -> "A".

"B" -> "C" -> "A".

"C" -> "A".

"A".

显然,旅行终点站是 "A" 。

示例 3:

输入:paths = [["A","Z"]]

输出:"Z"

class Solution:
    def destCity(self, paths: List[List[str]]) -> str:
        s = {c1 for c1,c2 in paths}
        for c1,c2 in paths:
            if c2 not in s:
                return c2

1446. 连续字符

给你一个字符串 s ,字符串的「能量」定义为:只包含一种字符的最长非空子字符串的长度。

请你返回字符串的能量。

示例 1:

输入:s = "leetcode"

输出:2

解释:子字符串 "ee" 长度为 2 ,只包含字符 'e' 。

示例 2:

输入:s = "abbcccddddeeeeedcba"

输出:5

解释:子字符串 "eeeee" 长度为 5 ,只包含字符 'e' 。

示例 3:

输入:s = "triplepillooooow"

输出:5

示例 4:

输入:s = "hooraaaaaaaaaaay"

输出:11

示例 5:

输入:s = "tourist"

输出:1

class Solution:
    def maxPower(self, s: str) -> int:
        if not s:
            return 0
        old = s[0]
        count = 1
        ans = 1
        for c in s[1:]:
            if c!=old:
                old = c
                ans = max(ans,count)
                count = 1
            else:
                count += 1
        ans = max(ans,count)
        return ans

1455. 检查单词是否为句中其他单词的前缀

给你一个字符串 sentence 作为句子并指定检索词为 searchWord ,其中句子由若干用 单个空格 分隔的单词组成。

请你检查检索词 searchWord 是否为句子 sentence 中任意单词的前缀。

如果 searchWord 是某一个单词的前缀,则返回句子 sentence 中该单词所对应的下标(下标从 1 开始)。

如果 searchWord 是多个单词的前缀,则返回匹配的第一个单词的下标(最小下标)。

如果 searchWord 不是任何单词的前缀,则返回 -1 。

字符串 S 的 「前缀」是 S 的任何前导连续子字符串。

示例 1:

输入:sentence = "i love eating burger", searchWord = "burg"

输出:4

解释:"burg" 是 "burger" 的前缀,而 "burger" 是句子中第 4 个单词。

示例 2:

输入:sentence = "this problem is an easy problem", searchWord = "pro"

输出:2

解释:"pro" 是 "problem" 的前缀,而 "problem" 是句子中第 2 个也是第 6 个单词,但是应该返回最小下标 2 。

示例 3:

输入:sentence = "i am tired", searchWord = "you"

输出:-1

解释:"you" 不是句子中任何单词的前缀。

示例 4:

输入:sentence = "i use triple pillow", searchWord = "pill"

输出:4

示例 5:

输入:sentence = "hello from the other side", searchWord = "they"

输出:-1

class Solution:
    def isPrefixOfWord(self, sentence: str, searchWord: str) -> int:
        for i,w in enumerate(sentence.split()):
            if w.startswith(searchWord):
                return i+1
        else:
            return -1

1496. 判断路径是否相交

给你一个字符串 path,其中 path[i] 的值可以是 'N'、'S'、'E' 或者 'W',分别表示向北、向南、向东、向西移动一个单位。

机器人从二维平面上的原点 (0, 0) 处开始出发,按 path 所指示的路径行走。

如果路径在任何位置上出现相交的情况,也就是走到之前已经走过的位置,请返回 True ;否则,返回 False 。

示例 1:

输入:path = "NES"

输出:false

解释:该路径没有在任何位置相交。

示例 2:

输入:path = "NESWW"

输出:true

解释:该路径经过原点两次。

class Solution:
    def isPathCrossing(self, path: str) -> bool:
        s = set()
        coor = (0, 0)
        s.add(coor)
        for p in path:
            if p == 'N':
                x, y = 0, 1
            elif p == 'S':
                x, y = 0, -1
            elif p == 'E':
                x, y = 1, 0
            else:
                x, y = -1, 0
            coor = (coor[0] + x, coor[1] + y)
            if coor in s:
                return True
            s.add(coor)
        else:
            return False

1507. 转变日期格式

给你一个字符串 date ,它的格式为 Day Month Year ,其中:

Day 是集合 {"1st", "2nd", "3rd", "4th", ..., "30th", "31st"} 中的一个元素。

Month 是集合 {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"} 中的一个元素。

Year 的范围在 ​[1900, 2100] 之间。

请你将字符串转变为 YYYY-MM-DD 的格式,其中:

YYYY 表示 4 位的年份。

MM 表示 2 位的月份。

DD 表示 2 位的天数。
 
示例 1:

输入:date = "20th Oct 2052"

输出:"2052-10-20"

示例 2:

输入:date = "6th Jun 1933"

输出:"1933-06-06"

示例 3:

输入:date = "26th May 1960"

输出:"1960-05-26"

class Solution:
    def reformatDate(self, date: str) -> str:
        month_w2n = {"Jan":'01', "Feb":'02', "Mar":'03', "Apr":'04', "May":'05', "Jun":'06', "Jul":'07', "Aug":'08', "Sep":'09', "Oct":'10', "Nov":'11', "Dec":'12'}
        d, m, y = date.split()
        day = d[:-2]
        month = month_w2n[m]
        return '{}-{}-{:0>2d}'.format(y,month,int(day))

1544. 整理字符串

给你一个由大小写英文字母组成的字符串 s 。

一个整理好的字符串中,两个相邻字符 s[i] 和 s[i + 1] 不会同时满足下述条件:

0 <= i <= s.length - 2

s[i] 是小写字符,但 s[i + 1] 是相同的大写字符;反之亦然 。

请你将字符串整理好,每次你都可以从字符串中选出满足上述条件的 两个相邻 字符并删除,直到字符串整理好为止。

请返回整理好的 字符串 。题目保证在给出的约束条件下,测试样例对应的答案是唯一的。

注意:空字符串也属于整理好的字符串,尽管其中没有任何字符。

示例 1:

输入:s = "leEeetcode"

输出:"leetcode"

解释:无论你第一次选的是 i = 1 还是 i = 2,都会使 "leEeetcode" 缩减为 "leetcode" 。

示例 2:

输入:s = "abBAcC"

输出:""

解释:存在多种不同情况,但所有的情况都会导致相同的结果。例如:

"abBAcC" --> "aAcC" --> "cC" --> ""

"abBAcC" --> "abBA" --> "aA" --> ""

示例 3:

输入:s = "s"

输出:"s"

class Solution:
    def makeGood(self, s: str) -> str:
        stack = []
        for i in s:
            if stack and ((ord(stack[-1])-32) == ord(i) or (ord(stack[-1])+32) == ord(i)):
                stack.pop()
            else:
                stack.append(i)
        return ''.join(stack)

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotated-digits
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

posted @ 2020-08-19 22:59  MrDoghead  阅读(827)  评论(0编辑  收藏  举报