LeetCode题集四
- 简单题
- 171. Excel表列序号
- 172. 阶乘后的零
- 189. 旋转数组
- 中等题
- 2. 两数相加
- 3. 无重复字符的最长子串
- 5. 最长回文子串
- 6. Z 字形变换
- 8. 字符串转换整数 (atoi)
简单题
171. Excel表列序号
题目:
思路:
26进制转10进制。
解法:
class Solution:
def titleToNumber(self, s: str) -> int:
if not s:
return 0
n = len(s)
res = 0
for i in range(n):
res += 26 ** (n-i-1) * (ord(s[i]) -64)
return res
172. 阶乘后的零
题目:
思路:
要在末位产生0,则必然是5×2,即使是原数中包含的0也可以分解,因此将题目简化为寻找阶乘中5的个数,即n//5,但是25又可以拆解成5×5,所以还得记上这一次。
解法:
class Solution:
def trailingZeroes(self, n: int) -> int:
# 非递归
res = 0
while n > 0:
n //= 5
res += n
return res
# # 递归
# if n == 0:
# return 0
# else:
# return self.trailingZeroes(n // 5) + n // 5
189. 旋转数组
题目:
思路:
1.最直接的方法就是按照题意读取最后一个值,如果插入第一个位置;
2.反转法,先反转整个数组,再反转前k个数,再反转剩下的数;
解法:
- 直接求解
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# # 暴力破解
for i in range(k):
num = nums.pop()
nums.insert(0, num)
- 反转法
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# 反转法
l = len(nums)
k = k % n
if n < 2:
pass
else:
def reverse(nums, t, s):
while t < s:
nums[t], nums[s] = nums[s], nums[t]
t += 1
s -= 1
reverse(nums, 0, n-1)
reverse(nums, 0, k-1)
reverse(nums, k, n-1)
中等题
2. 两数相加
题目:
思路:
创建一个新的链表,每一个结点相加后将个位数入栈,用carry表示十位数是否进位,依次遍历给定链表,可以获得目标链表。
解法:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
carry = 0
res = ListNode(0)
cur = res
while l1 or l2:
val_1 = l1.val if l1 else 0
val_2 = l2.val if l2 else 0
val_sum = val_1 + val_2 + carry
carry = val_sum // 10
cur.next = ListNode(val_sum % 10)
cur = cur.next
if l1:
l1 = l1.next
if l2:
l2 = l2.next
if carry > 0:
cur.next = ListNode(carry)
return res.next
3. 无重复字符的最长子串
题目:
思路:
遍历字符串,当字母不存在与子串中,加入子串。当字母存在于子串中,查找子串中这个字母的位置,子串变为这个字母之后的切片。
解法:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# 如果是空,返回0
if not s:
return 0
# 初始化参数
sub_sring = ""
sub_len = 0
max_len = 0
for c in s:
# 当字母已经存在了,回溯到前一个相同字母的位置
if c in sub_sring:
sub_sring = sub_sring[sub_sring.index(c) + 1:]
sub_len = len(sub_sring)
sub_sring += c
sub_len += 1
if sub_len >= max_len:
max_len = sub_len
return max_len
5. 最长回文子串
题目:
思路:
尝试了各种写法,还是暴力破解舒服
解法:
class Solution:
def longestPalindrome(self, s: str) -> str:
for l in range(len(s), -1, -1):
for i in range(0, len(s) - l + 1):
sub_string = s[i:l + i]
if sub_string == sub_string[::-1]:
return sub_string
6. Z 字形变换
题目:
思路:
Z字形走动,可以使用一个flag来判别行走的方向。
解法:
class Solution:
def convert(self, s: str, numRows: int) -> str:
if numRows < 2:
return s
res = ["" for _ in range(numRows)]
i, flag = 0, -1
# flag 表示方向
for c in s:
res[i] += c
if i == 0 or i == numRows - 1:
flag = -flag
i += flag
return "".join(res)
8. 字符串转换整数 (atoi)
题目:
思路:
遍历判断。
解法:
class Solution:
def myAtoi(self, str: str) -> int:
# 去除首尾的空格
str = str.strip()
if not str:
return 0
result = ''
flag = 1
# 遍历判断符号与数字
for i in range(len(str)):
if i == 0:
if str[i] not in ['+', '-'] and not str[i].isdigit():
return 0
if str[i] == '-':
flag = -1
elif str[i] == '+':
flag = 1
else:
result += str[i]
elif not str[i].isdigit():
break
else:
result += str[i]
if result:
if -2 ** 31 <= int(result) * flag <= 2 **31 - 1:
return int(result) * flag
elif flag == -1:
return - 2 ** 31
else:
return 2 ** 31 -1
else:
return 0