LeetCode 每日一题 2022/4/4-2022/4/10

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


目录

      • 4/4 307. 区域和检索 - 数组可修改
      • 4/5 762. 二进制表示中质数个计算置位
      • 4/6 310. 最小高度树
      • 4/7 796. 旋转字符串
      • 4/8 429. N 叉树的层序遍历
      • 4/9 780. 到达终点
      • 4/10 804. 唯一摩尔斯密码词


4/4 307. 区域和检索 - 数组可修改

分段处理 对于n个数分为若干块 每块大小size 一共n//size块
初始化统计每块总和
更新index 在index//size块中
取和left在k1中第i个 right在k2中第j个
如果k1=k2 那么就是k1中[i,j]和
否则就是k1的[i,size-1] k2的[j,size-1] 加上k1+1~k2-1的所有块总和
每块大小去更号n

class NumArray(object):

    def __init__(self, nums):
        """
        :type nums: List[int]
        """
        self.nums = nums
        n = len(nums)
        self.size = int(n**0.5)
        self.sums = [0]*((n+self.size-1)//self.size)
        for index,num in enumerate(nums):
            self.sums[index//self.size] += num
        
    def update(self, index, val):
        """
        :type index: int
        :type val: int
        :rtype: None
        """
        self.sums[index//self.size]+= val-self.nums[index]
        self.nums[index] = val

    def sumRange(self, left, right):
        """
        :type left: int
        :type right: int
        :rtype: int
        """
        s = self.size
        k1,k2 = left//s,right//s
        if k1==k2:
            return sum(self.nums[left:right+1])
        else:
            return sum(self.nums[left:(k1+1)*s])+sum(self.sums[k1+1:k2])+sum(self.nums[k2*s:right+1])



4/5 762. 二进制表示中质数个计算置位

遍历每个数 统计其1的个数
位数不超过20
质数2,3,5,7,11,13,17,19

def countPrimeSetBits(left, right):
    """
    :type left: int
    :type right: int
    :rtype: int
    """
    def find(x):
        num = 0
        while x:
            if x&1==1:
                num+=1
            x = x>>1
        return num
    s = set([2,3,5,7,11,13,17,19])
    ans = 0
    for x in range(left,right+1):
        if find(x) in s:
            ans +=1
    return ans

4/6 310. 最小高度树

无向图内 MHT的根节点必定是在中间 不会是叶节点
所以将叶节点按层 一层一层去除后 留下来的必定是到所有叶节点高度最小的点 这样的点可能有两个
res记录还会存在的节点
所以可以先建立每个节点的出入度degree 如果为1 说明改点在图中属于叶节点 将会被去除 从res中取出 加入到去除列表
同时建立节点之间的连接关系图 graph记录每个节点与多少个其它节点连接
当res的个数大于2时说明还需要继续去除叶节点
获取当前层数的叶节点个数l
从去除列表中取出节点
遍历该节点连接的其他节点 并将这些节点的degree-1 若此时degree变为1了 说明这个节点变成了叶节点 同样加入到去除列表
直至res中的个数小于等于2时 留下的便是MHT的根节点

def findMinHeightTrees(n, edges):
    """
    :type n: int
    :type edges: List[List[int]]
    :rtype: List[int]
    """
    res = set([x for x in range(n)])
    if n <=2:
        return list(res)
    degree = [0] * n
    graph = [[] for x in range(n)]
    
    for [x,y] in edges:
        graph[x].append(y)
        graph[y].append(x)
        degree[x]+=1
        degree[y]+=1
        
    removelist = []
    
    for i in range(n):
        if degree[i]==1:
            removelist.append(i)
            res.remove(i)
            
    while len(res)>2:
        l = len(removelist)
        for _ in range(l):
            i = removelist.pop(0)
            for x in (graph[i]):
                degree[x] -= 1
                if degree[x]==1:
                    removelist.append(x)
                    res.remove(x)
    return list(res)

4/7 796. 旋转字符串

操作x次后 字符串变为s[x:]+s[:x]

def rotateString(s, goal):
    """
    :type s: str
    :type goal: str
    :rtype: bool
    """
    for i in range(len(s)):
        if s[i:]+s[:i]==goal:
            return True
    return False

4/8 429. N 叉树的层序遍历

BFS

class Node(object):
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
        
def levelOrder(root):
    """
    :type root: Node
    :rtype: List[List[int]]
    """
    ans = []
    if not root:
        return ans
    l = [root]
    while l:
        tmp = []
        val = []
        for node in l:
            val.append(node.val)
            tmp.extend(node.children)
        ans.append(val)
        l = tmp
    return ans

4/9 780. 到达终点

(x,y)可以转变为(x,x+y) (x+y,y) x>0 y>0
对于结果tx,ty
如果txty 那么必定没有进行过转换
如果进行过转换必定存在大小 xy
所以对于tx,ty可以倒推
满足tx>sx ty>sy tx!=ty的情况下
如果tx 每次都是大的减小的 可以直接更新tx%ty
对于 tx
sx tysy已经到达起点状态
如果 tx
sx ty!=sy tx不能减小 只能减小ty
如果 tx!=sx ty==sy ty不能减小 只能减小tx

def reachingPoints(sx, sy, tx, ty):
    """
    :type sx: int
    :type sy: int
    :type tx: int
    :type ty: int
    :rtype: bool
    """
    while tx!=ty and sx<tx and sy<ty:
        if tx>ty:
            tx %=ty
        else:
            ty %=tx
    if tx==sx and ty==sy:
        return True
    elif tx==sx:
        return ty>sy and (ty-sy)%tx==0
    elif ty==sy:
        return tx>sx and (tx-sx)%ty==0
    else:
        return False

4/10 804. 唯一摩尔斯密码词

计算每个单词摩斯密码 map存储
返回map有多少不同的key

def uniqueMorseRepresentations(words):
    """
    :type words: List[str]
    :rtype: int
    """
    morse = [".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]
    m = {}
    for word in words:
        s = ""
        for c in word:
            s += morse[ord(c)-ord("a")]
        m[s] = m.get(s,0)+1
    return len(m)

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