88. 合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 num1 成为一个有序数组。
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
# 方法1:技巧合并
# nums1[:] = nums1[:len(nums1)-n] + nums2
# nums1.sort()
# 方法2:双指针:从后往前
p1, p2 = m-1, n-1
p = m+n-1
while p1 >= 0 and p2 >= 0:
if nums1[p1] < nums2[p2]:
nums1[p] = nums2[p2]
p2 -= 1
else:
nums1[p] = nums1[p1]
p1 -= 1
p=p-1
nums1[:p2+1] = nums2[:p2+1]
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
# 方法一:zip()+set()
# s = ""
# for i in zip(*strs):
# if len(set(i)) == 1:
# s= s+i[0]
# else:
# break
# return s
# 方法二:遍历
if len(strs) == 0:
return ''
for i in range(len(strs[0])):
c = strs[0][i]
for j in range(1,len(strs)):
if i == len(strs[j]) or strs[j][i] != c:
return strs[0][0:i]
return strs[0]
# 遍历
if len(strs)==0:return ""
tmp = ""
for i in range(len(strs[0])):
for j in range(1, len(strs)):
if len(strs[j]) == i or strs[0][i] != strs[j][i]:
return tmp
tmp = tmp + strs[0][i]
return tmp
给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
在杨辉三角中,每个数是它左上方和右上方的数的和。
class Solution:
def generate(self, numRows: int) -> List[List[int]]:
# 取巧:上下行加1
# if numRows == 0: return []
# if numRows == 1: return [[1]]
# res = [[1]]
# for i in range(2, numRows+1):
# new_row = [a+b for a,b in zip([0]+ res[-1], res[-1]+[0])]
# res.append(new_row)
# return res
# 递归
if numRows == 0:return []
if numRows == 1: return [[1]]
upper = self.generate(numRows - 1)
new_row = [1]
for i in range(1, numRows-1):
new_row.append(upper[-1][i-1]+upper[-1][i])
new_row.append(1)
upper.append(new_row)
return upper
#动态
# dp = [[1]*i for i in range(1, numRows+1)]
# for i in range(numRows):
# for j in range(1, i):
# dp[i][j] = dp[i-1][j-1]+dp[i-1][j]
# return dp
class Solution:
def romanToInt(self, s: str) -> int:
roman_dict = {
"I":"1",
"V":"5",
"X":"10",
"L":"50",
"C":"100",
"D":"500",
"M":"1000",
"IV":"4",
"IX":"9",
"XL":"40",
"XC":"90",
"CD":"400",
"CM":"900"
}
nums = 0
for i in range(len(s)-1):
if int(roman_dict[s[i]]) < int(roman_dict[s[i+1]]):
nums = nums - int(roman_dict[s[i]])
else:
nums = nums + int(roman_dict[s[i]])
nums = nums + int(roman_dict[s[-1]])
return nums
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
# 方法1:find
# return haystack.find(needle)
# 方法2:split
# if needle == "":return 0
# if needle in haystack:
# li = haystack.split(needle)
# return len(li[0])
# else:
# return -1
# 方法三:双指针
i, j = 0, 0
tmp = -1
if needle == "":return 0
while j < len(needle) and i < len(haystack):
if haystack[i] == needle[j]:
if j == 0:tmp = i
i += 1
j += 1
elif j != 0:
i, j = tmp+1, 0
tmp = -1
else:
i += 1
j,tmp = 0,-1
if j == len(needle):return tmp
return -1
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
# 方法一:for循环,逆序
# for i in range(len(nums)-1, 0, -1):
# if nums[i-1]==nums[i]:
# nums.pop(i)
# return len(nums)
# 方法二:“”占位,正序
for i in range(len(nums)-1):
if nums[i] == nums[i+1]:
nums[i] = ""
while "" in nums:
nums.remove("")
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# 方法一:切片
# k = k % len(nums)
# nums[:] = nums[-k:] + nums[:-k]
#方法二:三次反转
k = k % len(nums)
nums[:] = nums[::-1]
nums[:k] = nums[:k][::-1]
nums[k:] = nums[k:][::-1]
实现 int sqrt(int x)
函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
class Solution:
def mySqrt(self, x: int) -> int:
# 二分查找
if x < 1:return 0
if x < 4:return 1
l, r = 0, x//2
while l <= r:
mid = (r+l)//2
if mid*mid < x:
l=mid+1
elif mid*mid > x:
r=mid-1
else:
return mid
return r
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
# 数学法:
# 从最后一个元素开始遍历到底1个元素
for i in range(len(digits)-1,-1,-1):
# 如果该元素不是9,则该元素加1,返回结果
if digits[i] != 9:
digits[i] = digits[i]+1
return digits
# 如果该元素是9,则该元素变为0,遍历前一个元素,直至遍历到非9的元素
digits[i] = 0
# 如果第1个元素是0,说明是999类似的数值,则在最前面插入1
if digits[0] == 0:
digits.insert(0,1)
return digits
# 暴力法:
# 将int转为str,再join拼接
# num = int("".join([str(i) for i in digits])) + 1
# return [int(x) for x in str(num)]
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
class Solution:
def isPalindrome(self, s: str) -> bool:
# pattern = r'[a-zA-Z0-9]'
# res = re.findall(pattern, s)
# res = ''.join(res).lower()
# return res == res[::-1]
s = ''.join(e for e in s if e.isalnum()).lower()
return s==s[::-1]
给定两个字符串形式的非负整数 num1
和num2
,计算它们的和。
注意:
num1
和num2
的长度都小于 5100.num1
和num2
都只包含数字0-9
.num1
和num2
都不包含任何前导零。- 你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。
class Solution: def addStrings(self, num1: str, num2: str) -> str: i, j = len(num1)-1, len(num2)-1 carry, res = 0, "" while i >= 0 or j >= 0: if i>=0: carry += int(num1[i]) i -= 1 if j >=0: carry += int(num2[j]) j -= 1 res = str(carry%10)+res carry //= 10 if carry != 0:return "1"+res return res
小A 和 小B 在玩猜数字。小B 每次从 1, 2, 3 中随机选择一个,小A 每次也从 1, 2, 3 中选择一个猜。他们一共进行三次这个游戏,请返回 小A 猜对了几次?
输入的guess
数组为 小A 每次的猜测,answer
数组为 小B 每次的选择。guess
和answer
的长度都等于3。
class Solution:
def game(self, guess: List[int], answer: List[int]) -> int:
# guess = [1, 2, 3], answer = [1, 2, 3]
n = 0
for i in range(len(guess)):
a = guess[i]
b = answer[i]
if a == b:
n += 1
n=str(n)
return n
斐波那契数,通常用 F(n)
表示,形成的序列称为斐波那契数列。该数列由 0
和 1
开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0, F(1) = 1 F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
给定 N
,计算 F(N)
。
class Solution:
def fib(self, N: int) -> int:
# 动态
if N <= 1:
return N
a, b = 0, 1
for i in range(2, N+1):
a, b = b, a+b
return b
# # 递归
# if N <= 1:
# return N
# return self.fib(N-1) + self.fib(N-2)
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
class Solution:
def search(self, nums: List[int], target: int) -> int:
# 暴力法
# if target in nums: return nums.index(target)
# return -1
# 二分查找法1
# left, right = 0, len(nums)-1
# while (left <= right):
# mid = (right + left)//2
# if nums[mid] == target:
# return mid
# elif nums[mid] < target:
# left = mid + 1
# else:
# right = mid - 1
# return -1
给定一个二叉树,检查它是否是镜像对称的。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
#递归:
if root == None:return True
def match(l,r):
if l == None and r==None:return True
elif l == None or r ==None:return False
elif l.val != r.val:return False
return match(l.left, r.right) and match(l.right, r.left)
return match(root.left, root.right)
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def maxDepth(self, root: TreeNode) -> int:
# 递归
# if root == None:return 0
# return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
# 迭代
stack = []
if root is not None:stack.append((1, root))
depth = 0
while stack != []:
current_depth, root = stack.pop()
if root is not None:
depth = max(depth, current_depth)
stack.append((current_depth+1,root.left))
stack.append((current_depth+1,root.right))
return depth
给定由一些正数(代表长度)组成的数组 A
,返回由其中三个长度组成的、面积不为零的三角形的最大周长。
如果不能形成任何面积不为零的三角形,返回 0
。
class Solution:
def largestPerimeter(self, A: List[int]) -> int:
if 3 <= len(A):
A = sorted(A, reverse = True)
for i in range(0,len(A)-2):
if A[i] < A[i+1] + A[i+2]:
return A[i]+A[i+1]+A[i+2]
return 0
return 0
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
# 暴力法1
# if target in nums:return nums.index(target)
# i = 0
# while i < len(nums):
# if nums[i] < target:
# i +=1
# else:
# break
# return i
# 暴力法2
if target in nums:return nums.index(target)
for i in range(len(nums)):
if nums[i] > target:
return i
return i+1
# 二分法
# 因为有可能数组的最后一个元素的位置的下一个是我们要找的,故右边界是 len
# left, right = 0, len(nums)
# while (left < right):
# mid = (left + right)//2
# # 严格小于 target 的元素一定不是解
# if nums[mid] == target:
# # 下一轮搜索区间是 [mid + 1, right]
# return mid
# elif nums[mid] < target:
# left = mid + 1
# else:
# right = mid
# return left
# 技巧法
# nums.append(target)
# nums.sort()
# return nums.index(target)
对于非负整数 X
而言,X
的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231
,那么其数组形式为 [1,2,3,1]
。
给定非负整数 X
的数组形式 A
,返回整数 X+K
的数组形式。
class Solution:
def addToArrayForm(self, A: List[int], K: int) -> List[int]:
# # 1、暴力法,转化为整数
# s = ""
# for i in A:
# s = s + str(i)
# num = int(s) + K
# return [int(j) for j in str(num)]
# 方法二:遍历元素求和
K_li = [int(i) for i in str(K)]
i, j = len(A)-1, len(K_li)-1
carry, res = 0, []
while i>=0 or j>=0:
if i>=0:
carry += A[i]
i -= 1
if j>=0:
carry += K_li[j]
j -=1
res = [carry%10] + res
carry //= 10
if carry != 0:return [1]+res
return res