leetcode刷题记录961-970 python版

前言

继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,感谢各位大佬

961. 重复 N 次的元素

# 调库
class Solution:
    def repeatedNTimes(self, A: List[int]) -> int:
        from collections import Counter
        c = Counter(A)
        return c.most_common(1)[0][0]
# 一行
class Solution:
    def repeatedNTimes(self, A: List[int]) -> int:
        return (sum(A)-sum(list(set(A))))//(len(A)//2-1)

962. 最大宽度坡

class Solution:
    def maxWidthRamp(self, A: List[int]) -> int:
        stack = []
        n = len(A)
        for i in range(n):
            if not stack or A[stack[-1]] > A[i]:
                stack.append(i)
        res = 0
        i = n - 1
        while i > res:  # 当res大于等于i时没必要继续遍历了 
            while stack and A[stack[-1]] <= A[i]:
                res = max(res, i - stack[-1])
                stack.pop()
            i -= 1
        return res

963. 最小面积矩形 II

class Solution:
    def minAreaFreeRect(self, points: List[List[int]]) -> float:
        import itertools
        EPS = 1e-7
        points = set(map(tuple, points))

        res = float('inf')
        for p1, p2, p3 in itertools.permutations(points, 3):
            p4 = p2[0] + p3[0] - p1[0], p2[1] + p3[1] - p1[1]
            if p4 in points:
                v21 = complex(p2[0] - p1[0], p2[1] - p1[1])
                v31 = complex(p3[0] - p1[0], p3[1] - p1[1])
                if abs(v21.real * v31.real + v21.imag * v31.imag) < EPS:
                    area = abs(v21) * abs(v31)
                    if area < res:
                        res = area
        return res if res < float('inf') else 0

964. 表示数字的最少运算符


class Solution:
    def leastOpsExpressTarget(self, x: int, target: int) -> int:
        from functools import lru_cache
        import math
        @lru_cache(None)
        def dfs(cur):
            # 当cur < x, 比如 cur = 2, x = 3, 需要判断使用 3/3 + 3/3 和 3 - 3/3,哪个用运算符最少
            if cur < x:
                return min(2 * cur - 1, (x - cur) * 2)
            if cur == 0:
                return 0
            # 到cur 需要几个x相乘,
            p = int(math.log(cur, x))
            sums = x ** p
            # cur < sums 的情况,就是要加
            res = dfs(cur - sums) + p
            # sums > cur, 就是要减去多少才能到底目标值, 这个判断条件是有严格的数学证明的
            if sums * x - cur < cur:
                res = min(res, p + 1 + dfs(sums * x - cur))
            return res
        return dfs(target)

965. 单值二叉树

class Solution:
    def isUnivalTree(self, root: TreeNode) -> bool:
        if root == None: return True
        if root.right != None and root.val != root.right.val: return False
        if root.left != None and root.val != root.left.val: return False
        return self.isUnivalTree(root.right) and self.isUnivalTree(root.left)

966. 元音拼写检查器

class Solution:
    def spellchecker(self, wordlist: List[str], queries: List[str]) -> List[str]:
        def replace(word):
            tmp = ''
            for t in word:
                if t in 'aeiuo':
                    tmp += '*'
                else:
                    tmp += t
            return tmp

        dic = {
     }
        temp = {
     }
        wordset = set(wordlist)
        for w in wordlist:
            tmp = w.lower()
            if tmp not in dic:
                dic[tmp] = w
            tmp = replace(tmp)
            if tmp not in temp:
                temp[tmp] = w
        res = []
        for q in queries:
            if q in wordset:
                res.append(q)
                continue
            key = q.lower()
            if key in dic:
                res.append(dic[key])
            else:
                key = replace(key)
                if key in temp:
                    res.append(temp[key])
                else:
                    res.append("")
        return res

967. 连续差相同的数字

class Solution:
    def numsSameConsecDiff(self, n: int, k: int) -> List[int]:
        if n == 1: return list(range(10))
        res = set()
        # 第一位
        for i in range(1, 10):
            if 0 <= i - k <= 9 or 0 <= i + k <= 9:
                res.add(str(i))
        # 后面
        for i in range(1, n):
            next_step = set()
            for tmp in res:
                num = int(tmp[-1])
                if 0 <= num + k <= 9:
                    next_step.add(tmp + str(num + k))
                if 0 <= num - k <= 9:
                    next_step.add(tmp + str(num - k))
            res = next_step
        return list(map(int, res))

968. 监控二叉树

# 看到一个很秀的做法
class Solution:
    def minCameraCover(self, root: TreeNode) -> int:
        def solve(node):
            if not node: return 0, 0, float('inf')
            L = solve(node.left)
            R = solve(node.right)
            '''
            dp0代表当前节点未被覆盖(可能是父节点为支配集里面的点,覆盖了当前节点)但该节点的子节点都被覆盖   时所需要的最小摄像头的数量
            dp1代表当前节点的子节点中有一个或者两个(图论里可以是多个)为支配集里面的点,所以把当前的点也覆盖了  时所需要的最小摄像头的数量
            dp2代表当前节点为支配集里面的点   时所需要的最小摄像头的数量
            '''
            dp0 = L[1] + R[1] # 若想让此节点不被覆盖 但是子节点都被覆盖,则左右两个节点都要满足条件1,此节点等于左右节点dp1之和
            dp1 = min(L[2] + min(R[1:]), R[2] + min(L[1:])) # 若想让当前节点满足条件1 有两种情况:1.左节点覆盖住了此节点,此时右节点要想满足全覆盖也有两种情况(dp1 and dp2,取最小值即可)2. 右节点覆盖住了此节点,此时左节点要想满足全覆盖也有两种情况(dp1 and dp2,取最小值即可)
            dp2 = 1 + min(L) + min(R) # 若想让当前节点满足条件2,此时左右节点都被此节点覆盖,所以左右节点可以选取任意一种状态
            return dp0, dp1, dp2
        return min(solve(root)[1:])

969. 煎饼排序

class Solution:
    def pancakeSort(self, A: List[int]) -> List[int]:
        res = []
        n = len(A)
        for i in range(n, 1, -1):
            idx = A.index(i)
            A = A[-1:idx:-1] + A[:idx]
            res += [idx+1, i]
        return res

970. 强整数

class Solution:
    def powerfulIntegers(self, x: int, y: int, bound: int) -> List[int]:
        res=set()
        for i in range(32):
            for j in range(32):
                if x**i+y**j<=bound:
                    res.add(x**i+y**j)
        res=list(res)
        return res

你可能感兴趣的:(leetcode,python,leetcode)