记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
- 11/4 633. 平方数之和
- 11/5 3222. 求出硬币游戏的赢家
- 11/6 3254. 长度为 K 的子数组的能量值 I
- 11/7 3255. 长度为 K 的子数组的能量值 II
- 11/8 3235. 判断矩形的两个角落是否可达
- 11/9 3242. 设计相邻元素求和服务
- 11/10 540. 有序数组中的单一元素
11/4 633. 平方数之和
- 正常
计算最大可能的平方数 依次减小判断- 双指针
假设a从0开始,b从最大可能数开始 如果aa+bb
小于c 那么增加a
大于c 那么减小b
def judgeSquareSum(c):
"""
:type c: int
:rtype: bool
"""
import math
n = int(math.sqrt(c))
for i in range(n,-1,-1):
tmp = c-i*i
m = int(math.sqrt(tmp))
if m*m==tmp:
return True
return False
def judgeSquareSum2(c):
"""
:type c: int
:rtype: bool
"""
import math
r = int(math.sqrt(c))
l = 0
while l<=r:
s = r*r+l*l
if s==c:
return True
elif s<c:
l+=1
else:
r-=1
return False
11/5 3222. 求出硬币游戏的赢家
115 = 75+4*10
取一次需要1个75 4个10
计算最多能取几次 如果是奇数次就是A赢 偶数次B赢
def losingPlayer(x, y):
"""
:type x: int
:type y: int
:rtype: str
"""
return "Alice" if min(x,y//4)%2 else "Bob"
11/6 3254. 长度为 K 的子数组的能量值 I
如果满足条件那么相邻的上升数值相差1
cnt统计以当前i为结尾有多少个连续上升的个数
如果个数大于等于k个那么以当前i为最后一个数可以得到满足条件的子数组
def resultsArray(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
n=len(nums)
cnt=0
ans = [-1]*(n-k+1)
for i in range(n):
if i==0 or nums[i]-nums[i-1]!=1:
cnt=1
else:
cnt+=1
if cnt>=k:
ans[i-k+1]=nums[i]
return ans
11/7 3255. 长度为 K 的子数组的能量值 II
如果满足条件那么相邻的上升数值相差1
cnt统计以当前i为结尾有多少个连续上升的个数
如果个数大于等于k个那么以当前i为最后一个数可以得到满足条件的子数组
def resultsArray(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
n=len(nums)
cnt=0
ans = [-1]*(n-k+1)
for i in range(n):
if i==0 or nums[i]-nums[i-1]!=1:
cnt=1
else:
cnt+=1
if cnt>=k:
ans[i-k+1]=nums[i]
return ans
11/8 3235. 判断矩形的两个角落是否可达
如果起点或终点在园内 不存在路径
如果园和左、上边相交 并且和右、下边相交 不存在路径
def canReachCorner(xCorner, yCorner, circles):
"""
:type xCorner: int
:type yCorner: int
:type circles: List[List[int]]
:rtype: bool
"""
def incircle(px,py,x,y,r):
return (x-px)**2+(y-py)**2<=r**2
def topleft(x,y,r,xc,yc):
return (abs(x)<=r and 0<=y<=yc)or(0<=x<=xc and abs(y-yc)<=r)or(incircle(x, y, 0, yc, r))
def bottomright(x,y,r,xc,yc):
return (abs(y)<=r and 0<=x<=xc)or(0<=y<=yc and abs(x-xc)<=r)or(incircle(x, y, xc, 0, r))
def circleincircle(x1,y1,r1,x2,y2,r2,xc,yc):
return (x1 - x2) ** 2 + (y1 - y2) ** 2 <= (r1 + r2) ** 2 and x1 * r2 + x2 * r1 < (r1 + r2) * xCorner and y1 * r2 + y2 * r1 < (r1 + r2) * yCorner
n=len(circles)
visited=[False]*n
def dfs(i):
x1,y1,r1=circles[i]
if bottomright(x1, y1, r1, xCorner, yCorner):
return True
visited[i]=True
for j,(x2,y2,r2) in enumerate(circles):
if (not visited[j]) and circleincircle(x1, y1, r1, x2, y2, r2, xCorner, yCorner) and dfs(j):
return True
return False
for i,(x,y,r) in enumerate(circles):
if incircle(0, 0, x, y, r) or incircle(xCorner, yCorner, x, y, r):
return False
if (not visited[i]) and topleft(x, y, r, xCorner, yCorner) and dfs(i):
return False
return True
11/9 3242. 设计相邻元素求和服务
记录每个value的位置
class NeighborSum(object):
def __init__(self, grid):
"""
:type grid: List[List[int]]
"""
self.n=len(grid)
self.grid=grid
self.m = {}
for i in range(self.n):
for j in range(self.n):
self.m[grid[i][j]]=(i,j)
def adjacentSum(self, value):
"""
:type value: int
:rtype: int
"""
i,j = self.m[value]
ans = 0
if i-1>=0:
ans+=self.grid[i-1][j]
if i+1<self.n:
ans+=self.grid[i+1][j]
if j-1>=0:
ans+=self.grid[i][j-1]
if j+1<self.n:
ans+=self.grid[i][j+1]
return ans
def diagonalSum(self, value):
"""
:type value: int
:rtype: int
"""
i,j = self.m[value]
ans = 0
if i-1>=0 and j-1>=0:
ans+=self.grid[i-1][j-1]
if i+1<self.n and j+1<self.n:
ans+=self.grid[i+1][j+1]
if i+1<self.n and j-1>=0:
ans+=self.grid[i+1][j-1]
if i-1>=0 and j+1<self.n:
ans+=self.grid[i-1][j+1]
return ans
11/10 540. 有序数组中的单一元素
在单一元素前 元素成对出现
偶数位和偶数位+1元素相同 单一元素位置为偶数
单一元素后 元素成对出现 偶数位和偶数位-1元素相同
二分查找偶数位元素
def singleNonDuplicate(nums):
"""
:type nums: List[int]
:rtype: int
"""
l,r = 0,len(nums)-1
while l<r:
mid = (l+r)//2
if mid%2==1:
mid-=1
if nums[mid]==nums[mid+1]:
l = mid+2
else:
r = mid
return nums[l]