1. 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其
长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"
,所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
def my_sort(s):
if not s:
return "输入不合法"
cur_len, max_len = 0, 0
tmp = []
for i in s:
if i not in tmp:
tmp.append(i)
cur_len += 1
else:
index = tmp.index(i)
tmp = tmp[index+1:]
tmp.append(i)
cur_len = len(tmp)
if max_len < cur_len:
max_len = cur_len
return max_len
print(my_sort("pwwkew"))
2 滑动窗口, 给定窗口大小,在每个窗口能出现的最大值。
[1, 2, 3, 2,1, 4, 5, 6] 窗口为3时的 输出为 [3, 3, 3, 4, 5, 6]
def maxInWindows(num, size):
# 如果数组 num 不存在,则返回 []
if not num:
return []
# 如果滑动窗口的大小大于数组的大小,或者 size 小于 0,则返回 []
if size > len(num) or size < 1:
return []
# 如果滑动窗口的大小为 1 ,则直接返回原始数组
if size == 1:
return num
# 存放最大值,次大值的数组,和存放输出结果数组的初始化
# tmp存的时索引
temp = [0]
res = []
# 对于数组中每一个元素进行判断
for i in range(len(num)):
# 判断第 i 个元素是否可以加入 temp 中
# 如果比当前最大的元素还要大,清空 temp 并把该元素放入数组
# 首先判断当前最大的元素是否过期
if i - temp[0] > size - 1:
temp.pop(0)
# 将第 i 个元素与 temp 中的值比较,将小于 i 的值都弹出
while len(temp) > 0 and num[i] >= num[temp[-1]]:
temp.pop()
# 如果现在 temp 的长度还没有达到最大规模,将元素 i 压入
if len(temp) < size - 1:
temp.append(i)
# 只有经过一个完整的窗口才保存当前的最大值
if i >= size - 1:
res.append(num[temp[0]])
return res
a = [3, 3, 3, -5, 3 ,6 ,7]
print(maxInWindows(a, 3))
路径问题
1 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
def total_ways(n, m):
tmp = [[0 for i in range(n)] for j in range(m)]
for i in range(n):
tmp[0][i] = 1
for i in range(m):
tmp[i][0] = 1
for i in range(1, n):
for j in range(1, m):
tmp[j][i] = tmp[j-1][i] + tmp[j][i-1]
return tmp[-1][-1]
2 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
输入: [ [0,0,0], [0,1,0], [0,0,0] ] 1 为障碍物 输出: 2
解法
- 如果第一个格点
obstacleGrid[0,0]
是1
,说明有障碍物,那么机器人不能做任何移动,我们返回结果0
。 - 否则,如果
obstacleGrid[0,0]
是0
,我们初始化这个值为1
然后继续算法。 - 遍历第一行,如果有一个格点初始值为
1
,说明当前节点有障碍物,没有路径可以通过,设值为0
;否则设这个值是前一个节点的值obstacleGrid[i,j] = obstacleGrid[i,j-1]
。 - 遍历第一列,如果有一个格点初始值为
1
,说明当前节点有障碍物,没有路径可以通过,设值为0
;否则设这个值是前一个节点的值obstacleGrid[i,j] = obstacleGrid[i-1,j]
。 - 现在,从
obstacleGrid[1,1]
开始遍历整个数组,如果某个格点初始不包含任何障碍物,就把值赋为上方和左侧两个格点方案数之和obstacleGrid[i,j] = obstacleGrid[i-1,j] + obstacleGrid[i,j-1]
。 - 如果这个点有障碍物,设值为
0
,这可以保证不会对后面的路径产生贡献
不太好理解,但是很简便
def uniquePathsWithObstacles(dp):
# 处理特殊情况, 就是起点和终点有障碍物
if dp[0][0] == 1 or dp[-1][-1] == 1:
return 0
m, n = len(dp), len(dp[0])
dp[0][0] = 1
# 将第一个节点设置为1
for i in range(m):
for j in range(n):
# [0,0]要特殊处理
if i == 0 and j == 0:
# 除去起点
continue
# 跳出if
# 遇到障碍物, 把它设置为0
if dp[i][j] != 0:
dp[i][j] = 0
continue
if i - 1 >= 0:
dp[i][j] += dp[i - 1][j]
if j - 1 >= 0:
dp[i][j] += dp[i][j - 1]
return dp[-1][-1]
自己的版本,相对荣誉,但是自己能理解
def uniquePathsWithObstacles(dp):
# 处理特殊情况, 就是起点和终点有障碍物
if dp[0][0] == 1 or dp[-1][-1] == 1:
return 0
m, n = len(dp), len(dp[0])
# m 是行 n 是列
dp[0][0] = 1
# 将第一个节点设置为1
for i in range(1, n):
if dp[0][i] != 1:
dp[0][i] = dp[0][i-1]
else:
dp[0][i] = 0
for i in range(1, m):
if dp[i][0] != 1:
dp[i][0] = dp[i-1][0]
else:
dp[i][0] = 0
for i in range(1, m):
for j in range(1, n):
if dp[i][j] == 1:
dp[i][j] = 0
else:
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[-1][-1]
# print(uniquePathsWithObstacles([[0,0],[1,0]]))
# print(uniquePathsWithObstacles([[0,0,0],[0,1,0],[0,0,0]]))
print(uniquePathsWithObstacles([[0,0,0,0,0],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0]]))