Day06
43. 字符串相乘 (Medium)
- 模拟竖乘法
# 4 5 6
# * 1 2 3
# ----------------------------------------
# 12 15 18
# 8 10 12
# + 4 5 6
# -----------------------------------------
# 4 13 28 27 18 进位
# 5 6 0 8 8
1.遍历num1[::-1]和num2[::-1]
2.取字典d的key值(0, 1, 2, 3, 4)
3.此时的d为{0: 8, 1: 28, 2: 28, 3: 13, 4: 4},
通过list(map(str, d.values()))[::-1]))后为:[‘8’, ‘8’, ‘0’, ‘6’, ‘5’, ‘0’], 然后用正则修正返回结果.
"""
43. 字符串相乘 (Medium) 链接:https://leetcode-cn.com/problems/multiply-strings/
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
示例 1:
输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
说明:
num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理
"""
class Solution:
# 直接转类型相乘再转字符串
def multiply(self, num1: str, num2: str) -> str:
"""
:type num1: str
:type num2: str
:rtype: str
"""
return str(int(num1) * int(num2))
class Solution_baoli_shucheng:
# 思路:模拟竖乘法
# 4 5 6
# * 1 2 3
# ----------------------------------------
# 12 15 18
# 8 10 12
# + 4 5 6
# -----------------------------------------
# 4 13 28 27 18 进位
# 5 6 0 8 8
def multiply(self, num1: str, num2: str) -> str:
"""
:type num1: str :123
:type num2: str :456
:rtype: str
"""
d = {}
# 遍历num1[::-1]和num2[::-1],此时的i, n1, j, n2, d[i + j], d分别是
# i = 0, n1 = 3, j = 0, n2 = 6, d[i + j] = 18, d = {0: 18}
# i = 0, n1 = 3, j = 1, n2 = 5, d[i + j] = 15, d = {0: 18, 1: 15}
# i = 0, n1 = 3, j = 2, n2 = 4, d[i + j] = 12, d = {0: 18, 1: 15, 2: 12}
# i = 1, n1 = 2, j = 0, n2 = 6, d[i + j] = 15 + 12, d = {0: 18, 1: 27, 2: 12}
# i = 1, n1 = 2, j = 1, n2 = 5, d[i + j] = 12 + 10, d = {0: 18, 1: 27, 2: 22}
# i = 1, n1 = 2, j = 2, n2 = 4, d[i + j] = 8, d = {0: 18, 1: 27, 2: 22, 3: 8}
# i = 2, n1 = 1, j = 0, n2 = 6, d[i + j] = 22 + 6, d = {0: 18, 1: 27, 2: 28, 3: 8}
# i = 2, n1 = 1, j = 1, n2 = 5, d[i + j] = 8 + 5, d = {0: 18, 1: 27, 2: 28, 3: 13}
# i = 2, n1 = 1, j = 2, n2 = 4, d[i + j] = 4, , d = {0: 18, 1: 27, 2: 28, 3: 13, 4: 4}
for i, n1 in enumerate(num1[::-1]):
for j, n2 in enumerate(num2[::-1]):
d[i + j] = d.get(i + j, 0) + int(n1) * int(n2)
# 取字典d的key值(0, 1, 2, 3, 4)
for k in [*d]:
# 此时d[k], d[k + 1]分别是
# k = 0, d[0] = 8, d[1] = 27 + 1 = 28
# k = 1, d[1] = 8, d[2] = 28 + 2 = 30
# k = 2, d[2] = 0, d[3] = 13 + 3 = 16
# k = 3, d[3] = 6, d[4] = 4 + 1 = 5
d[k + 1], d[k] = d.get(k + 1, 0) + int(d[k] * 0.1), d[k] % 10
# 此时的d为{0: 8, 1: 28, 2: 28, 3: 13, 4: 4},
# 通过list(map(str, d.values()))[::-1]))后为:['8', '8', '0', '6', '5', '0'], 然后用正则修正返回结果.
return re.sub('^0*', '', ''.join(map(str, d.values()))[::-1]) or '0'
46. 全排列 (Medium)
46. 全排列 (Medium)
思路:
1.python内置库itertools的permutations函数,不放回抽样排列.
2.递归法,首先设定递归两个参数,即"状态",path来记录每次选定的数字,cand为剩下的数字.递归的终止条件为cand为空.首先传入参数为path=[],cand=nums=[123],假设此时nums=123,则每次遍历,cand往path丢数,剩下继续进入递归函数中,直到终止.详细看以下代码.
"""
46. 全排列 (Medium) 链接:https://leetcode-cn.com/problems/permutations/
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
"""
import itertools
from typing import List
class Solution(object):
# 调用python库permutations 不放回抽样排列
def permute(self, nums: List[int]) -> List[List[int]]:
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
return list(itertools.permutations(nums))
class Solution_recursion:
# 递归
def permute(self, nums: List[int]) -> List[List[int]]:
"""
:type nums: List[int]: 123
:rtype: List[List[int]]
"""
if len(nums) <= 1:
return [nums]
self.res = []
def recursion(path, cand):
# 若cand为空,则把path添加到res结果当中
if len(cand) == 0:
self.res.append(path)
# 遍历cand,以123为例,一开始递归状态为:
# path = [], cand = nums = [123], self.res = []
# path = [1], cand = [23], self.res = []
# path = [12], cand = [3], self.res = []
# path = [123], cand = [], self.res = [123]
# path = [1], cand = [23], self.res = []
# path = [13], cand = [2], self.res = []
# path = [132], cand = [], self.res = [[123], [132]]
for i, n in enumerate(cand):
recursion(path + [n], cand[:i] + cand[i + 1:])
recursion([], nums)
return self.res
class Solution_back_track(object):
# 回溯法
def permute(self, nums: List[int]) -> List[List[int]]:
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if len(nums) == 0:
return []
res = []
def Back_track(nums, path):
if not nums:
res.append(path)
return
for i in range(len(nums)):
cur = nums[i]
Back_track(nums[:i] + nums[i + 1:], path + [cur])
Back_track(nums, [])
return res
53. 最大子序和 (Easy)
53. 最大子序和 (Easy)
思路:
贪心算法
"""
53. 最大子序和 (Easy) 链接:https://leetcode-cn.com/problems/maximum-subarray/
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
"""
from typing import List
class Solution(object):
# 贪心算法
# Time complexity: O(N)
# Space complexity: O(1)
def maxSubArray(self, nums: List[int]) -> int:
"""
:type nums: List[int]
:rtype: int
"""
# 初始化当前和与最大和
cur_sum = max_sum = nums[0]
# 从nums[1]开始遍历
for i in range(1, len(nums)):
# 以每次遍历的第i个数值 与 当前和加第i数值的和进行比较取max得到更新后的当前和
cur_sum = max(nums[i], cur_sum + nums[i])
# 以当前和 与 最大和进行比较取max
max_sum = max(cur_sum, max_sum)
return max_sum