14. Longest Common Prefix
返回最长公共前缀字符串。原题
1 | Input: ["flower","flow","flight"] |
1 | def longest_common_prefix(strs): |
20. Valid Parentheses
判断括号是否成对出现,并且嵌套正确。原题
1 | Input: "()[]{}" |
1 | def is_valid(s): |
921. Minimum Add to Make Parentheses Valid
给定一个只包含小括号的字符串。返回需要多少个”(“或”)”使其成为完整的括号表达式。原题
1 | Input: "())" |
方法一:平衡问题。
1 | def minAddToMakeValid(self, S: str) -> int: |
28. Implement strStr()
实现index。原题
1 | Input: haystack = "hello", needle = "ll" |
1 | def str_index(haystack, needle): |
38. Count and Say
原题
1 | 1. 1 |
1 | def countAndSay(self, n: int) -> str: |
443. String Compression
字符串压缩,实际是要将重复的字符串以个数来表示。要求O(1)空间复杂度,就地修改原数组。原题
思路:看上去和38题差不多,但是有些不同,不同的地方在于如果个数为1,则不显示。个数为两位数,要显示两个元素。
1 | Input = ["a","a","b","b","c","c","c"] |
1 | def compress(self, chars: List[str]) -> int: |
125. Valid Palindrome
验证回文字符串,只判断字母数字,忽略大小写。原题
1 | Input: "A man, a plan, a canal: Panama" |
方法一:切片
1 | def is_palindrome(s): |
方法二:双指针
1 | def is_palindrome(s): |
680. Valid Palindrome II
验证是否是回文数,只包含小写字母,但是允许最多去掉一个字母之后是回文数。原题
1 | Input: "abca" |
方法一:一开始想的方法。切片由于可能i=0
,所以必须反序切片再倒置。
1 | def validPalindrome(self, s): |
1 | def validPalindrome(self, s): |
方法三:贪心解法,留坑。
151. Reverse Words in a String
倒置一句话中的单词。原题
1 | Input: "the sky is blue", |
1 | def reverse_words(s): |
344. Reverse String
倒置字符串。原题
1 | Input: "A man, a plan, a canal: Panama" |
1 | def reverse_str(s): |
242. Valid Anagram
验证回文构词法,即两个字符串由同样个数的字符组成。原题
1 | Input: s = "anagram", t = "nagaram" |
方法一: sort
1 | def is_anagram(s, t): |
方法二:Counter
1 | def is_anagram(s, t): |
438. Find All Anagrams in a String
找出字符串中所有的回文构词。原题
方法一:有个小地方注意就是,如果计数为0要删除,否则等式将不成立。
1 | def findAnagrams(self, s, p): |
3. Longest Substring Without Repeating Characters
最长不含重复字符的子字符串。原题
方法一:暴力法,果然超时了。
1 | def lengthOfLongestSubstring(self, s): |
dic[s[end]]+1
,比如当s='abba'
,end走到最后的时候,上一次start因为b做了更新变为了2。
1 | def lengthOfLongestSubstring(self, s): |
也可以把max判断放到条件里。
1 | def lengthOfLongestSubstring(self, s): |
387. First Unique Character in a String
返回第一个不重复的字符。原题
1 | s = "leetcode" |
Time-O(N), Space-O(N)。暂时没发现更快的算法了。
1 | def firstUniqChar(self, s): |
58. Length of Last Word
输入一个字符串,通过空格分割,然后返回最后一个单词的长度,空串不算。原题
1 | s = "Hello World" |
方法一:直观的方法。
1 | def lengthOfLastWord(self, s): |
方法二:使用列表生成式,理论上时间复杂度比上述方法稍微高一点,不过实际时间差不多,估计是list comprehension做了优化。
1 | def lengthOfLastWord(self, s): |
205. Isomorphic Strings
判断两个字符串是否具有一样的形式。s和t长度一样。原题
1 | Input: s = "egg", t = "add" |
方法一:使用dict
保存每个字母的位置。这里使用了OrderedDict
保存了values
的顺序,也可以使用sorted
对values
排序。最后说明一下在Python3
中需要使用list
格式化一下,因为values()
返回一个dict_values
对象,而这个对象如果直接使用==
判断,会返回False
,即使有相同的值,这里还不清楚内部的__eq__
方法是如何实现的。而在Python2
中可以直接比较。
1 | def isIsomorphic(self, s, t): |
方法二:使用zip
并行输出。
1 | >>> list(zip('paper', 'title')) |
1 | def isIsomorphic(self, s, t): |
方法三:两个字符串每个位置的字符,第一次出现的index
是否相同。
1 | def isIsomorphic(self, s, t): |
方法四:setdeault妙用。Lee215。
1 | def isIsomorphic(self, s: str, t: str) -> bool: |
290. Word Pattern
匹配字符串和空格分隔的字符串是否具有相同形式,此题和上一题相似,只不过将其中一个换成了数组。另一个区别是长度不一定相等。原题
1 | Input: pattern = "abba", str = "dog cat cat dog" |
1 | def wordPattern(self, pattern, str): |
1 | def wordPattern(self, pattern, str): |
1 | def wordPattern(self, pattern: str, str: str) -> bool: |
890. Find and Replace Pattern
找到和pattern一样模式的字符串。和290,205一样。原题
1 | Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb" |
方法一:我使用zip和set来判断的。
1 | def findAndReplacePattern(self, words: List[str], pattern: str) -> List[str]: |
1 | def findAndReplacePattern(self, words: List[str], p: str) -> List[str]: |
917. Reverse Only Letters
倒置一个字符串的字母。原题
1 | Input: "ab-cd" |
注意:不能使用l <= r
作为条件,因为会打乱正确结果的排序。输出"dcb-a"
。
1 | def reverseOnlyLetters(self, S): |
345.Reverse Vowels of a String
倒置一个字符串中的元音字母。原题
1 | Example 2: |
方法一:和917题一样,换汤不换药。只需定义一个vowels={'a', 'e', 'i', 'o', 'u'}
然后条件改成while l<r and res[l].lower() not in vowels:
,提交了一下beat
有68%左右,应该还有更效率的方法。
方法二:改了一下,不再使用lower方法了,把大写字母加上,beat变为99.88%。
1 | def reverseVowels(self, s): |
方法三:正则
1 | def reverseVowels(self, s): |
383. Ransom Note
判断是否magazine
可以构成ransomNote
。原题
1 | canConstruct("a", "b") -> false |
方法一:使用count。
1 | def canConstruct(self, ransomNote, magazine): |
1 | def canConstruct(self, ransomNote, magazine): |
1 | def canConstruct(self, ransomNote, magazine): |
925. Long Pressed Name
说有这么一个破键盘,老是连键,有时候打一个字母c,出来好几个。给定一个目标字符串和打出来的字符串,判断是否是这个破键盘输出的。原题
1 | Input: name = "alex", typed = "aaleex" |
思路:一开始还想用Counter,后来发现不对,因为它将所有的一样的字符聚合到了一起。所以此题可以使用groupby
1 | def isLongPressedName(self, name, typed): |
1 | def isLongPressedName(self, name: str, typed: str) -> bool: |
929. Unique Email Addresses
统计不同的email地址。原题
1 | def numUniqueEmails(self, emails): |
409. Longest Palindrome
给你一堆字符串,返回用它组成的最长的回文串的长度,可以不使用所有的字符。原题
方法一:每对一样的数字可以放在两边来组成回文。
1 | def longestPalindrome(self, s): |
1 | def longestPalindrome(self, s): |
434. Number of Segments in a String
统计字符串中有多少个以空格分割的字符串。原题
方法一:Time-O(n), Space-O(1)1 | def countSegments(self, s): |
方法二:
1 | def countSegments(self, s): |
500. Keyboard Row
输入一个字符串数组,返回字符在键盘同一行的字符串。原题
1 | Input: ["Hello", "Alaska", "Dad", "Peace"] |
1 | class Solution: |
520. Detect Capital
判断一个字符串的大写是否使用正确。要么全大写,要么全小写,或者首字母大写。原题
1 | Input: "USA" |
方法一:太简单了,一下子就写出来了,看评论居然好多人不知道istitle
。
1 | def detectCapitalUse(self, word): |
541. Reverse String II
按照2k的长度划分一个字符串,把其中每段前k个字符倒置。原题
1 | Input: s = "abcdefg", k = 2 |
方法一:比较简单的一题,使用Python的切片。
1 | def reverseStr(self, s, k): |
551. Student Attendance Record I
判断一个学生是否有奖励,缺席次数小于等于一天,没有三次连续的迟到。原题
1 | Input: "PPALLP" |
1 | def checkRecord(self, s): |
557. Reverse Words in a String III
倒置一句话中的每个单词。所有单词均已一个空格分隔。原题
1 | Input: "Let's take LeetCode contest" |
1 | def reverseWords(self, s): |
657. Robot Return to Origin
机器人是否能回到原点。’UDLR’分别表示上下左右,每次移动的距离一样。原题
1 | Input: "UD" |
方法一:就是看上下和左右的次数是否一样。此题过于简单。
1 | def judgeCircle(self, moves): |
1 | def judgeCircle(self, moves): |
696. Count Binary Substrings
二进制字符串计数,有多少个连续的子字符串,由相同的0和1组成,如’10’,’1100’。原题
1 | Input: "00110011" |
1 | def countBinarySubstrings(self, s): |
方法二:变量,常数空间复杂度。
1 | def countBinarySubstrings(self, s): |
709. To Lower Case
实现字符串的lower
方法。原题
1 | Input: "Hello" |
1 | def toLowerCase(self, str): |
771. Jewels and Stones
判断S里有多少个在J里,J为不重复元素。原题
1 | Input: J = "aA", S = "aAAbbbb" |
方法一:使用set.
1 | def numJewelsInStones(self, J: 'str', S: 'str') -> 'int': |
方法二:count. count的值只会是0和1,因为J没有重复元素。由于这个特性,所以反过来也是一样。
1 | def numJewelsInStones(self, J: 'str', S: 'str') -> 'int': |
784. Letter Case Permutation
字母组合,给定一个字符串,其中的字母可大写可小写,返回所有可能的字符串。原题
1 | Examples: |
方法一:提取字母,然后format
。
1 | def letterCasePermutation(self, S: 'str') -> 'List[str]': |
1 | def letterCasePermutation(self, S: 'str') -> 'List[str]': |
788. Rotated Digits
可旋转的数字,说把一个数的所有数字旋转180度,是一个正确的数字。并且和原来不同。给定一个N,返回1~N所有这样的数的个数。原题
1 | Example: |
1 | def rotatedDigits(self, N: 'int') -> 'int': |
796. Rotate String
判断一个字符串A是否可以旋转成B。原题
1 | Example 1: |
方法一:Brute Force. Time: O(N²), Space: O(N²).
1 | def rotateString(self, A: 'str', B: 'str') -> 'bool': |
1 | def rotateString(self, A: 'str', B: 'str') -> 'bool': |
方法三:KMP算法。留坑。
方法四:Rolling Hash算法。留坑。
804. Unique Morse Code Words
不重复的莫斯密码,给定一句话,求不重复的单词的莫斯密码个数。原题
1 | Example: |
1 | def uniqueMorseRepresentations(self, words: 'List[str]') -> 'int': |
806. Number of Lines To Write String
单词换行,已知每个字母的宽度,每100一换行,写不下一个字母时,换行,最一个字符串需要多少行和末尾行的宽度。原题
1 | Example : |
1 | def numberOfLines(self, widths: 'List[int]', S: 'str') -> 'List[int]': |
819. Most Common Word
最常见的单词,从输入的段落中找到出现频率最高并且不在banned列表中的单词。原题
1 | Input: |
方法一:一开始写的方法。
1 | def mostCommonWord(self, paragraph: 'str', banned: 'List[str]') -> 'str': |
1 | def mostCommonWord(self, paragraph: 'str', banned: 'List[str]') -> 'str': |
821. Shortest Distance to a Character
根据已知字符串S, 求目标字符C和左右index最近的距离。原题
1 | Input: S = "loveleetcode", C = 'e' |
方法一:前后遍历两次,分别求距离。本想通过一次,结果实现过于繁琐。
1 | def shortestToChar(self, S: 'str', C: 'str') -> 'List[int]': |
824. Goat Latin
山羊拉丁口音,把一句话中的每个单词根据规则,生成一句新的话。原题
1 | Input: "The quick brown fox jumped over the lazy dog" |
1 | def toGoatLatin(self, S: 'str') -> 'str': |
844. Backspace String Compare
退格键字符串比较。比较两个带有退格#
的字符串,判断最后输出是否一致。原题
1 | Input: S = "ab#c", T = "ad#c" |
方法一:首先想到stack
.
1 | def backspaceCompare(self, S: 'str', T: 'str') -> 'bool': |
1 | def backspaceCompare(self, S: 'str', T: 'str') -> 'bool': |
#a#c
的结果会变成#c
。因为第一次循环相当于back('#', 'a')
所以第一个#
会一直保留。
1 | def backspaceCompare(self, S: 'str', T: 'str') -> 'bool': |
查看文档中reduce实现:
1 | def reduce(function, iterable, initializer=None): |
859. Buddy Strings
好友字符串。指A通过一次交换两个字符变成B。判断是否是好友字符串。原题
1 | Input: A = "ab", B = "ba" |
方法一:Brute Force. 效率很低。
1 | def buddyStrings(self, A: 'str', B: 'str') -> 'bool': |
1 | def buddyStrings(self, A: 'str', B: 'str') -> 'bool': |
893. Groups of Special-Equivalent Strings
特殊等价字符串组。这题Contest就没做出来,描述有问题,讨论区一堆diss的评论。总的来说就是把A的字符串分组,能够改变偶数位的字符,或奇数位的字符能使之相等的为一组,求一共有多少个组。原题
1 | Input: ["a","b","c","a","c","c"] |
方法一:数组保留索引。
1 | def numSpecialEquivGroups(self, A: 'List[str]') -> 'int': |
1 | def numSpecialEquivGroups(self, A: 'List[str]') -> 'int': |
1003. Check If Word Is Valid After Substitutions
判断字符串是否由abc
无限插入得到。原题
1 | Input: "aabcbc" |
1 | def isValid(self, S: str) -> bool: |
17. Letter Combinations of a Phone Number
电话的数字可以组成的字符串组合。原题
1 | Input: "23" |
方法一:recursive.
1 | def letterCombinations(self, digits: str) -> List[str]: |
方法二:使用product
。
1 | def letterCombinations(self, digits: str) -> List[str]: |
product
。
1 | def letterCombinations(self, digits: str) -> List[str]: |
reduce
方法。
1 | def letterCombinations(self, digits: str) -> List[str]: |
方法五:Solution中的回溯法。
1 | def letterCombinations(self, digits: str) -> List[str]: |
1023. Binary String With Substrings Representing 1 To N
二进制子串,从1到N。原题
1 | Input: S = "0110", N = 3 |
方法一:暴力法。
1 | def queryString(self, S: str, N: int) -> bool: |
方法二:对于任意的i<N/2
的数i*2
的二进制表示形式一定包含i
。因为左移一位。
1 | def queryString(self, S: str, N: int) -> bool: |
482. License Key Formatting
根据要求格式化字符串。原题
1 | Input: S = "5F3Z-2e-9-w", K = 4 |
方法一:使用内置方法。
1 | def licenseKeyFormatting(self, S: str, K: int) -> str: |
方法二:完整实现。one-pass.
1 | def licenseKeyFormatting(self, S: str, K: int) -> str: |
1071. Greatest Common Divisor of Strings
最长公共被整除的字符串。原题
1 | Input: str1 = "ABCABC", str2 = "ABC" |
方法一:这里我是从小找一个公共串,并记录重复次数。再从两个重复的次数中取最大公约数。
1 | def gcdOfStrings(self, str1: str, str2: str) -> str: |
1 | def gcdOfStrings(self, str1: str, str2: str) -> str: |
1156. Swap For Longest Repeated Character Substring
最多交换一次两个字符,求连续重复的字符最大个数是多少。原题
1 | Input: text = "aaabaaa" |
方法一:竞赛没在规定时间内完成,思路是对的,使用groupby,第二个例子那里小细节没有处理好。
1 | def maxRepOpt1(self, text: str) -> int: |
1106. Parsing A Boolean Expression
转换&|~操作符,返回结果。原题
1 | Input: expression = "|(&(t,f,t),!(t))" |
方法一:这题很有意思,马上就能想到用eval
来作弊,但是~
没有处理好,看了Lee神答案后恍然大悟。这里需要将非符号转成any数组。
1 | def parseBoolExpr(self, expression: str) -> bool: |
1408. String Matching in an Array
找出字符串是其它子串的字符串。原题
1 | Input: words = ["mass","as","hero","superhero"] |
方法一:排序暴力法。
1 | def stringMatching(self, words: List[str]) -> List[str]: |
791. Custom Sort String
自定义排序字符串,按照S中字母顺序排序T。原题
1 | Example : |
1 | def customSortString(self, S: str, T: str) -> str: |
678. Valid Parenthesis String
匹配括号,*可以表示左右或者空。原题
1 | Input: "(*))" |
方法一:这题一开始想歪了,想用栈和递归的方式实现,结果没想出来。这里用了Lee215的方法。cmin
表示至少需要)
, cmax
表示最多。
1 | def checkValidString(self, s: str) -> bool: |
1419. Minimum Number of Frogs Croaking
有n个青蛙🐸一起叫,叫声混到了一起,求最小青蛙的个数。原题
1 | Input: croakOfFrogs = "crcoakroak" |
方法一:记录每个字母的个数,注意叫的过程中字母数量的顺序。inuse
表示同时叫的青蛙。
1 | def minNumberOfFrogs(self, croakOfFrogs: str) -> int: |
1358. Number of Substrings Containing All Three Characters
包含’abc’子串的个数。原题
1 | Input: s = "abcabc" |
方法一:滑动窗口。记录abc的数量,当无法组成时退出,此时最左的索引为i-1。
1 | def numberOfSubstrings(self, s: str) -> int: |
方法二:数学方法。以右侧点为准,向左累加。
1 | def numberOfSubstrings(self, s: str) -> int: |
1309. Decrypt String from Alphabet to Integer Mapping
数字到字母的一个映射。原题
1 | Input: s = "10#11#12" |
方法一:比赛时的答案过于繁琐。
1 | def freqAlphabets(self, s: str) -> str: |
1545. Find Kth Bit in Nth Binary String
找到第n个字符串的第k位。原题
S1 = "0"
S2 = "0**1**1"
S3 = "011**1**001"
S4 = "0111001**1**0110001"
1 | Input: n = 3, k = 1 |
方法一:比赛时是按照题意的方式写的,效率慢了10倍,这题用逆向思维。by@lee215.
1 | def findKthBit(self, n: int, k: int) -> str: |
777. Swap Adjacent in LR String
转换成目标字符串,可以将”XL”变成”LX”,或者将”RX”变成”XR”。原题
1 | Input: start = "RXXLRXRXL", end = "XRLXXRRLX" |
方法一:一开始想错了,以为互换倒过来也行。这个变换有点像将L向左移,R向右移,而且不能跨越其它的R或者L也就是可以将X想象成空位。所以这里计算时要将LR一起考虑。
1 | def canTransform(self, start: str, end: str) -> bool: |
539. Minimum Time Difference
两个时间的最小分钟差的绝对值。原题
1 | Input: ["23:59","00:00"] |
方法一:Lee的方法,自己想的一样,优化一下写法。
1 | def findMinDifference(self, timePoints: List[str]) -> int: |
459. Repeated Substring Pattern
字符串中是否包含重复的子串模式。原题
1 | Input: "abcabcabcabc" |
方法一:如果s包含一个重复的子串,那么通过旋转s在n-1次之内,一定会又出现s本身。如s='abcabc'
那么旋转三次就会得到它。判断是否出现重复那么只要出现两次就算。于是将s+s得到s2。并将头尾去掉,这样s2包含了所有的旋转可能。如果s在其中,那么就说明至少有2次以上的子串重复。
1 | def repeatedSubstringPattern(self, s: str) -> bool: |
165. Compare Version Numbers
比较两个版本号,版本的大小。原题
1 | Input: version1 = "7.5.2.4", version2 = "7.5.3" |
方法一:这题写完直接自信提交。
1 | def compareVersion(self, version1: str, version2: str) -> int: |
方法二:学学stefan的写法。其实就是cmp函数,python3没有这个函数。
1 | def compareVersion(self, version1: str, version2: str) -> int: |
1371. Find the Longest Substring Containing Vowels in Even Counts
找到最长的包含偶数个元音字母的字符串,这道题非常的典型。原题
1 | Input: s = "eleetminicoworoep" |
方法一:自己研究了半天的写法,其实感觉2个数组记录属实有点多余。对于变化的形态,一种有32种状态,我这里是记录了这个状态最开始时上个状态+1的索引,因为这种状态可以通过非元音往两侧延伸。然后记录了每种状态最后的索引。结果就是两个索引的差值。
1 | def findTheLongestSubstring(self, s: str) -> int: |
1<<i>>1
是为了将其他find为0的变成0。不过大佬的方法比我的慢了200ms,可能因为’aeiou‘的反复遍历。
1 | def findTheLongestSubstring(self, s: str) -> int: |
443. String Compression
原地压缩一个字符数组,如果是1则不需要补数量。原题
1 | Input: chars = ["a","a","b","b","c","c","c"] |
方法一:因为不能使用其它的空间,所以只能是通过指针来改变。0作为一个结尾符号,因为还可能包含其它符号,而不会出现数字。
1 | def compress(self, chars: List[str]) -> int: |
809. Expressive Words
情感丰富的单词,给定一个单词列表,判断有多少个可以变成S,规则是可以重复一个字母,但是至少要重复到3次。原题
1 | Example: |
方法一:首次AC的方法,groupby
注意只能遍历一次,哪怕是求len,也会导致其中嵌套的生成器被消耗掉。
1 | def expressiveWords(self, S: str, words: List[str]) -> int: |
zip_longest
。
1 | def expressiveWords(self, S: str, words: List[str]) -> int: |
833. Find And Replace in String
找到匹配并替换,注意是所有的同时替换,因为替换长度不同可能会导致索引不一致,所以不能用切片直接修改。原题
1 | Input: S = "abcd", indexes = [0,2], sources = ["ab","ec"], targets = ["eee","ffff"] |
方法一:注意last_i要更新,还有一点是,islice用的不熟,以为islice(S, 0)
是从0开始呢,原来是到0截止。
1 | def findReplaceString(self, S: str, indexes: List[int], sources: List[str], targets: List[str]) -> str: |
1 | def findReplaceString(self, S: str, indexes: List[int], sources: List[str], targets: List[str]) -> str: |
1 | def findReplaceString(self, S: str, indexes: List[int], sources: List[str], targets: List[str]) -> str: |
面试题 17.15. 最长单词
给定一组单词words,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成。若有多个长度相同的结果,返回其中字典序最小的一项,若没有符合要求的单词则返回空字符串。
方法一:dfs。
1 | def longestWord(self, words: List[str]) -> str: |
面试题 16.18. 模式匹配
你有两个字符串,即pattern和value。 pattern字符串由字母”a”和”b”组成,用于描述字符串中的模式。例如,字符串”catcatgocatgo”匹配模式”aabab”(其中”cat”是”a”,”go”是”b”),该字符串也匹配像”a”、”ab”和”b”这样的模式。但需注意”a”和”b”不能同时表示相同的字符串。编写一个方法判断value字符串是否匹配pattern字符串。
方法一:这题边界条件挺多的。写了很长时间。不是最优的时间复杂度,但是速度还可以。
1 | def patternMatching(self, pattern: str, value: str) -> bool: |
1638. Count Substrings That Differ by One Character
两个字符串的连续子串中刚好差一个字符的一共有多少对。
1 | Input: s = "aba", t = "baba" |
方法一: 比赛时暴力过的。复杂度很高,时间1000ms+,不过居然能过。
1 | def countSubstrings(self, s: str, t: str) -> int: |
1 | def countSubstrings(self, s: str, t: str) -> int: |