记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
2/28 1601. 最多可达成的换楼请求数目
因为requests最多只有16个
我们可以枚举所有请求情况
使用一个16位的二进制数代表取了若干个请求的情况 1代表实现请求
对每一种请求模拟后 如果满足情况 那么更新请求最大个数
def maximumRequests(n, requests):
"""
:type n: int
:type requests: List[List[int]]
:rtype: int
"""
ans = 0
m = len(requests)
def onenum(num):
one = 0
while num:
num&=(num-1)
one+=1
return one
for mask in range(1<<m):
num = onenum(mask)
if num<ans:
continue
l = [0]*n
for i,(x,y) in enumerate(requests):
if mask&(1<<i):
l[x]-=1
l[y]+=1
tag = True
for i in range(n):
if l[i]!=0:
tag = False
break
if tag:
ans = num
return ans
3/1 6. Z 字形变换
位置0开始计算
第j行 第一个数是j 间隔有两种类型 step1=2*(n-j-1) step2 = 2*j
def convert(s, numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
if numRows==1:
return s
ans = ""
num = len(s)
for j in range(numRows):
step1 = 2*(numRows-j-1)
step2 = 2*j
if step1==0 or step2==0:
step1,step2=max(step1,step2),max(step1,step2)
steps = [step1,step2]
loc = j
v = 0
while loc<num:
ans += s[loc]
loc +=steps[v%2]
v+=1
return ans
3/2 564. 寻找最近的回文数
如果位数变动 多一位最接近的肯定是100…001 少一位肯定是99…99
两种情况可以特殊考虑
如果位数不变动 为了使差值最小 肯定变动后半部分
前半部分保持不变 num=len(n) 前半部分为x=(num+1)//2位
考虑 x-1,x,x+1 三种情况即可
def nearestPalindromic(n):
"""
:type n: str
:rtype: str
"""
num = len(n)
more = 10**num+1
less = 10**(num-1)-1
ans = ""
if len(n)==1:
return str(int(n)-1)
ori = int(n)
diff = min(more-ori,ori-less)
if more-ori<ori-less:
ans = str(more)
else:
ans = str(less)
half = int(n[:(num+1)//2])
for x in range(half-1,half+2):
if num%2==0:
y = x
else:
y = x//10
while y:
x = x*10+y%10
y//=10
if x==ori:
continue
print(x,abs(x-ori),diff,ans)
if abs(x-ori)<diff or(abs(x-ori)==diff and len(ans)>len(str(x))):
diff = abs(x-ori)
ans = str(x)
return ans
3/3 258. 各位相加
模拟 取各位和
def addDigits(num):
"""
:type num: int
:rtype: int
"""
while num>9:
tmp = num
num = 0
while tmp>0:
num += tmp%10
tmp = tmp//10
return num
3/4 2104. 子数组范围和
1.暴力 遍历所有子数组
2.单调栈
作为最大值的贡献:
维护一个单调递减的栈 x,y (nums[x]>nums[y])
如果此时z位置的值大于y 需要处理y
y作为最大值的子数组个数(y-x)*(z-y)
贡献为nums[y]*个数
作为最小值的贡献 类似 只是贡献为负
def subArrayRanges(nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
ans = 0
for i in range(n-1):
maxv,minv = nums[i],nums[i]
for j in range(i+1,n):
maxv = max(maxv,nums[j])
minv = min(minv,nums[j])
ans += maxv-minv
return ans
def subArrayRanges2(nums):
"""
:type nums: List[int]
:rtype: int
"""
ans=0
stack = []
for i,num in enumerate(nums+[float('inf')]):
while stack and nums[stack[-1]]<num:
j = stack.pop()
left = stack[-1] if stack else -1
ans += nums[j]*(i-j)*(j-left)
stack.append(i)
stack = []
for i,num in enumerate(nums+[float('-inf')]):
while stack and nums[stack[-1]]>num:
j = stack.pop()
left = stack[-1] if stack else -1
ans -= nums[j]*(i-j)*(j-left)
stack.append(i)
return ans
3/5 521. 最长特殊序列 Ⅰ
如果两个字符串相等 则不存在
否则最长的字符串子序列取自身 必定不是另一个的子序列
def findLUSlength( a, b):
"""
:type a: str
:type b: str
:rtype: int
"""
if a==b:
return -1
return max(len(a),len(b))
3/6 2100. 适合打劫银行的日子
前time天非递增 后time天非递减
两个条件分开来考虑
qian[i]用来记录从前往后到位置i最长非递增长度
hou[i]用来记录从i往后最长非递减长度
def goodDaysToRobBank(security, time):
"""
:type security: List[int]
:type time: int
:rtype: List[int]
"""
n = len(security)
qian,hou = [0]*n,[0]*n
for i in range(1,n):
if security[i]<=security[i-1]:
qian[i] = qian[i-1]+1
if security[n-i-1]<=security[n-i]:
hou[n-i-1]=hou[n-i]+1
ans = []
for i in range(time,n-time):
if qian[i]>=time and hou[i]>=time:
ans.append(i)
return ans