刷题链接:力扣
整数反转:
题目:给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123 输出:321
算法思路:
python代码:因为是整数,所以把它变为单个的数字并且要翻转的话,思路就是处于10取余,然后这个余数再乘10加上下一个数就达到了翻转的效果,代码如下,但是有几个用例过不去,也不知道为什么。
参考代码里,把整数转为字符串了,然后通过切片反转。但是它的判断溢出那里,我就没太明白怎么会这样来判断???
python代码:
class Solution(object):
def reverse(self, x):
s = abs(x)
res = 0
while (s!= 0):
if x > 0 and x > 2 ** 31 - 1:
return 0
if x < 0 and x < (-2 ** 31 ):
return 0
temp = s % 10
res = res * 10 + temp
s = s / 10
return res if x >= 0 else -res
class Solution(object):
def reverse(self, x):
s = str(abs(x)) # 取绝对值转字符串
reverse_string = s[::-1] # 反转字符串
if len(reverse_string) > 1: # 如果数字大于一位数
temp = int(reverse_string[:-1]) # 切去最后一位防止数字反转溢出
print(temp)
if temp > 2**31//10: # 溢出
return 0
return int(reverse_string) if x >= 0 else -int(reverse_string)
字符串中的第一个唯一字符
题目:给定一个字符串 s
,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1
。
示例 :
输入: s = "loveleetcode" 输出: 2
算法思路:开始我在想要不要使用双指针,但是发现写不出来,然后借助count()这个查找个数的函数,一旦找到就return,但是这个代码会超出时间限制。
参考代码里用到了find()和rfind()函数,明天仔细弄清楚这两个函数。然后了解一下关于字符串的基础知识。
python代码:
class Solution(object):
def firstUniqChar(self, s:str):
for i in range(len(s)):
if s.count(s[i])==1:
return i
return -1
s = "leetcode"
soluion = Solution()
firstUniqChar = soluion.firstUniqChar(s)
print(firstUniqChar)
#参考代码
class Solution(object):
def firstUniqChar(self, s):
# 先假设最小索引为最后的字符索引 + 1
min_unique_char_index = len(s)
# 已知字符串由小写字母构成,则遍历 a - z
for c in "abcdefghizklmnopqrstuvwxyz":
i = s.find(c)
# 分别从目标的字符串头和字符串尾查找对应字母的索引;若两索引相等,则说明是单一字符
if i != -1 and i == s.rfind(c):
# 更新最小索引
min_unique_char_index = min(min_unique_char_index, i)
# 如果返回值不为最后字符的索引 + 1,则返回最小索引值
# 否则,返回 -1
return min_unique_char_index if min_unique_char_index != len(s) else -1
有效的字母异位词
题目:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
算法思路:
python代码:开始想的是暴力解法,但是没有写出来,然后看了别人的思路,使用了哈希表。如果没有defaultdict()函数,那么开始的时候dict_s和dict_t都是空字典,当第一次遇到s[i]时,它在字典中就还不存在所以就会找不到键‘s[i]’而引发KeyError,所以就需要defaultdict()函数当访问不存在的键时,会自动创建一个默认值。所以这里就使用了两个字典,它们的key是每一个字符,key对应的value是字符出现的个数。然后用出现在 dict_s 里面的k和v判断在dict_t这个字典里是不是也同样存在。
还有很直接的方法就是,对这两个字符串排序(sorted()函数),然后判断这两个字符串相不相等。
还有就是使用Counter()这个函数,它可以接受一个可迭代对象作为参数,并返回一个字典,其中键是元素,值是元素的出现次数。比如,print(s_count) 它的输出是:Counter({'a': 3, 'n': 1, 'g': 1, 'r': 1, 'm': 1})
python代码:
from collections import defaultdict
class Solution(object):
def isAnagram(self,s,t):
n = len(s)
m = len(t)
dict_s = defaultdict(int)
dict_t = defaultdict(int)
if n != m:
return False
for i in range(n):
dict_s[s[i]] +=1
dict_t[t[i]] +=1
for k,v in dict_s.items():
if dict_t[k] !=v:
return False
return True
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
return sorted(s) == sorted(t)
class Solution(object):
def isAnagram(self, s: str, t: str) -> bool:
from collections import Counter
a_count = Counter(s)
b_count = Counter(t)
return a_count == b_count
验证回文串
题目:如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
示例 1:
输入: s = "A man, a plan, a canal: Panama" 输出:true
算法思路:先都转为小写,然后移除所有非字母数字字符,之后反转看看是否和现在的相等?
python代码:
class Solution(object):
def isPalindrome(self, s):
if len(s)==0:
return True
t=[]
s=s.lower()
for i in s:
if (ord(i)>=97 and ord(i)<=122) or (ord(i)>=48 and ord(i)<=57):
t.append(i)
if t==t[::-1]:
return True
else:
return False
字符串转换整数 (atoi)
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数。
函数 myAtoi(string s) 的算法如下:
- 空格:读入字符串并丢弃无用的前导空格(" ")
- 符号:检查下一个字符(假设还未到字符末尾)为 '-' 还是 '+'。如果两者都不存在,则假定结果为正。
- 转换:通过跳过前置零来读取该整数,直到遇到非数字字符或到达字符串的结尾。如果没有读取数字,则结果为0。
- 舍入:如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被舍入为 −231 ,大于 231 − 1 的整数应该被舍入为 231 − 1 。
- 返回整数作为最终结果。
算法思路:
这个题注意需要补的理论知识有:s.lstrip()函数可以移除字符串s开头的空白字符(包括空格、制表符、换行符等),if not s 表示如果s字符串为空,因为上传的是字符串的形式,所以当用isdigit()函数判断出这个字符串是数字时,需要把它加到输出的里时,需要用到d *= 10 d += ord(i) - 48 这个代码,ord(i) - 48就可以把 i 转为数字的形式。还有就是最后整数的范围,这个就可以在返回的时候 return max(-2**31, min(sign * d,2**31-1)) 妙啊!!!虽然写出来就是按照要求来写的,但是还有有很多步骤不知道该咋处理。
python代码:
class Solution(object):
def myAtoi(self,s):
s = s.lstrip()
if not s:
return 0
sign = -1 if s[0]=="-" else 1
if sign == -1 or s[0] == "+":
s = s[1:]
d = 0
for i in s:
if i.isdigit():
d *=10
d +=ord(i)-48
else:
break
return max(-2**31, min(sign * d,2**31-1))
实现 strStr()
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
示例 1:
输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0
算法思路:
这个题主要是看needle在不在 haystack里,如果用直观的想法就是判断 haystack[i:i+n] == needle 然后再用一个for循环,如果找到就return i ,就可以找到第一个了。代码如下,但是这个题是典型的KMP算法。
什么是KMP算法呢?
python代码:
class Solution(object):
def strStr(self,haystack, needle):
m,n = len(haystack),len(needle)
for i in range(m):
if haystack[i:i+n] == needle:
return i
return -1
外观数列
题目:「外观数列」是一个数位字符串序列,由递归公式定义:
- countAndSay(1) = "1"
- countAndSay(n) 是 countAndSay(n-1) 的行程长度编码。
行程长度编码(RLE)是一种字符串压缩方法,其工作原理是通过将连续相同字符(重复两次或更多次)替换为字符重复次数(运行长度)和字符的串联。例如,要压缩字符串 "3322251" ,我们将 "33" 用 "23" 替换,将 "222" 用 "32" 替换,将 "5" 用 "15" 替换并将 "1" 用 "11" 替换。因此压缩后字符串变为 "23321511"。
给定一个整数 n ,返回 外观数列 的第 n 个元素。
示例 1:
输入:n = 4
输出:"1211"
解释:
countAndSay(1) = "1"
countAndSay(2) = "1" 的行程长度编码 = "11"
countAndSay(3) = "11" 的行程长度编码 = "21"
countAndSay(4) = "21" 的行程长度编码 = "1211"
算法思路:就是根据countAndSay(n-1)的值来算countAndSay(n)的行程长度编码,然后知道countAndSay(1) = "1",有点像数学中的递归法。怎么实现呢?(不知道)看答案吧。
首先如果输入的是n,那么就返回'1',然后通过递归调用self.countAndSay(n - 1)获取上一个状态的结果,并将其赋值给s。同时,n ==1也是递归的终止条件。最开始的时候,会遍历完self.countAndSay(n - 1),直到把n 遍历到1。然后把返回的 字符串1 赋值给s。所以经过self.countAndSay(n - 1)后,s=‘1’。然后开始使用双指针,这个递归没有看懂唉,后面的双指针感觉把输出打出来也不对。算了,背吧!!!
python代码:
class Solution(object):
def countAndSay(self,n):
if n == 1:
return "1"
s = self.countAndSay(n - 1)
ans =''
start,end = 0,0
while end < len(s):
while end < len(s) and s[start] == s[end]:
end +=1
ans += str(end-start) + s[start]
start = end
return ans
最长公共前缀
题目:编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""
。
示例 1:
输入:strs = ["flower","flow","flight"] 输出:"fl"
算法思路:
如何把输入的字符串组分割出来呢?strs = ["flower","flow","flight"] print(strs[0])输出的是flower。然后使用二维数组strs[i][j],只需要判断第一个字符串与剩下的字符串相等吗?如果相等就记录它的count,然后在返回的时候,返回pre[:count]。
python代码:
class Solution(object):
def longestCommonPrefix(self,strs):
if len(strs)==0:
return ""
pre = strs[0]
strs = strs[1:]
for i in range(len(strs)):
count = 0
length = min(len(pre),len(strs[i]))
for j in range(length):
if strs[i][j] == pre[j]:
count +=1
else:
break
pre = pre[:count]
return pre