在这里想要总结一下,数组相关问题,比如:两个数之和、三个数之和、三个数之和最相近的数、全部子序列、组合排列问题。。。这些问题看似是一个个单独的问题,但是,却可以在很多场景下反复用到。所以,觉得很有必要将它们进行总结,以便在以后的工作中使用。
话不多说,下面就开始做。
1. 列表中多个数之和
def findnSum(nums, target, N):
# 使用递归的方式实现
def nSum(nums, target, N, result, results):
if len(nums) < N or N < 2: # 边界条件
return
if N == 2: # 两个数之和
head, end = 0, len(nums) - 1
while head < end:
s = nums[head] + nums[end]
if s < target:
head += 1
elif s > target:
end -= 1
else:
plet = [nums[head], nums[end]]
results.append(result + plet)
while head < end and nums[head] == plet[0]: head += 1
while head < end and nums[end] == plet[1]: end -= 1
else: # 使用递归将多个数降低到两个数之和求解
for i in range(0, len(nums) - N + 1):
if target < nums[i]*N or target > nums[-1]*N: # take advantages of sorted list
break
if i == 0 or i > 0 and nums[i-1] != nums[i]: # recursively reduce N
nSum(nums[i + 1:], target - nums[i], N - 1, result + [nums[i]], results)
results = []
nSum(sorted(nums), target, N, [], results)
return results
2. 求最相近的数
这种问题可以运用在下面的场景下,比如说你定外卖,有一张满20减5元的卷,你想要凑单,但是你又不想多花钱,所以你在这家餐馆最少定多少钱能满足满20减5元的卷。其实这个问题就可以转化为求一个数与列表中多个数之和最相近。
from collections import defaultdict
def findnClosest(nums, N): # N表示n个数的和
allSet = [[]]
for num in nums:
allSet.extend([num] + allSet[idx] for idx in range(len(allSet))) # 输出全部子序列
allset = [s for s in allSet if len(s) == N]
res = defaultdict(list)
for i in allset:
res[sum(i)].append(i)
result = sorted(res.items(), key=lambda x: x[0])
curr = result[0][0]
for j in range(len(result)):
if abs(result[j][0]-target) < abs(curr-target):
curr = result[j][0]
return curr
3. 列表的排列组合
使用递归方式
# 一个数组的全排列
def permute(array):
n, op = len(array), []
if n == 1:
return [array]
for i, v in enumerate(array):
for perm in permute(array[:i] + array[i+1:]): # array[:0]是一个为空的数组
op.append([v] + perm)
return op
同时,也可以使用内置的包。
list(map(list, itertools.permutations(array)))
4. 寻找数组中的值
这里使用线性搜索的方式
def linear_search_recursive(array, value):
if len(array) == 0:
return -1
index = len(array) - 1
if array[index] == value:
return index
return linear_search_recursive(array[:index], value)
未完。。。待续!