(1)LC300:最长上升子序列【【LeetCode】最长上升子序列 python ★★★★★★_yingzoe的博客-CSDN博客_最长上升子序列python】
(2)LC673:最长递增子序列个数
(3)LC167改造:two_sum(有序数组,输出所有组合):设计一个算法找到数组中两个元素相加等于指定数的所有组合_jia635的专栏-CSDN博客_找出数组里面任意两个数相加等于某个k值的组合
#两数之和 升序数组【多组答案,要求有序】
def solve(arr,target):
i = 0
j = len(arr) - 1
res = []
while i < j:
if arr[i] + arr[j] == target:
res.append([i+1,j+1])
i += 1
j -= 1
elif arr[i] + arr[j] < target:
i += 1
else:
j -= 1
return res
(4)LC15:three_sum(有序数组):力扣
def threeSum(arr):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
arr.sort()
if not arr:
return []
if arr[0] > 0: #注意不能取等号 有[0,0,0]情况
return []
n = len(arr)
res = []
for i in range(n):
if i > 0 and arr[i] == arr[i-1]:
continue
# first = arr[i]
second = i+1
third = n-1
while second < third:
if arr[i] + arr[second] + arr[third] == 0:
res.append([arr[i],arr[second],arr[third]])
while second < third and arr[second] == arr[second+1]:
second += 1
while second < third and arr[third] == arr[third-1]:
third -= 1
second += 1
third -= 1
elif arr[i] + arr[second] + arr[third] < 0:
second += 1
else:
third -= 1
return res
(5)青蛙上台阶
def solve(n):
if n < 2:
return 1
f1 = 1
f2 = 1
for i in range(2,n+1):
fn = f1 + f2
f1 = f2
f2 = fn
return fn % 1000000007
(6)只出现一次的数字【力扣】
#20201210
(1)旋转数组找最小值
(2)旋转数组找指定值【力扣】
def solve(data,target):
left = 0
right = len(data) - 1
while left <= right:
mid = (left + right) // 2
if data[mid] == target:
return mid
if data[0] <= data[mid]:#左边是有序数组
if data[left] <= target < data[mid]:
right -= 1
else:
left += 1
else:
if data[mid] < target <= data[len(data)-1]:
left += 1
else:
right -= 1
return -1
#20201219
(1)股票最佳时机(一次)【力扣】
(2)股票最佳时机(多次)【力扣】
#20201220
(1)LC200:岛屿数量【力扣】
#深度优先
def solve(arr):
row = len(arr)
if row == 0:
return 0
col = len(arr[0])
res = 0 #记录岛屿数量
for i in range(row):
for j in range(col):
if arr[i][j] == '1':
res += 1
dfs(arr,i,j)
return res
def dfs(arr,x,y):
arr[x][y] = '0'
row, col = len(arr), len(arr[0])
for i, j in [(x-1,y),(x,y-1),(x,y+1),(x+1,y)]:
if 0 <= i and i < row and 0 <= j and j < col and arr[i][j] == '1':
dfs(arr,i,j)
#广度优先
from collections import deque
def solve(arr):
row = len(arr)
if row == 0:
return 0
col = len(arr[0])
res = 0
for i in range(row):
for j in range(col):
if arr[i][j] == '1':
res += 1
deque_list = deque([(i,j)])
while deque_list:
col_x, col_y = deque_list.popleft()
for x, y in [(col_x-1,col_y),(col_x,col_y-1),(col_x+1,col_y),(col_x,col_y+1)]:
if x >= 0 and x < row and y >= 0 and y< col and arr[x][y] == '1':
deque_list.append((x,y))
arr[x][y] = 0
return res
(2)两数之和
def solve(data,target):
res = {}
for i in range(len(data)):
if target - data[i] in res:
return [i,res[target-data[i]]]
else:
res[data[i]] = i
return -1
(3)三数之和
def solve(data):
data.sort()
n = len(data)
res = []
if data[0] > 0:
return res
for i in range(n):
if i > 0 and data[i] == data[i-1]:
continue#第一个指针的初始位置,跳过重复值
left = i + 1
right = n-1
while left < right:
if data[i] + data[left] + data[right] == 0:
res.append([data[i],data[left],data[right]])
while left < right and data[left] == data[left+1]:
left += 1
while left < right and data[right] == data[right-1]:
right -= 1
left += 1
right -= 1
elif data[i] + data[left] + data[right] > 0:
right -= 1
else:
left += 1
return res
#20200106
(1)二维有序数组找target
(2)K路归并
#20200107
(1)第K大的数
#20200108
(1)最长公共子串
(2)最小的K个数
(3)最长回文子串【LC5】
(4)全排列【LC46】
(5)二叉树最近公共祖先【LC236】
(6)二叉树层序遍历
(7)二叉树序列化、反序列化
(8)二叉树上和为target的最长路径
(9)翻转链表中偶数位置的值
(10)从K个整数中组合出被3整除的最大数【LC1363】
#20210109 MicroSoft
(0)二叉树定义
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
(0-1)ListNode定义
class ListNode:
def __init__(self,val=0,next=None):
self.val = val
self.next = next
(1)LC208:字典树实现
(2)LC705、LC706:哈希表实现
(3)LC8:字符串转换整数(atoi)
#atoi【自动状态机】
'''
['', +/-, number, other]
start: [start,signed,in_number,end]
signed: [end,end,in_number,end]
in_number: [end,end,in_number,end]
end: [end,end,end,end]
'''
MAX = 2 ** 31 - 1
MIN = -2 ** 31
# print(MAX)
class Automation:
def __init__(self):
self.state = 'start'
self.sign = 1
self.ans = 0
self.table = {
'start':['start','signed','in_number','end'],
'signed':['end','end','in_number','end'],
'in_number':['end','end','in_number','end'],
'end':['end','end','end','end']
}
def get_col(self,c):
if c.isspace():
return 0
if c == '+' or c == '-':
return 1
if c.isdigit():
return 2
return 3
def get(self,c):
self.state = self.table[self.state][self.get_col(c)]
if self.state == 'in_number':
self.ans = self.ans * 10 + int(c)
# print(min(self.ans,MAX))
self.ans = min(self.ans,MAX) if self.sign == 1 else min(self.ans,-MIN)
elif self.state == 'signed':
self.sign = 1 if c == '+' else -1
class Solution:
def myAtoi(self,string):
automation = Automation()
for s in string:
automation.get(s)
# print(automation.ans)
return automation.sign * automation.ans
(4)LC297:二叉树序列化、反序列化
#深度优先
class Codec:
def serialize(self,root):
res = []
def dfs(node):
if node:
res.append(str(node.val))#注意字符转化
dfs(node.left)
dfs(node.right)
else:
res.append('null')
dfs(root)
return '[' + ','.join(res) +']'
def deserialize(self,data):
vals = data[1:-1].split(',')
def dfs():
first = vals.pop(0)
if first == 'null':
return None
else:
node = TreeNode(int(first))
node.left = dfs()
node.right = dfs()
return node
return dfs()
#广度优先
from collections import deque
class Codec:
def serialize(self,root):
if not root:
return '[]'
quene = deque([root])
res = []
while quene:
node = quene.popleft()
if not node:
res.append('null')
else:
res.append(str(node.val))
quene.append(node.left)
quene.append(node.right)
return '[' + ','.join(res) + ']'
def deserialize(self,data):
if data == '[]':
return None
vals = data[1:-1].split(',')
root = TreeNode(int(vals[0]))
quene = deque([root])
i = 1
while quene:
node = quene.popleft()
if vals[i] != 'null':
node.left = TreeNode(int(vals[i]))
quene.append(node.left)
i += 1
if vals[i] != 'null':
node.right = TreeNode(int(vals[i]))
quene.append(node.right)
i += 1
return root
(5)LC295:数据流中位数
(6)LC33:旋转数组找指定值
(7)LC53:最大子数组和
(8)前序、中序、后序二叉树,怎么恢复
(9)LC215:第K大的元素
#第K大的数
#快排
def quickSort(arr,start,end):
low = start
high = end
base = arr[start]
while low < high:
while low < high and arr[high] >= base:
high -= 1
arr[low] = arr[high]
while low < high and arr[low] < base:
low += 1
arr[high] = arr[low]
arr[low] = base
# quickSort(arr,start,low-1)
return low
def findKthLargest(arr,k):
k = len(arr) - k
start = 0
end = len(arr) - 1
while True:
loc = quickSort(arr,start,end)
if loc == k:
return arr[loc]
elif loc < k:
start = loc + 1
else:
end = loc - 1
(9-0)剑指offer 40:最小的K个数
#最小的K个数
#堆 自己实现大顶堆
# 若是找最大的K个数 使用小顶堆 每次把最小的数排出去
# 复杂度 nlog(k)
def getLeastNumbers(arr,k):
if k == 0:
return []
data = arr[:k]
build_heap(data,len(data)) ##实现
for each in arr[k:]:
if data[0] > each:
data[0] = each
heapify(data,len(data),0)
return data
def build_heap(arr,n):
i = n // 2
while i >= 0:
heapify(arr,n,i)
i -= 1
def heapify(arr,n,i):
left = 2 * i
right = 2 * i + 1
largest = i
if left < n and arr[left] > arr[i]:
largest = left
if right < n and arr[right] > arr[largest]:
largest = right
if largest != i:
arr[i],arr[largest] = arr[largest],arr[i]
heapify(arr,n,largest)
# 快排实现 复杂度期望O(n)
def quickSort_kernel(lst, start, end):
# if start > end:
# return
base = lst[start]
low = start
high = end
while low < high:
while low < high and lst[high] >= base: # 若是最大的改这里
high -= 1
lst[low] = lst[high]
while low < high and lst[low] <= base: # 若是最大的改这里
low += 1
lst[high] = lst[low]
lst[low] = base
return low
def solve(lst, k):
start = 0
end = len(lst) - 1
loc = quickSort_kernel(lst, start, end)
while loc != k:
if loc > k - 1:
end = loc - 1
else:
start = loc + 1
loc = quickSort_kernel(lst, start, end)
return lst[:k]
(10)LC131:分割回文串
(11)汉字数字转数字【Python将汉字数字转换成阿拉伯数字的方法_yusisc的博客-CSDN博客_python中文数字转阿拉伯数字】
(12)LC102:二叉树层序遍历
#深度优先
def levelOrder(root):
if not root:
return []
res = []
def dfs(index,r):
if len(res) < index:
res.append([])
res[index-1].append(r.val)
if r.left:
dfs(index+1,r.left)
if r.right:
dfs(index+1,r.right)
dfs(1,root)
return res
#广度优先
def levelOrder(root):
if not root:
return []
quene = [root]
res = []
while quene:
tmp = []
for _ in range(len(quene)):
node = quene.pop(0)
tmp.append(node.val)
if node.left:
quene.append(node.left)
if node.right:
quene.append(node.right)
# else:
# tmp.append('null')
res.append(tmp)
return res
(13)LC103:二叉树之字形层序遍历
(14)LC560:和为K的子数组数量
(15)LC34:排序数组中元素第一个和最后一个位置
(16)LC155:最小栈
(17)LC232:栈实现队列
(18)LC225:队列实现栈
(19)LC450:二叉搜索树删除
(20)LC137:只出现一次数字(其余数字出现三次)
(21)LC4:两个有序数组中位数
(22)长度为N的环 走K步 从原点到原点【【面试题】一个环,有n个点, 问从0点出发,经过k步回到原点有多少种方法_苏学算法的博客-CSDN博客】
(23)LC852:山脉数组峰顶索引
def solve(arr):
low = 0
high = len(arr) - 1
while low < high:
mid = (low + high) // 2
if arr[mid] < arr[mid+1]:
low = mid + 1
else:
high = mid
return low
(24-0)LC21:2路归并
#二路归并
#递归
def mergeTwoLists(arr1,arr2):
if arr1 is None:
return arr2
elif arr2 is None:
return arr1
elif arr1.val < arr2.val:
arr1.next = mergeTwoLists(arr1.next,arr2)
return arr1
else:
arr2.next = mergeTwoLists(arr1,arr2.next)
return arr2
#迭代
def mergeTwoLists(arr1,arr2):
prehead = ListNode(-1)
prev = prehead
while arr1 and arr2:
if arr1.val < arr2.val:
prev.next = arr1
arr1 = arr1.next
else:
prev.next = arr2
arr2 = arr2.next
prev = prev.next
prev.next = arr2 if arr1 is None else arr1
return prehead.next
(24)LC23:k路归并
#K路归并
#heap
def mergeKLists(arr):
import heapq
if not arr:
return None
dummy = ListNode(-1)
p = dummy
head = []
for i in range(len(arr)):#push每个链表第一个数
if arr[i]:
heapq.heappush(head,(arr[i].val,i))
arr[i] = arr[i].next
while head:
val, idx = heapq.heappop(head)
p.next = ListNode(val)
p = p.next
if arr[idx]:
heapq.heappush(head,(arr[idx].val,idx))
arr[idx] = arr[idx].next
return dummy.next
#k路归并
#分治
def mergeKLists(arr):
if not arr:
return None
def split(start,end):
if start == end:
return arr[start]
mid = start + (end - start) / 2
left = split(start,mid)
right = split(mid+1,end)
return merge(left,right)
def merge(a,b):
prev = ListNode(0)
prehead = prev
while a and b:
if a.val < b.val:
prehead.next = a
a = a.next
else:
prehead.next = b
b = b.next
prehead = prehead.next
prehead.next = b if a is None else a
return prev.next
return split(0,len(arr)-1)
(25)LC516:回文子序列
(26)LC240:搜索二维矩阵
#二维数组查找
def searchMatrix(arr,target):
if not arr:
return False
for i in range(min(len(arr),len(arr[0]))):
vertical = find(arr,target,i,True)
horizon = find(arr,target,i,False)
if vertical or horizon:
return True
return False
def find(arr,target,start,flag):
low = start
high = len(arr[0])-1 if flag else len(arr)-1
while low <= high:
mid = (low + high) // 2
if flag:
if arr[start][mid] < target:
low = mid + 1
elif arr[start][mid] > target:
high = mid - 1
else:
return True
else:
if arr[mid][start] < target:
low = mid + 1
elif arr[mid][start] > target:
high = mid - 1
else:
return True
return False
(27)LC141:环形链表
#环形链表
#记录元素
def hasCycle(head):
res = set()
while head:
if head in res:
return True
res.add(head)
head = head.next
return False
#环形链表
#快慢指针
def hasCycle(head):
if not head or not head.next:
return False
slow = head
fast = head.next
while slow != fast:
if not fast or not fast.next:
return False
slow = slow.next
fast = fast.next.next
return True
#20200110
(1)LC228:汇总区间
#蓄水池抽样
def summaryRanges(arr):
n = 0
res = []
while n < len(arr):
if n + 1 < len(arr) and arr[n] + 1 == arr[n+1]:
m = n
while n + 1 < len(arr) and arr[n] + 1 == arr[n+1]:
n += 1
res.append('{}->{}'.format(arr[m],arr[n]))
else:
res.append(str(arr[n]))
n += 1
return res
#20210111
(1)LC46:所有排列
#全排列
def solve(arr):
res = []
n = len(arr)
def back(first):
if first == n:
res.append(arr[:])
for i in range(first,n):
arr[first],arr[i] = arr[i],arr[first]
back(first + 1)
arr[first],arr[i] = arr[i],arr[first]
back(0)
return res
(2)LC674:最长连续递增序列
def findLengthOfLCIS(arr):
if len(arr) < 2:
return len(arr)
j = 1
res = 0
for i in range(len(arr)-1):
if arr[i+1] > arr[i]:
j += 1
else:
j = 1
res = max(res,j)
return res
#20210111 SOUHU
(1)LC74:搜索二维数组
def solve(arr,target):
m = len(arr)
if m == 0:
return False
n = len(arr[0])
left,right = 0, m * n -1
while left <= right:
mid = (left + right) // 2
element = arr[mid // n][mid % n]
if target == element:
return True
elif target < element:
right = mid - 1
else:
left = mid + 1
return False
(2)剑指offer 07:重建二叉树
def solve(preorder,inorder):
dic = {inorder[i]:i for i in range(len(inorder))}
def back(root,left,right):
if left > right:
return
node = TreeNode(preorder[root])
i = dic[preorder[root]]
node.left = back(root+1,left,i-1)
node.right = back(i-left+root+1,i+1,right)
return node
return back(0,0,len(inorder)-1)
#20210112
(1)LC325:和为target的最长子数组长度
#和为k的最长子数组长度
def solve(arr,target):
if not arr:
return 0
dic = {}
# dic[0] = -1
res = 0
sums = 0
for i in range(len(arr)):
sums += arr[i]
if sums == target:
res = i + 1
elif sums - target in dic:
res = max(i - dic[sums - target], res)
else:
dic[sums] = i
return res
(2)LC4:两个正序数组的中位数
#两个数组的中位数
def solve(arr1,arr2):
def findK(k):
index1 = 0
index2 = 0
while True:
if m == index1:
return arr2[index2+k-1]
if n == index2:
return arr1[index1+k-1]
if k == 1:
return min(arr1[index1],arr2[index2])
newIndex1 = min(index1+k // 2-1,m-1)
newIndex2 = min(index2+k // 2-1,n-1)
base1 = arr1[newIndex1]
base2 = arr2[newIndex2]
if base1 <= base2:
k -= newIndex1 - index1 + 1
index1 = newIndex1 + 1
else:
k -= newIndex2 - index2 + 1
index2 = newIndex2 + 1
m = len(arr1)
n = len(arr2)
if (m + n) % 2 == 1:
return findK((m+n+1)//2)
else:
return 0.5 * (findK((m+n)//2) + findK((m+n)//2+1))
(3)多个有序数组合并【合并k个有序数组 - tanshoudong - 博客园】
(4)合并两个有序数组
def solve(nums1,m,nums2,n):
p1 = m - 1
p2 = 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 -= 1
nums1[:p2+1] = nums2[:p2+1]
# return nums1
(5)单链表翻转
#反转链表
def solve(head):
pre = None
cur = head
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
#20210114
(1)蓄水池抽样【[总结]随机抽样与蓄水池抽样问题 - Jamest - 博客园】
#20210121
(1)LC337:打家劫舍(树形动态规划)
#打家劫舍
def solve(root):
tmp = find(root)
return max(tmp[0], tmp[1])
def find(root):
if not root:
return [0,0]
left = find(root.left)
right = find(root.right)
tou = root.val + left[1] + right[1]
butou = max(left[0], left[1]) + max(right[0], right[1])
return [tou, butou]
(2)LC198:打家劫舍(动态规划)
def solve(arr):
if not arr:
return 0
n = len(arr)
if n == 1:
return arr[0]
dp = [0] * n
dp[0] = arr[0]
dp[1] = max(arr[0], arr[1])
for i in range(2,n):
dp[i] = max(dp[i-1], dp[i-2]+arr[i])
return dp[n-1]
#20210124
(1)数组中和为target的全部组合
#20210131
(1)剪绳子1:剑指14-1