记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
839. Similar String Groups 相似字符串组
similar用来判断两个单词是否相似
1.DFS
挑选一个找到所有与他相似的词 取出
再在相似词中取出一个 重复 直到无法再取出 则已经没有单词可以进入这个集合
2.并查集
将相似的放进一个集合中
def similar(a,b):
dif = 0
l=len(a)
for i in range(l):
if a[i]!=b[i]:
dif+=1
if dif>2:
return False
return True
def numSimilarGroups(A):
"""
:type A: List[str]
:rtype: int
"""
aset = set(A)
res=0
while aset:
st = aset.pop()
res+=1
q = [st]
while q:
s = q.pop(0)
tmp = aset.copy()
while tmp:
i = tmp.pop()
if similar(s,i):
aset.remove(i)
q.append(i)
return res
def numSimilarGroups2(A):
"""
:type A: List[str]
:rtype: int
"""
def find(node):
if parent[node]!=node:
parent[node] = find(parent[node])
return parent[node]
def union(x,y):
parent[find(x)]=find(y)
A=list(set(A))
parent = {x:x for x in A}
for i in range(len(A)):
for j in range(i+1,len(A)):
if similar(A[i],A[j]):
union(A[i],A[j])
return len([1 for k,v in parent.items() if k==v])
854. K-Similar Strings 相似度为 K 的字符串
两个字符串从开始一次比较 若整串字符串都相等直接返回0
单个位置字符相等时跳过
直到第i个位置A[i]!=B[i]
此时我们需要在B中i后面的位置上找可以替换的位置j A[i]=B[j] (j>i)
我们使用query来储存B中能够替换的位置
这里有两种特殊情况:
1.B[j]==A[j]
这个情况下 本来j位置两个字符串是相同的 调换位置后i处相等了 但j处从相等变成了不等 这样的替换是没有意义的 所以排除
2.A[j]==B[i]
此时如果B的i,j对换 这样两个字符串的i,j两处位置都相同了 这是最理想的情况 遇到这种情况时 无序继续寻找 直接保存这个情况 退出替换
我们一次遍历query中的情况:
替换位置后A,B在i之前已经相等了 我们可以截断 将A[i+1:] B[i+1:]当做两个新的字符串考虑
def kSimilarity(A, B):
"""
:type A: str
:type B: str
:rtype: int
"""
def replace(A,B):
if ''.join(B)==A:
return 0
k = 99999
query = []
for i in range(len(A)):
if A[i]==B[i]:
continue
pos = i
best = False
find = False
for j in range(i+1,len(A)):
if B[j]!=A[i] or B[j]==A[j]:
continue
find = True
if A[j] == B[i]:
best = True
query=[]
query.append(j)
break
query.append(j)
if best or find:
break
for x in query:
B[x],B[pos] = B[pos],B[x]
k = min(k,1+replace(A[pos+1:],B[pos+1:]))
B[x],B[pos] = B[pos],B[x]
return k
928. Minimize Malware Spread II 尽量减少恶意软件的传播 II
注意是从initial中去除一个 不是所有的点
直接遍历initial中所有点 使用bfs 计算每一种情况下的感染个数 取最小的位置
def minMalwareSpread(graph, initial):
"""
:type graph: List[List[int]]
:type initial: List[int]
:rtype: int
"""
N = len(graph)
link = {}
for i in range(N):
link[i] = [x for x in range(N) if graph[i][x]==1]
res=-1
mincount= 99999
if not initial:
return 0
initial.sort()
def bfs(pos):
query = initial[:]
query.remove(pos)
visit = {x:0 for x in range(N)}
visit[pos]=1
ret = len(query)
while query:
x = query.pop(0)
for next in link[x]:
if visit[next]==0 and graph[x][next]==1:
query.append(next)
visit[next]=1
ret+=1
return ret
for i in initial:
ans = bfs(i)
if ans<mincount:
mincount = ans
res = i
return res
996. Number of Squareful Arrays 正方形数组的数目
函数sqr判断两数之和x是否是完全平方数
1.将A中各位值中两数之和为完全平方数的位置相连 构成关系图graph
如果存在某一位置不和其他相连 及没有任何一个数可以和他构成完全平方数 则该序列A没有符合条件的数组 返回0
判断起始位置:
只有单条连线的位置(只能和一个数构成完全平方数)的值必定放在开头或者结尾
如果这样的位置不是两个或者零个 那么返回0
如果是两个 则从这两个位置开始去寻找
如果是零个 那么需要从所有位置开始寻找
寻找函数 find
res保存已有的序列 pos当前的序列 g去除已使用的位置的关系图
如果res包含了所有的A内点 那么说明找到了一种排序方式
将这个结果保存到map result中 去除重复
这种方法按位置进行分析 但是有许多位置上的值其实是一样的 所以造成了时间上的浪费
2.按照数值来分析 统计每个值的出现个数 使用一个数组记录可以同对应的值构成完全平方数的数值
同样我们过滤掉无法构成完全平方数的情况
遍历每个值为开头的情况
find(value,lastnum)
value:为当前的数值
lastnum:剩余的值个数
在可以同value构成完全平方数的值的数组中遍历(i) 继续find(i,lastnum-1)
import copy
def sqr(x):
import math
if math.sqrt(x)==int(math.sqrt(x)):
return True
return False
def numSquarefulPerms(A):
"""
:type A: List[int]
:rtype: int
"""
graph = {x:[] for x in range(len(A))}
for i in range(len(A)):
for j in range(i+1,len(A)):
if sqr(A[i]+A[j]):
graph[i].append(j)
graph[j].append(i)
##查找是否有无法构成完全平方数的位置
ck = [0 for x in graph.keys() if len(graph[x])==0]
if ck:
return 0
def find(res,pos,g):
res.append(pos)
#print([A[i] for i in res],pos,g)
if len(res)==len(A):
ret = [A[i] for i in res]
result[str(ret)]=ret
if not g[pos]:
return
l={}
for i in g[pos]:
l[A[i]]=i
for i in l.values():
tmpg = copy.deepcopy(g)
for j in tmpg[pos]:
tmpg[j].remove(pos)
tmpg[pos]=[]
#print("begin:",res,i,tmpg)
find(res[:],i,tmpg)
result={}
##只能和其它一个数构成的完全平方数的位置 可以当做开始或结尾
##这样的位置只能有0或2个
start = [x for x in graph.keys() if len(graph[x])==1]
if len(start)!=2 and len(start)!=0:
return 0
if len(start)==0:
start = list(range(len(A)))
for x in start:
#print("start",x,A[x])
l = []
find(l,x,graph)
print(result.values())
return len(result)
def numSquarefulPerms2(A):
"""
:type A: List[int]
:rtype: int
"""
import collections
count = collections.Counter(A)
graph = {x:[] for x in count}
for i in count:
for j in count:
if sqr(i+j):
graph[i].append(j)
ck = [0 for x in graph.keys() if len(graph[x])==0]
if ck:
return 0
def find(value,lastnum):
count[value] -= 1
if lastnum==0:
ans = 1
else:
ans = 0
for i in graph[value]:
if count[i]:
ans += find(i,lastnum-1)
count[value] +=1
return ans
start= list(count)
res = 0
for i in start:
res += find(i,len(A)-1)
return res