LeetCode 每日一题 2021/9/13-2021/9/19

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步


目录

      • 9/13 447. Number of Boomerangs 回旋镖的数量
      • 9/14 524. Longest Word in Dictionary through Deleting 通过删除字母匹配到字典里最长单词
      • 9/15 162. Find Peak Element 寻找峰值
      • 9/16 212. Word Search II 单词搜索 II
      • 9/17 36. Valid Sudoku 有效的数独
      • 9/18 292. Nim Game Nim 游戏
      • 9/19 650. 2 Keys Keyboard 只有两个键的键盘


9/13 447. Number of Boomerangs 回旋镖的数量

matrix[i][j] 记录点i 点j之间的距离
遍历每一个点 相同距离的点个数
计算

def numberOfBoomerangs(points):
    """
    :type points: List[List[int]]
    :rtype: int
    """
    def dist(x,y):
        return (y[1]-x[1])**2+(y[0]-x[0])**2
    n = len(points)
    matrix = [[0]*n for _ in range(n)]
    
    for i in range(n):
        for j in range(n):
            matrix[i][j] = dist(points[i],points[j])
        
    from collections import defaultdict
    ans = 0
    for i in range(n):
        m = defaultdict(int)
        for j in range(n):
            m[matrix[i][j]]+=1
        
        for k,v in m.items():
            if v>1:
                ans += v*(v-1)
    return ans

9/14 524. Longest Word in Dictionary through Deleting 通过删除字母匹配到字典里最长单词

按字符串长度从大到小排列
在s中找子序列是否存在

def findLongestWord(s, dictionary):
    """
    :type s: str
    :type dictionary: List[str]
    :rtype: str
    """
    dictionary.sort(key=lambda x:(-len(x),x))
    def check(a,b):
        x,y = 0,0
        while x<len(a) and y<len(b):
            if a[x]==b[y]:
                y+=1
            x+=1
        return y==len(b)
    
    for word in dictionary:
        if len(word)>len(s):
            continue
        if check(s,word):
            return word
    return ""

9/15 162. Find Peak Element 寻找峰值

二分
因为边界为负无穷
只要往高坡移动 必定能找到峰值

def findPeakElement(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    l,r = 0,len(nums)-1
    while l<r:
        mid = l+((r-l)>>1)
        if nums[mid]<nums[mid+1]:
            l = mid+1
        else:
            r = mid
    return l

9/16 212. Word Search II 单词搜索 II

将单词生成字典树trie
对board中每个点进行深搜
如果找到了单词 end==1 那么添加该单词 并将end=0 防止后续多次添加
经过一个点 将[i][j]设置为# 表示该次深搜已经搜索过该点
返回时将点的值还原

def findWords(board, words):
    """
    :type board: List[List[str]]
    :type words: List[str]
    :rtype: List[str]
    """
    ret = []
    if not words:
        return ret
    trie={}
    #生成字典树
    for word in words:
        t = trie
        for w in word:
            t = t.setdefault(w,{})
        t["end"]=1
    row = len(board)
    col = len(board[0])
    
    def dfs(i,j,trie,s):
        w = board[i][j]
        if w not in trie:
            return
        trie=trie[w]
        if "end" in trie and trie["end"]==1:
            ret.append(s+w)
            trie["end"]=0 ##防止重复
        board[i][j]="#"
        for x,y in [[-1,0],[1,0],[0,1],[0,-1]]:
            tmpi = i+x
            tmpj = j+y
            if 0<=tmpi<row and 0<=tmpj<col and board[tmpi][tmpj]!="#":
                dfs(tmpi,tmpj,trie,s+w)
        board[i][j]=w
                 
    for i in range(row):
        for j in range(col):
            dfs(i,j,trie,"")
    return ret

9/17 36. Valid Sudoku 有效的数独

遍历横竖
每一个小格子

def isValidSudoku(board):
    """
    :type board: List[List[str]]
    :rtype: bool
    """
    from collections import defaultdict
    for i in range(9):
        heng,shu =defaultdict(int),defaultdict(int)
        for j in range(9):
            if heng[board[i][j]]>0:
                return False
            if shu[board[j][i]]>0:
                return False
            if board[i][j]!=".":
                heng[board[i][j]] = 1
            if board[j][i]!=".":
                shu[board[j][i]] = 1
                
    m = defaultdict(int)
    for i in range(3):
        for j in range(3):
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1
    m = defaultdict(int)
    for i in range(3):
        for j in range(3,6):
            print(board)
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1 
    m = defaultdict(int)
    for i in range(3):
        for j in range(6,9):
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1
    m = defaultdict(int)
    for i in range(3,6):
        for j in range(3):
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1
    m = defaultdict(int)
    for i in range(3,6):
        for j in range(3,6):
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1 
    m = defaultdict(int)
    for i in range(3,6):
        for j in range(6,9):
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1
    m = defaultdict(int)
    for i in range(6,9):
        for j in range(3):
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1
    m = defaultdict(int)
    for i in range(6,9):
        for j in range(3,6):
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1 
    m = defaultdict(int)
    for i in range(6,9):
        for j in range(6,9):
            if m[board[i][j]]>0:
                return False
            if board[i][j]!=".":
                m[board[i][j]]=1
    return True

9/18 292. Nim Game Nim 游戏

如果是4的倍数 先手必输 先手拿x个 后手拿4-x个 最后必定是后手拿到
否则 先手取若干个将其变成4的倍数 那么对手就变成了先手4的倍数

def canWinNim(n):
    """
    :type n: int
    :rtype: bool
    """
    return n%4!=0

9/19 650. 2 Keys Keyboard 只有两个键的键盘

分解质因数
如果是质数 则只能一个个复制粘贴
合数分解成质数 a = b*c 那么a需要b+c次操作

def minSteps(n):
    """
    :type n: int
    :rtype: int
    """
    ans = 0
    i = 2
    while i*i<=n:
        while n%i==0:
            n //=i
            ans +=i
        i+=1
    if n>1:
        ans +=n
    return ans

你可能感兴趣的:(Exercise,leetcode,算法)