python data structure to achieve (seven)
- 1 back
- 1.1 python use of backtracking algorithm to solve the eight queens problem
- 1.2 python use of backtracking algorithm to solve 0-1 knapsack problem
- 2 minutes Osamu
- 3 Dynamic Programming
- 3.1 python dynamic programming 0-1 knapsack problem
- 3.2 python achieve and solve the minimum path
- 3.3 python achieve the shortest Levenshtein edit distance
- Longest common subsequence 3.4 python implementation looks for two strings
- 3.5 python implement a data sequence of the longest increasing subsequence
- 4 LeetCode related exercises
1 back
1.1 python use of backtracking algorithm to solve the eight queens problem
'''
利用回溯算法求解八皇后问题
'''
class FindQueen:
def __init__(self):
self.total = 0 # 八皇后解的个数
self.table = [[0 for i in range(8)] for i in range(8)] # 8 x 8 的棋盘
def findQueen(self, row):
if row > 7: # 八皇后问题有解了(已经排到了第9行)
self.total += 1
self.printQueen()
return
for coloumn in range(8):
if self.check(row, coloumn):
self.table[row][coloumn] = 1
self.findQueen(row+1)
self.table[row][coloumn] = 0 # 每趟递归退出后都需将这趟递归每行置1的位置清零
def check(self, row, col):
for n in range(8): # 检查行列两个方向的有效性
if self.table[n][col] or self.table[row][n]:
return False
# 检查左对角线
lf = [self.table[row+i][col+j] for i,j in zip(range(-7,8),range(7,-8,-1)) \
if 0 <= row+i < 8 and 0 <= col+j < 8 and self.table[row+i][col+j]==1]
if len(lf):
return False
# 检查右对角线
rt = [self.table[row+i][col+j] for i,j in zip(range(-7,8),range(-7,8)) \
if 0 <= row+i < 8 and 0 <= col+j < 8 and self.table[row+i][col+j]==1]
if len(rt):
return False
return True
def printQueen(self):
for val in self.table:
print(val)
print('\n')
solutions = FindQueen()
solutions.findQueen(0)
print(solutions.total)
1.2 python use of backtracking algorithm to solve 0-1 knapsack problem
def bag01(N, V, C, W):
'''
:param N:N件物品
:param V:Value数组,对应每件物品的价值
:param C:Capacity,指背包的最大容量
:param W:Weight数组,对应每件物品的重量
'''
bestResult = [0] * N; curResult = [0] * N
curCost = 0; curValue = 0; bestValue = 0
def backtracking(depth):
nonlocal curCost,curValue,bestValue
if depth > N-1:
if curValue > bestValue:
bestValue = curValue
bestResult[:] = curResult[:]
print(bestResult)
print(bestValue)
else:
for i in [0, 1]: # 取或不取这件物品
curResult[depth] = i
if i == 0: # 不取这件物品
backtracking(depth+1)
else:
if curCost + W[depth] <= C:
curCost += W[depth]
curValue += V[depth]
backtracking(depth+1)
# 往上回溯,恢复现场
curCost -= W[depth]
curValue -= V[depth]
backtracking(0)
return bestResult, bestValue
bag01(4,[1500,3000,2000,1000],4,[1,4,3,0.5])
=================================================
([1, 0, 1, 0], 3500)
2 minutes Osamu
2.1 python using a divide and conquer algorithm for the set of data on the number of reverse
'''
利用归并排序的思想,在归并排序的过程中找到各个逆序对输出即可
'''
count = 0
def mergeSort(array1, low, high):
array2 = [None] * 100
if low == high:
return
else:
mid = (low + high) // 2
mergeSort(array1, low, mid)
mergeSort(array1, mid+1, high)
merge(array1, array2, low, mid, high)
array1[low:high+1] = array2[low:high+1] # 恢复原数组
def merge(a1, a2, low, mid, high):
i = low; j = mid+1; k = i; global count
while i <= mid and j <= high:
if a1[i] <= a1[j]:
a2[k] = a1[i] # 保护原数组
i += 1; k += 1
else:
count += mid-i+1
for _ in range(i,mid+1):
print(a1[_],a1[j])
a2[k] = a1[j];k+=1;j+=1
while i <= mid:
a2[k] = a1[i]
k += 1; i += 1
while j <= high:
a2[k] = a1[j]
k += 1; j += 1
r =[23,13,35,6,19,50,28,38,26,17,45]
mergeSort(r, 0, 10)
print(count)
3 Dynamic Programming
3.1 python dynamic programming 0-1 knapsack problem
Description of the problem: There are n items, each item of the weight W [i], the value of C [i], only one of each item
with dp [i] [v] denotes the front i items (1 <= i < maximum value = n, 0 <= v < = V) just charged capacity v backpack that can be obtained
, there are two strategies of selection of items i:
1: i-th not placed items, then former problem into items exactly i-1 is the maximum load capacity value of v in the backpack can be obtained, i.e. DP [i-1] [v]
2: Add the i items, is converted to the problem before i the maximum value of items exactly -1 charged capacity vw [i] backpack can be obtained, i.e., dp [i-1] [vw [i]] + c [i]
can obtain the state transition equation:
We can boundary dp [0] [v] = 0 starts out recursive entire array dp, dp array i.e. corresponding to the maximum value of the optimal solution
Not optimized time complexity, whereOptimize space complexity:
- Via a state transition equation, we can see, two-dimensional arrays dp, dp [i] is to use the row data dp [i-1] is calculated per row
- Precisely, when calculating dp [I] [v], we use the data dp [i-1] [v] and the data dp [v] the left [i-1] dp [i-1] [vw [i]];
- When calculating the data dp [i + 1] line, the data dp [i-1] does not need to line up
It can be thought, we can scroll through a one-dimensional array dp By building []:
- For dp [v], before the transfer before it dp represented [i-1] [v], it is left before dp [i-1] of the left data [v], it is right before dp [I] [v] the right of the data (for dp [i + 1] [v] is calculated using), i.e., the one-dimensional array at the time dp [v] after calculating transferred through dp before transfer [v] and dp results [v] calculated from the previous data, dp [v] after repeated continuously supplied to the continued under such an article using
Thus, to state transition equation:
def bag01DP(N, C, W, V):
'''
动态规划求解01背包问题
:param N: 物品的件数
:param C: 物品的价值数组
:param W: 物品的重量数组
:param V: 背包的容量
'''
dp = [0] * (V+1) # 0 到 V
for index in range(N):
# 每行都是要将那个index对应的物品放入包中再进行计算
for v in range(V, W[index]-1, -1):
'''
这里v表示容量从W[index]到V的背包,每次减1,这是由物品重量的粒度决定的
若物品重量不全是整数,则需要调整减少的粒度大小
如物品重量有为5.5的,则每次减少的则为0.5
'''
dp[v] = max(dp[v], dp[v-W[index]]+ C[index])
return max(dp)
bag01DP(5,[4,5,2,1,3],[3,5,1,2,2],8)
================
10
3.2 python achieve and solve the minimum path
def minPathSum(grid):
sum = 0; height = len(grid); width = len(grid[0])
dp = [[0 for x in range(width)] for y in range(height)] # 注意不能使用 [[0] * width] * height,此为浅复制,不同坐标指向了同一块内存
dp[0][0] = grid[0][0]
for col in range(1,width): # 初始化第一行
dp[0][col] = dp[0][col-1] + grid[0][col]
for row in range(1,height): # 初始化第一列
dp[row][0] = dp[row-1][0] + grid[row][0]
for i in range(1,height):
for j in range(1,width):
dp[i][j] = min(dp[i-1][j]+grid[i][j],dp[i][j-1]+grid[i][j])
return dp[height-1][width-1]
3.3 python achieve the shortest Levenshtein edit distance
import numpy as np
def LevenshteinDistance(str1, str2):
'''
str1与str2的莱文斯坦最短编辑距离
'''
len1 = len(str1); len2 = len(str2)
'''
创建一个dp数组存储状态转移方程的结果
dp[i][j]中i对应str1,j对应str2
考虑到还有空串的情况,对应位置在i==0或j==0的位置,故数组下标为0 到 len1,len2
'''
dp = np.zeros((len1+1,len2+1))
# 当str1或str2为空串时,最小编辑距离即为非空串的长度,以此初始化第一行和第一列
for col in range(1,len2+1): # 初始化第一行
dp[0][col] = col
for row in range(1,len1+1): # 初始化第一列
dp[row][0] = row
for i in range(1,len1+1):
for j in range(len2+1):
k = 0 if str1[i-1] == str2[j-1] else 1 # 注意字符串中的下标比数组的下标要少1才是对应的字符位置
dp[i][j] = min(dp[i][j-1] + 1, dp[i-1][j] + 1, dp[i-1][j-1] + k)
return dp[-1][-1]
LevenshteinDistance('kitten','sitting')
======================
3.0
Longest common subsequence 3.4 python implementation looks for two strings
'''
最长公共子序列的状态转移方程为:(和最短编辑距离类似,只和左方,上方,左上方的元素有关)
①当str1[i] == str2[j]时:dp[i][j] = dp[i-1][j-1] + 1
②当str1[i] != str2[j]时:dp[i][j] = max(dp[i][j-1], dp[i-1][j])
'''
def LCS(str1, str2):
# 寻找str1和str2的最长公共子序列
len1 = len(str1); len2 = len(str2)
dp = [[0 for x in range(len2)] for y in range(len1)] # 开辟一个二维数组dp,初始全为0
dp[0][0] = 1 if str1[0] == str2[0] else 0
for col in range(1,len2):
dp[0][col] = 1 if str1[0] == str2[col] else dp[0][col-1] # 初始化第一行
for row in range(1,len1):
dp[row][0] = 1 if str1[row] == str2[0] else dp[row-1][0] # 初始化第一列
for i in range(1,len1):
for j in range(1,len2):
dp[i][j] = max(dp[i][j-1], dp[i-1][j]) if str1[i] != str2[j] else dp[i-1][j-1] + 1
return dp[-1][-1]
LCS('sitting','kittenkkg')
========================
5
3.5 python implement a data sequence of the longest increasing subsequence
def LIS(lst):
length = len(lst)
dp = [0 for _ in range(length)]
dp[0] = 1; maxdp = 1
for i in range(1, length):
for j in range(i):
if lst[j] < lst[i] and dp[j] >= dp[i]:
dp[i] = dp[j] + 1
# dp数组最大值若大于1,则它一定是通过上一条语句计算出来的
maxdp = dp[i]
return maxdp
LIS([1,3,5,2,4,6,7,8,0])
=====================
6
4 LeetCode related exercises
4.1 Letter Combinations of a Phone Number (17) (letter combinations telephone number)
When execution: 40 ms, of a Phone Number's submit Python3 defeated Letter Combinations of 99.19% of the user
memory consumption: 13 MB, beat 95.74% of the user Letter Combinations of Python3 a Phone Number's submit
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
if digits:
len1 = len(digits)
num2letter = {'2':'abc','3':'def','4':'ghi','5':'jkl','6':'mno','7':'pqrs','8':'tuv','9':'wxyz'}
set1 = num2letter[digits[0]]
result = []
def backtrack(level, str1, set1):
'''if level == len1-1:
result.append(str1)
return '''
for letter in set1:
str1 += letter
if level < len1-1:
backtrack(level+1, str1, num2letter[digits[level+1]])
if len(str1) == len1:
result.append(str1)
str1 = str1[:-1]
return result
return backtrack(0,'',num2letter[digits[0]])
return []
4.2 permutations(46)
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
result = []
def perm(nums, end):
if end == 0:
result.append(nums[:])
else:
for i in range(end+1):
nums[i], nums[end] = nums[end], nums[i]
perm(nums, end-1)
nums[i], nums[end] = nums[end], nums[i]
return result
return perm(nums, len(nums)-1)
4.3 Coin Change (change exchange)
Nature is full knapsack problem, dp [i] represents the minimum number of coins required for the amount i
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
if amount < 0:return -1
dp = [float('inf')] * (amount+1)
dp[0] = 0
for i in range(1,amount+1):
for coin in coins:
if coin <= i:
dp[i] = min(dp[i], dp[i-coin]+1) # 状态转移方程
return dp[amount] if dp[amount] != float('inf') else -1
4.4
The minimum price of the i-Record minnum days before (on the day of purchase), maxnum recorded in the best interests of the i-th day available to sell
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if prices:
len1 = len(prices)
if len1 == 1:return 0
minnum = prices[0]; maxnum = -float('inf')
for i in range(1, len1):
minnum = min(minnum, prices[i])
maxnum = max(maxnum, prices[i]-minnum)
return maxnum
return 0