“字符串问题在面试中出现频率很高,你极有可能在面试中遇到。
我们推荐以下题目:反转字符串,字符串中第一个唯一字符,字符串转整数(atoi)和 实现 strStr() 。”
2.1 反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
提示:
- 1 <= s.length <= 105
- s[i] 都是 ASCII 码表中的可打印字符
相关标签 递归
双指针
字符串
法1:
输入:
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
l = len(s)
i = 0
while i < l / 2:
s[i], s[-1 - i] = s[-1 - i], s[i]
i += 1
s = ["h","e","l","l","o"]
Solution().reverseString(s)
s
输出:
['o', 'l', 'l', 'e', 'h']
执行用时:32 ms, 在所有 Python 提交中击败了98.55%的用户
内存消耗:20.4 MB, 在所有 Python 提交中击败了10.42%的用户
通过测试用例:477 / 477
法2:双指针
输入:
class Solution(object):
def reverseString(self, s):
"""
:type s: List[str]
:rtype: None Do not return anything, modify s in-place instead.
"""
left, right = 0, len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
# 交换后,左指针右移,右指针左移
left += 1
right -= 1
s = ["h","e","l","l","o"]
Solution().reverseString(s)
s
输出:
['o', 'l', 'l', 'e', 'h']
执行用时:12 ms, 在所有 Python 提交中击败了100.00%的用户
内存消耗:20.1 MB, 在所有 Python 提交中击败了92.71%的用户
通过测试用例:477 / 477
2.2 整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
提示:
- -231 <= x <= 231 - 1
相关标签 数学
法1
思路:
输入:
class Solution:
def reverse(self, x: int) -> int:
res = 0
x_ = abs(x)
while x_ != 0:
res = res * 10 + x_ % 10
x_ //= 10
res = res if x > 0 else -res
return res if -2**31 <= res <= 2**31 -1 else 0
x = -1534
print(Solution().reverse(x))
输出:
-4351
执行用时:28 ms, 在所有 Python3 提交中击败了98.42%的用户
内存消耗:14.9 MB, 在所有 Python3 提交中击败了41.42%的用户
通过测试用例:1032 / 1032
法2
输入:
class Solution(object):
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
x, flag = list(str(x)), 0
if '-' in x:
x.remove('-')
flag = 1
left, right = 0, len(x) - 1
while left < right:
x[left], x[right] = x[right], x[left]
left += 1
right -= 1
x = int(''.join(x))
if flag:
x = -x
if -2 ** 31 <= x <= 2 ** 31 - 1:
return x
else:
return 0
x = -1534
print(Solution().reverse(x))
输出:
-4351
执行用时:12 ms, 在所有 Python 提交中击败了99.63%的用户
内存消耗:13.1 MB, 在所有 Python 提交中击败了28.10%的用户
通过测试用例:1032 / 1032
2.3 字符串中的第一个唯一字符
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例:
s = "leetcode" 返回 0
s = "loveleetcode" 返回 2
提示:你可以假定该字符串只包含小写字母。
相关标签 队列
哈希表
字符串
计数
法1:
输入:
class Solution(object):
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
s = list(s)
s1 = s.copy()
for idx, i in enumerate(s1):
index = 0
while i in s:
s.remove(i)
index += 1
if index == 1:
return idx
break
if index != 1:
return -1
s = "llettccoodde"
Solution().firstUniqChar(s)
输出:
-1
执行超时,未通过。
法2:哈希表
输入:
from collections import Counter
class Solution:
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
s_dict = Counter(s)
for n in range(len(s)):
if s_dict[s[n]] == 1:
return n
return -1
s = "llettccoodde"
Solution().firstUniqChar(s)
输出:
-1
执行用时:108 ms, 在所有 Python3 提交中击败了50.20%的用户
内存消耗:15.1 MB, 在所有 Python3 提交中击败了53.26%的用户
通过测试用例:105 / 105
法2耗时更少的写法:
输入:
class Solution:
def firstUniqChar(self, s: str) -> int:
s_dict = dict()
for char in s:
if char not in s_dict.keys():
s_dict[char] = s.count(char)
for key in s_dict.keys():
if s_dict[key] == 1:
return s.index(key)
return -1
s = "llettccoodde"
Solution().firstUniqChar(s)
输出:
-1
执行用时:96 ms, 在所有 Python3 提交中击败了61.32%的用户
内存消耗:15.1 MB, 在所有 Python3 提交中击败了53.26%的用户
通过测试用例:105 / 105
2.4 有效的字母异位词
给定两个字符串s和t ,编写一个函数来判断t是否是s的字母异位词。
注意:若s和t中每个字符出现的次数都相同,则称s和t互为字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
提示:
- 1 <= s.length, t.length <= 5 * 104
- s 和 t 仅包含小写字母
进阶:如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?
相关标签 哈希表
字符串
排序
输入:
from collections import Counter
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
s_dict, t_dict = Counter(s), Counter(t)
if s_dict == t_dict:
return True
else:
return False
s = "anagram"
t = "nagaram"
Solution().isAnagram(s, t)
输出:
True
执行用时:36 ms, 在所有 Python 提交中击败了64.57%的用户
内存消耗:13.3 MB, 在所有 Python 提交中击败了83.78%的用户
通过测试用例:36 / 36
2.5 验证回文串
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
解释:"amanaplanacanalpanama" 是回文串
示例 2:
输入: "race a car"
输出: false
解释:"raceacar" 不是回文串
提示:
- 1 <= s.length <= 2 * 105
- 字符串 s 由 ASCII 字符组成
相关标签 双指针
字符串
输入:
# “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
class Solution(object):
def isPalindrome(self, s):
"""
:type s: str
:rtype: bool
"""
s = ''.join(filter(str.isalnum,str(s))).lower()
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
s = "A man, a plan, a canal: Panama"
Solution().isPalindrome(s)
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表的迭代器。
输出:
True
执行用时:28 ms, 在所有 Python 提交中击败了93.04%的用户
内存消耗:13.8 MB, 在所有 Python 提交中击败了73.70%的用户
通过测试用例:480 / 480
手动实现filter功能
输入:
class Solution:
def isPalindrome(self, s: str) -> bool:
s = "".join([s_char for s_char in s if s_char.isalpha() or s_char.isdigit()]).lower()
left, right = 0, len(s)-1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
s = "A man, a plan, a canal: Panama"
Solution().isPalindrome(s)
输出:
True
执行用时:48 ms, 在所有 Python3 提交中击败了71.08%的用户
内存消耗:16 MB, 在所有 Python3 提交中击败了48.13%的用户
通过测试用例:485 / 485
2.7 实现 strStr()
实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = "hello", needle = "ll"
输出:2
示例 2:
输入:haystack = "aaaaa", needle = "bba"
输出:-1
示例 3:
输入:haystack = "", needle = ""
输出:0
提示:
- 0 <= haystack.length, needle.length <= 5 * 104
- haystack 和 needle 仅由小写英文字符组成
相关标签 双指针
字符串
字符串匹配
输入:
class Solution(object):
def strStr(self, haystack, needle):
"""
:type haystack: str
:type needle: str
:rtype: int
"""
for i in range(len(haystack)):
if haystack[i] == needle[0] and haystack[i:i+len(needle)] == needle:
return i
return -1
a = ''
b = 'a'
Solution().strStr(a,b)
输出:
-1
执行用时:36 ms, 在所有 Python3 提交中击败了70.24%的用户
内存消耗:14.7 MB, 在所有 Python3 提交中击败了98.33%的用户
通过测试用例:79 / 79
2.9 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
提示:
- 1 <= strs.length <= 200
- 0 <= strs[i].length <= 200
- strs[i] 仅由小写英文字母组成
相关标签 字符串
输入:
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
contrast = strs[0]
min_len = min([len(str) for str in strs])
if min_len > 0:
for i in range(min_len):
for str in strs:
if contrast[i] == str[i]:
continue
else:
return contrast[:i]
return contrast[:i+1]
else:
return ""
strs = ["flower","flow","flight"]
Solution().longestCommonPrefix(strs)
输出:
'fl'
执行用时:28 ms, 在所有 Python3 提交中击败了97.97%的用户
内存消耗:15 MB, 在所有 Python3 提交中击败了52.01%的用户
通过测试用例:124 / 124