滑动窗口的最大值
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
class Solution:
def maxInWindows(self, num, size):
# write code here
res=[]
if not size or len(num)<size or not num:
return res
# 暴力解法:
for i in range(0,len(num)-size+1):
temp_arr=num[i:i+size]
max_value=temp_arr[0]
for j in temp_arr:
if j>max_value:
max_value=j
res.append(max_value)
return res
# 比较大小时不重复计算,使用队列:
'''
双向队列的方法,队列只存最大值 和依次小于最大值的元素的坐标
在队列首部存放当前最大值的坐标,如果后续加进来的元素比现在的队尾元素小,则加入
如果当前队尾的元素 比要加入的新元素小,则移除这些队尾元素
如果当前坐标i+1>=size说明 窗口已经覆盖了三个元素以上,可以拿最大值了
将队列从尾部开始小于新加入元素的元素坐标都移除,因为此时他们已经不可能是窗口最大值了
队首元素的有效期即它为最大元素的窗口,是在他的坐标index +size区间内,超过这个区间就移除掉这个当前最大值 即当前队首元素
当i+1<size时候说明窗口还没覆盖到3个元素,还没找到窗口覆盖的最大值
'''
from collections import deque
deq = deque([0])
for i in range(1,len(num)):
if i - deq[0] >= size:
deq.popleft()
if num[i] > num[deq[0]]:
deq = deque([i])
else:
while num[i] > num[deq[-1]]:
deq.pop()
deq.append(i)
if i >= size-1:
res.append(num[deq[0]])
return res
矩阵中的路径
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
# -*- coding:utf-8 -*-
class Solution:
def hasPath(self, matrix, rows, cols, path):
# write code here
for i, s in enumerate(matrix):
# 当字符串第一个字符与矩阵中元素匹配上时,开始匹配下一个,其中i//cols和i%cols是匹配到的第一个字符的行列索引值
if s==path[0] and self.visit([(i//cols, i%cols)], matrix, rows, cols, path):
return True
return False
def visit(self, ans, matrix, rows, cols, path):
# 如果ans中存储的已经匹配道德字符个数等于字符串的长度,则说明已经匹配完毕,返回True
if len(ans)==len(path):
return True
i,j = ans[-1]
# 匹配当前元素上下左右的元素是否与path下一元素相匹配
nex = [(ii,jj) for ii,jj in [(i,j-1),(i,j+1),(i-1,j),(i+1,j)]
if 0<= ii <rows and 0<= jj <cols and
(ii,jj) not in ans and
matrix[ii*cols +jj]==path[len(ans)]]
# 对于所有满足条件的元素都要分别进行下一次匹配
return sum([self.visit(ans+[x], matrix, rows, cols, path) for x in nex])
机器人的运动范围
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.res=0
def movingCount(self, threshold, rows, cols):
# write code here
# 首先将方格中所有位置赋值1
arr = [[1 for i in range(cols)] for j in range(rows)]
self.findway(arr, 0, 0, threshold)
return self.res
def findway(self, arr, i, j, k):
# 当数组行列下标超出范围时,跳出该方法
if i < 0 or j < 0 or i >= len(arr) or j >= len(arr[0]):
return
# 将行列坐标每一个数位都转化为int类型的数字,便于求和
tmpi = list(map(int, list(str(i))))
tmpj = list(map(int, list(str(j))))
if sum(tmpi) + sum(tmpj) > k or arr[i][j] != 1:
return
# 满足条件即赋值0
arr[i][j] = 0
self.res += 1
# 对上下左右进行判断
self.findway(arr, i + 1, j, k)
self.findway(arr, i - 1, j, k)
self.findway(arr, i, j + 1, k)
self.findway(arr, i, j - 1, k)
剪绳子
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
输出描述:
输出答案。
示例1
输入
8
输出
18
# -*- coding:utf-8 -*-
class Solution:
def cutRope(self, number):
# write code here
res=1
if number<=1:
return 0
elif number<=2:
return 1
elif number<=3:
return 2
# 法一:数学归纳法/贪心算法
elif number>3:
if number%3==0:
res=3**(number//3)
elif number%3==1:
res=3**(number//3-1)*4
else:
res=3**(number//3)*(number%3)
return res
# 法二:动态规划
prod=[0,1,2,3]
for i in range(4,number+1):
max=0
for j in range(1,i//2+1):
pro=prod[j]*prod[i-j]
if pro>max:
max=pro
prod.append(max)
return prod[number]