记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
分为左右 [0-left]中最大值为leftmax right中的所有值都大于leftmax则成立
如果找到nums[i]
def partitionDisjoint(nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
leftmax = nums[0]
curmax = nums[0]
left = 0
for i in range(1,n-1):
curmax = max(curmax,nums[i])
if nums[i]<leftmax:
leftmax,left = curmax,i
return left+1
BFS找到第一座岛 再利用BFS将该岛一层层往外扩 直到遇到了第二座岛截止
def shortestBridge(grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
n = len(grid)
for i in range(n):
for j in range(n):
if grid[i][j]==0:
continue
l = [(i,j)]
grid[i][j]=-1
island = []
while l:
tmp=[]
for x,y in l:
island.append((x,y))
for nx,ny in [(x+1,y),(x,y+1),(x-1,y),(x,y-1)]:
if 0<=nx<n and 0<=ny<n and grid[nx][ny]==1:
grid[nx][ny]=-1
tmp.append((nx,ny))
l = tmp
step = 0
l = island
while True:
tmp = []
print("check",l)
for x,y in l:
for nx,ny in [(x+1,y),(x,y+1),(x-1,y),(x,y-1)]:
if 0<=nx<n and 0<=ny<n and grid[nx][ny]>=0:
if grid[nx][ny]==1:
print("get",nx,ny)
return step
else:
print(nx,ny)
grid[nx][ny]=-1
tmp.append((nx,ny))
step+=1
l=tmp
presum存储前缀和 目标找到presum[j]-presum[i]>=k j>i
loc存储递增的sum坐标
例如此时在位置i loc[-1]>=presum[i]
该情况下之后的presum[j]减去presum[i]可以得到更大的值并且范围更小
所以loc[-1]无用 直接去除
def shortestSubarray(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
n = len(nums)
ans = n+1
presum = [0]
for num in nums:
presum.append(presum[-1]+num)
loc = []
for i,cur in enumerate(presum):
while loc and cur-presum[loc[0]]>=k:
ans = min(ans,i-loc[0])
loc.pop(0)
while loc and presum[loc[-1]]>=cur:
loc.pop()
loc.append(i)
if ans<n+1:
return ans
return -1
遍历数组
def arraySign(nums):
"""
:type nums: List[int]
:rtype: int
"""
ans = 1
for num in nums:
if num==0:
return 0
elif num<1:
ans*=-1
return ans
对于某位置i 考虑arr[i]对答案的贡献 需要找到数组b min(b)=arr[i]
在i位置左侧有连续l个数大于等于arr[i] ,i位置右侧有连续r个大于arr[i]
那么子数组一共有m=(l+1)(r+1)个 min(b) = arr[i]
所以i位置的数贡献了m次 marr[i]
找左侧大于等于自己的个数
右侧同样的方法 为防止重复计算 右侧严格大于自己
def sumSubarrayMins(arr):
"""
:type arr: List[int]
:rtype: int
"""
MOD = 10**9+7
ans = 0
n = len(arr)
stack = []
l = [0]*n
r = [0]*n
for i,v in enumerate(arr):
while stack and v<=arr[stack[-1]]:
stack.pop()
if stack:
l[i] = i - stack[-1]
else:
l[i] = i+1
stack.append(i)
stack = []
for i in range(n-1,-1,-1):
while stack and arr[i]<arr[stack[-1]]:
stack.pop()
if stack:
r[i] = stack[-1]-i
else:
r[i] = n-i
stack.append(i)
for i in range(n):
ans = (ans+l[i]*r[i]*arr[i])%MOD
return ans
逐一检查匹配
def countMatches(items, ruleKey, ruleValue):
"""
:type items: List[List[str]]
:type ruleKey: str
:type ruleValue: str
:rtype: int
"""
ans = 0
for t,c,n in items:
if ruleKey=="type" and ruleValue==t:
ans +=1
elif ruleKey=="color" and ruleValue==c:
ans +=1
elif ruleKey=="name" and ruleValue==n:
ans +=1
return ans
从头遍历 ans存储到现在位置为止拥有的可能排列
如果当前为字母 则将ans内所有答案后添加当前字母的小写 或 大写
如果当前为数字 则将ans内所有答案后添加当前数字
def letterCasePermutation(s):
"""
:type s: str
:rtype: List[str]
"""
ans = [""]
for c in s:
tmp = []
alpha = False
if c.isalpha():
alpha = True
for v in ans:
tmp.append(v+c)
t = c
if alpha:
if c.islower():
t = c.upper()
else:
t = c.lower()
tmp.append(v+t)
ans = tmp
return ans