记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
6/21 401. Binary Watch 二进制手表
遍历所有存在的时间可能性
查看时间内亮的灯是否是需要的灯数
def readBinaryWatch(turnedOn):
"""
:type turnedOn: int
:rtype: List[str]
"""
ret = []
for i in range(12):
for j in range(60):
if bin(i).count('1')+bin(j).count('1')==turnedOn:
ret.append(f'{i}:{j:02d}')
return ret
6/22 剑指 Offer 38. 字符串的排列
排序防止重复
def permutation(s):
"""
:type s: str
:rtype: List[str]
"""
l = list(s)
l.sort()
ret = []
def func(l,tmp):
if not l:
ret.append(tmp)
return
n = len(l)
i =0
while i<n:
c = l[i]
tmp+=c
func(l[:i]+l[i+1:],tmp)
tmp=tmp[:-1]
i+=1
while i<n and l[i]==l[i-1]:
i+=1
func(l,'')
print(ret)
return ret
6/23 剑指 Offer 15. 二进制中1的个数
1.和1与 判断最后一位
往右挪一位 循环判断
2.每次n&(n-1) 去除n最后一位1
def hammingWeight(n):
"""
:type n: int
:rtype: int
"""
res = 0
while n > 0:
res += n &1
n >>= 1
return res
def hammingWeight2(n):
"""
:type n: int
:rtype: int
"""
ans = 0
while n>0:
ans +=1
n &=(n-1)
return ans
6/24 149. Max Points on a Line 直线上最多的点数
y=kx+b
根据x轴从小到大排序
记录x相同的直线有多少点
当ans大于一半的总数目时 必定是能够连接到的最多点数
find(k,b,loc):
寻找loc之后 满足k,b的点 小数误差|diff|<1e10
kb():
计算两点连成线的k,b
双层循环 决定组成直线的最初两点
跳过x相同的点
mem记录k,b 减少重复探查
def maxPoints(points):
"""
:type points: List[List[int]]
:rtype: int
"""
points.sort(key=lambda x:x[0])
if len(points)<3:
return len(points)
n = len(points)
ans = 2
pre = 1
for p in range(1,n):
if points[p][0]==points[p-1][0]:
pre +=1
ans = max(ans,pre)
else:
pre = 1
if ans>n//2:
return ans
def find(k,b,loc):
ans = 0
ck = float('inf')
for p in points[loc:]:
x,y = p[0],p[1]
if ck==x:
continue
diff = y-k*x-b
if abs(diff)<1e-10:
ans+=1
ck=x
return ans
def kb(x1,x2,y1,y2):
k = (y2-y1)*1.0/(x2-x1)
b = y1-x1*k
return k,b
mem = {}
for i in range(n-2):
x1,y1=points[i][0],points[i][1]
for j in range(i+1,n-1):
x2,y2=points[j][0],points[j][1]
if x2==x1:
continue
k,b = kb(x1,x2,y1,y2)
if (k,b) in mem:
continue
mem[(k,b)]=1
tmp = 2+find(k,b,j+1)
ans = max(ans,tmp)
if ans > n//2:
return ans
return ans
6/25 752. Open the Lock 打开转盘锁
- 从0000开始 BFS广搜 记录旋转次数
- 双向BFS
从0000 和 target 开始分别向对方靠近
l1,l2 记录当前两方需要探索字符串
visited记录已经判断过的字符串
每次挑选较少的情况来判断 len(l1)<len(l2)
def openLock(deadends, target):
"""
:type deadends: List[str]
:type target: str
:rtype: int
"""
dead = set(deadends)
if "0000" in dead:
return -1
l = [("0000",0)]
mem ={}
while l:
s,n = l.pop(0)
if s==target:
return n
if s in mem:
continue
mem[s] = 1
for i in range(4):
for diff in [1,-1]:
ls = list(s)
v = int(ls[i])
v = (v+diff)%10
if v<0:
v+=10
ls[i] = str(v)
tmps = "".join(ls)
if tmps==target:
return n+1
if tmps in dead:
continue
l.append((tmps,n+1))
return -1
def openLock2(deadends, target):
"""
:type deadends: List[str]
:type target: str
:rtype: int
"""
visited=set()
visited.add("0000")
l1,l2 = set(),set()
l1.add("0000")
l2.add(target)
step=0
while l1 and l2:
tmpset=set()
if len(l1)>len(l2):
l1,l2=l2,l1
for s in l1:
if s in deadends:
continue
if s in l2:
return step
visited.add(s)
for i in range(4):
tmp=list(s)
if tmp[i]=='9':
tmp[i]='0'
else:
tmp[i]= str((int(tmp[i])+1))
up = ''.join(tmp)
if up not in visited:
tmpset.add(up)
tmp=list(s)
if tmp[i]=='0':
tmp[i]='9'
else:
tmp[i]= str((int(tmp[i])-1))
down = ''.join(tmp)
if down not in visited:
tmpset.add(down)
step+=1
l1 = l2
l2 = tmpset
return -1
6/26 773. Sliding Puzzle 773. 滑动谜题
与752思路一致
BFS广度优先搜索 使用双向BFS节约时间
l1,l2 分别记录从起点,终点开始的移动情况
每次移动 情况少的一方len(l1)<len(l2)
当l1,l2中有相同的状态时 代表相遇 及可从起点走到终点
def slidingPuzzle(board):
"""
:type board: List[List[int]]
:rtype: int
"""
def tag(board):
t=""
for i in range(2):
for j in range(3):
t += str(board[i][j])
return t
visited = set()
visited.add(tag(board))
l1,l2 = set(),set()
l1.add(tag(board))
l2.add("123450")
step = 0
move = [[0,1],[0,-1],[1,0],[-1,0]]
while l1 and l2:
tmpset = set()
if len(l1)>len(l2):
l1,l2=l2,l1
for bd in l1:
if bd in l2:
return step
visited.add(bd)
x,y=0,0
loc = 0
for i in range(6):
if bd[i]=="0":
loc = i
break
x = loc//3
y = loc%3
for xx,yy in move:
tmpx = x+xx
tmpy = y+yy
tmpbd = list(bd)
if -1<tmpx<2 and -1<tmpy<3:
tmploc = 3*tmpx+tmpy
tmpbd[loc],tmpbd[tmploc]=tmpbd[tmploc],tmpbd[loc]
tmpstr = ''.join(tmpbd)
if tmpstr not in visited:
tmpset.add(tmpstr)
step+=1
l1 = tmpset
return -1
6/27 909. Snakes and Ladders 蛇梯棋
将二维board拼接成一维
BFS广度优先搜索
def snakesAndLadders(board):
"""
:type board: List[List[int]]
:rtype: int
"""
n = len(board)
l = [0]
reverse = False
for i in range(n-1,-1,-1):
tmp = board[i]
if reverse:
tmp = tmp[::-1]
reverse = not reverse
l.extend(tmp)
b = [1]
mem={}
step = 0
print(l)
while b:
tmp = []
step +=1
for loc in b:
for i in range(1,7):
new = loc+i
if l[new]>-1:
new = l[new]
if new ==n*n:
return step
if new>n*n:
continue
if new in mem:
continue
tmp.append(new)
mem[new]=step
b=tmp[:]
return -1