开始 字符串部分了,这一部分的花的时间不少了 今天上午给整理出来,主要就是一些有关字符串的基本函数应用,非常需要勤加练习.
题目链接:13. 罗马数字转整数
题目大意:罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如:
输入: s = "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
解题思路:非常基础的一道题 使用哈希表是不错的选择.
class Solution:
def romanToInt(self, s: str) -> int:
hash_map = {
'I':1,'IV':4,'V':5, 'IX':9,
'X':10,'XL':40,'L':50,'XC': 90,
'C':100,'CD':400 ,'D':500,'CM':900,
'M':1000
}
idx,n = 0,len(s)
ans = 0
while idx < n:
if s[idx:idx+2] in hash_map:
ans += hash_map[s[idx:idx+2]]
idx += 2
else:
ans += hash_map[s[idx]]
idx += 1
return ans
题目链接:28. 实现 strStr()
题目大意:实现 strStr() 函数。给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
例如:
输入:haystack = "hello", needle = "ll"
输出:2
输入:haystack = "aaaaa", needle = "bba"
输出:-1
解题思路: 简单题 直接使用 in 函数就很简单.
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
if len(needle) == 0: return 0
if needle not in haystack:
return -1
for i,ch in enumerate(haystack):
if ch == needle[0]:
if haystack[i:i+len(needle)] == needle:
return i
题目链接:67. 二进制求和
题目大意:给你两个二进制字符串,返回它们的和(用二进制表示)。输入为 非空 字符串且只包含数字 1 和 0。
例如:
输入: a = "11", b = "1"
输出: "100"
输入: a = "1010", b = "1011"
输出: "10101"
解题思路:经典习题啊! 需要额外设置 进位位 carry,具体看代码.
class Solution:
def addBinary(self, a: str, b: str) -> str:
n1,n2 = len(a),len(b)
ans = ''
i,j,carry = n1-1,n2-1,0
while i>=0 or j>=0:
num1 = int(a[i]) if i>=0 else 0
num2 = int(b[j]) if j>=0 else 0
tmp = num1 + num2 + carry
carry = tmp // 2
ans = str(tmp%2) + ans
i -= 1
j -= 1
return '1'+ans if carry else ans
题目链接:91. 解码方法
题目大意:一条包含字母 A-Z 的消息通过以下映射进行了 编码 :
'A' -> "1"
'B' -> "2"
...
'Z' -> "26"
要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,“11106” 可以映射为:
例如:
输入:s = "12"
输出:2
解释:它可以解码为 "AB"(1 2)或者 "L"(12)。
输入:s = "226"
输出:3
解释:它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
解题思路: 动态规划经典题,一看就懵,要多背一背这类题的求解方式,有点类似于递归的思想.
class Solution:
def numDecodings(self, s: str) -> int:
n = len(s)
dp = [1] + [0]*n
for i in range(1,n+1):
if s[i-1] != '0':
dp[i] += dp[i-1]
if i>=2 and s[i-2] != '0' and int(s[i-2:i])<=26:
dp[i] += dp[i-2]
print(dp)
return dp[n]
题目链接:125. 验证回文串
题目大意: 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。字母和数字都属于字母数字字符。给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
例如:
输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。
输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。。
解题思路: 简单题,重拳出击,两种编写方法,思路是一致的.
(一) 使用 循环分解字符串
class Solution:
def isPalindrome(self, s: str) -> bool:
if len(s) == 0: return True
s = ''.join(ch.lower() for ch in s if ch.isalnum())
return s == s[::-1]
(二)使用 filter 迭代器 分解字符串 稍微快一些
class Solution:
def isPalindrome(self, s: str) -> bool:
# filter 函数要比使用循环快一些
s = ''.join(filter(str.isalnum,s)).lower()
return s == s[::-1]
题目链接:151. 反转字符串中的单词
题目大意:给你一个字符串 s ,请你反转字符串中 单词 的顺序。单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
例如:
输入:s = "the sky is blue"
输出:"blue is sky the"
解题思路 :大胆做就成 其实也可以使用 reversed 函数
class Solution:
def reverseWords(self, s: str) -> str:
return ' '.join(s.split()[::-1])
题目链接:205. 同构字符串
题目大意: 给定两个字符串 s 和 t ,判断它们是否是同构的。如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。
例如:
输入:s = "egg", t = "add"
输出:true
输入:s = "foo", t = "bar"
输出:false
解题思路: 后面好像有一道更难一点的,一会比较一下!
class Solution:
def isIsomorphic(self, s: str, t: str) -> bool:
if len(set(s)) != len(set(t)): return False
seen = dict()
for ch1,ch2 in zip(s,t):
if ch1 not in seen:
seen[ch1] = ch2
else:
if seen[ch1] != ch2:
return False
return True
题目链接:344. 反转字符串
题目大意: 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
例如:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
解题思路:简单题 这里使用的是切片的方法.
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
n = len(s)
for i in range(n//2):
s[i],s[n-1-i] = s[n-1-i],s[i]
题目链接:345. 反转字符串中的元音字母
题目大意:给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现。
例如:
输入:s = "hello"
输出:"holle"
解题思路: 双指针 不难.
class Solution:
def reverseVowels(self, s: str) -> str:
def isVowel(ch: str) -> bool:
if ch in 'aeiouAEIOU':
return True
else:
return False
n = len(s)
c = list(s)
i,j = 0,n-1
while i<j:
while i<=n-1 and not isVowel(c[i]):
i += 1
while j>=0 and not isVowel(c[j]):
j -= 1
if i<j:
c[i],c[j] = c[j],c[i]
i += 1
j -= 1
return ''.join(c)
题目链接:387. 字符串中的第一个唯一字符
题目大意:给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1
例如:
输入: s = "leetcode"
输出: 0
解题思路: Counter 特别好用.
class Solution:
def firstUniqChar(self, s: str) -> int:
counter = collections.Counter(s)
for i,ch in enumerate(s):
if counter[ch] == 1:
return i
return -1
# 最好不要用 s.count 太tm慢了
# for i,ch in enumerate(s):
# if s.count(ch) == 1:
# return i
# return -1
题目链接:409. 最长回文串
题目大意:「给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的回文串 。在构造过程中,请注意 区分大小写 。比如 “Aa” 不能当做一个回文字符串。
例如:
输入:s = "abccccdd"
输出:7
解释:我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
解题思路: 全部偶数+一个奇数或没有奇数
class Solution:
def longestPalindrome(self, s: str) -> int:
n = len(s)
if n == 1: return 1
counter = collections.Counter(s)
tmp = 0
for ch in counter:
if counter[ch] % 2 == 1:
tmp += 1
return n-tmp+1 if tmp else n
题目链接:412. Fizz Buzz
题目大意:给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:
answer[i] == “FizzBuzz” 如果 i 同时是 3 和 5 的倍数。
answer[i] == “Fizz” 如果 i 是 3 的倍数。
answer[i] == “Buzz” 如果 i 是 5 的倍数。
answer[i] == i (以字符串形式)如果上述条件全不满足。
例如:
输入:n = 5
输出:["1","2","Fizz","4","Buzz"]
解题思路: if条件判断
class Solution:
def fizzBuzz(self, n: int) -> List[str]:
ans = []
for i in range(1,n+1):
if i % 3 == 0 and i % 5 == 0:
ans.append("FizzBuzz")
elif i % 3 == 0:
ans.append("Fizz")
elif i % 5 == 0:
ans.append('Buzz')
else:
ans.append(str(i))
return ans
题目链接:500. 键盘行
题目大意:
给你一个字符串数组 words ,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。
美式键盘 中:
第一行由字符 “qwertyuiop” 组成。
第二行由字符 “asdfghjkl” 组成。
第三行由字符 “zxcvbnm” 组成。
例如:
输入:words = ["Hello","Alaska","Dad","Peace"]
输出:["Alaska","Dad"]
解题思路: all 函数 很好用!
class Solution:
def findWords(self, words: List[str]) -> List[str]:
hash_map =["qwertyuiop","asdfghjkl","zxcvbnm"]
ans = []
for word in words:
flag = 0
word1 = word.lower()
for i in range(3):
if all(ch in hash_map[i] for ch in word1):
ans.append(word)
return ans
题目链接:537. 复数乘法
题目大意:复数 可以用字符串表示,遵循 “实部+虚部i” 的形式,并满足下述条件:
例如:
输入:num1 = "1+1i", num2 = "1+1i"
输出:"0+2i"
解释:(1 + i) * (1 + i) = 1 + i2 + 2 * i = 2i ,你需要将它转换为 0+2i 的形式。
解题思路: 按照题意进行即可,需要注意 map split 等函数的运用.
class Solution:
def complexNumberMultiply(self, num1: str, num2: str) -> str:
real1, imag1 = map(int,num1[:-1].split('+'))
real2, imag2 = map(int,num2[:-1].split('+'))
real = real1*real2 - imag1*imag2
imag = real1*imag2 + real2*imag1
return str(real)+'+'+str(imag)+'i'
# return f'{real}+{imag}i'
题目链接:541. 反转字符串 II
题目大意:给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
例如:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
解题思路: reversed() 函数挺好用的!
class Solution:
def reverseStr(self, s: str, k: int) -> str:
s = list(s)
n = len(s)
# 切片[::-1] 有返回值, reverse()函数没有返回值
# 使用反向切片注意 start > end
for i in range(0,n,2*k):
# 方法1
s[i:i+k] = reversed(s[i:i+k])
# 方法2 切片的 end 位置不能写-1 即[:-1:-1] 返回空数组
# s[i:i+k] = s[i:i+k][::-1]
return ''.join(s)
题目链接:557. 反转字符串中的单词 III
题目大意:给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
例如:
输入:s = "Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"
解题思路: 切片倒序
class Solution:
def reverseWords(self, s: str) -> str:
ans = s.split()
for i,word in enumerate(ans):
ans[i] = word[::-1]
# print(ans)
return ' '.join(ans)
字符串这一部分还是 比较简单 这一部分就只有上下了! 加油,努力,奋斗!