给定一个没有重复数字的数组和一个target,返回所有数组中的数求和为target的组合,每个数字可以重复利用。
**解题思路:**backtracking,该方法可以用来解决一类问题。注意边界值的处理
class Solution(object):
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
res = []
self.search(candidates, target, 0, [], res)
return res
def search(self, candidates, target, idx, t_res, res):
if target == 0:
res.append(sorted(t_res))
return
for i in range(idx, len(candidates)):
if target < candidates[i]:
continue
t_res.append(candidates[i])
self.search(candidates, target-candidates[i], i, t_res , res)
t_res.pop()
注意idx的传递,因为可以重复使用,循环里面提前判断当前target是不是够减,可以减少需要的操作
同Problem 39,不同的地方就是每个数字只能用一次,采用相同的方法,传递的idx每次加1即可。
给定两个字符串,每个字符均为’0’-‘9’,求解两个字符串代表的数字的乘积并返回。
解题思路:列出乘法竖式,我们可以看到对应于L两个字符串下标分别为i,j的数字的乘积,在结果中的位置。长度为a和b的字符串相乘,结果res最长为a+b,其i和j相乘的结果,位于res索引的i+j和i+j+1的位置。
class Solution(object):
def multiply(self, num1, num2):
res = [0] * (len(num1) + len(num2))
for i in range(len(num1)-1, -1, -1):
for j in range(len(num2)-1, -1, -1):
mul = int(num1[i]) * int(num2[j])
carry = i + j
mod = i + j + 1
t = mul + res[mod]
res[carry] += t // 10
res[mod] = t % 10
mul_res = 0
for i in res:
mul_res *= 10
mul_res += i
return str(mul_res)
给定一个list(没有重复值),求出它所有可能的排列组合。
解题思路:同Problem 39这类问题都可以用backtrack求解,特别注意,python里面如果用一个list,a.append(b)之后,对b的所有操作都会影响到之前a中添加的那个b,因此要使用a.append(list(b)),重新申请内存。
def search(nums, t, res):
if len(t) == len(nums):
res.append(list(t))#不能直接append(t),否则res里面的内容会随着后续对t的操作而发生改变
return
for i in nums:
if i in t:
continue
t.append(i)
search(nums, t, res)
t.pop()
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
search(nums, [], res)
return res
给定一个方形的图像,顺时针旋转90,要求in-place。
解题思路:先上下翻转,然后转置。如果要逆时针旋转的话,只需先左右翻转即可。
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
matrix.reverse()#如果这里不能reverse,可以直接循环求解
n = len(matrix)
for i in range(n):
for j in range(i+1, n):
t = matrix[i][j]
matrix[i][j] = matrix[j][i]
matrix[j][i] = t
PS:python有个trick,discussion里面提到的,用切片可以一步解决(对于非方阵,依旧有效)
def rotate(self, matrix):
matrix[::] = zip(*matrix[::-1])
**给定一个包含str的list,返回一个list,这个list的每一个元素也是一个list,该list里面所有的单词由相同的字母组成:譬如给定[“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],返回:
[
[“ate”, “eat”,”tea”],
[“nat”,”tan”],
[“bat”]
]**。
解题思路:遍历每个str,先排序,然后用一个字典维护具有相同字母的单词有哪些。
def groupAnagrams(self, strs):
"""
:type strs: List[str]
:rtype: List[List[str]]
"""
d = {}
for i in strs:
s_i = str(sorted(i))
if s_i not in d:
d[s_i] =[i]
else:
d[s_i].append(i)
return d.values()
给定一个矩阵,顺时针旋转打印,由外到内,譬如给定[[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]],输出[1, 2, 3, 4, 7, 10, 9, 8, 7, 4, 5, 6]。
解题思路:给定两个点,左上角和右下角,然后按照左->右,上->下,右->左,下->上,然后左上角往右下移动,右上角往左上移动,循环以上四个打印步骤,直至定位点相遇,注意,因为可能不是方阵,所有打印的后两个步骤要进行判断是否只有一行或者一列,避免重复打印。
解题思路2:1.打印第一行,即list[0],然后从list删除list[0];2.将list逆时针旋转90度,重复1,
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
return matrix and list(matrix.pop(0)) + self.spiralOrder(zip(*matrix)[::-1])
给定一个非负数的列表,每个数代表在当前位置能向前跳的最大步数,问是否能到达列表尾部。
解题思路:核心就是要考虑0的情况,有如下几种:
1. 列表长度为1,return True
2. 在列表尾碰到0,return True
3. 在中间碰到0,那么就要看0之前能迈出的最大步数是否大于2,即能否跨过这个0,如果不行就return False,如果可以就继续往前。
4. 当前位置的max_step=max(max_step-1,nums[i]),初始化为nums[0]。
def canJump(self, nums):
if len(nums) == 1:
return True
max_step = nums[0]
for i in range(len(nums)):
if nums[i] == 0 :
if i == len(nums) - 1:
return True
if max_step <2:
return False
max_step = max(max_step-1, nums[i])
return True