leetcode 第 177 场周赛 - 答案和思路

本次没有很难的题目

第一题 5169.日期之间隔几天

https://leetcode-cn.com/conte...

实际上应该用模拟的方法计算天数。我这里使用 python 的 datetime 库直接算出来了,有点作弊嫌疑,但是能过。

import datetime
class Solution:
    def daysBetweenDates(self, date1: str, date2: str) -> int:
        d1 = datetime.datetime.strptime(date1,'%Y-%m-%d')
        d2 = datetime.datetime.strptime(date2,'%Y-%m-%d')
        return abs((d2-d1).days)

第二题 5170.验证二叉树

https://leetcode-cn.com/conte...

要保证只有一个点入度为 0,其他点入度都是 1,而且全图没有环,就是树。

为了防止 0 号点不是根,计算了所有点的入度,选取入度为 0 的为根(如果有多个入度为 0,直接返回 False)

有点入度大于 1,也返回 False。

在通过 vis 遍历,发现环也返回 False

class Solution:
    def validateBinaryTreeNodes(self, n: int, leftChild: List[int], rightChild: List[int]) -> bool:
        f = [0] * n
        def vis(i):
            if i == -1:
                return True
            if f[i] == 1:
                return False
            f[i] = 1
            return vis(leftChild[i]) and vis(rightChild[i])
        for i in leftChild:
            if i == -1: continue
            f[i] += 1
        for i in rightChild:
            if i == -1: continue
            f[i] += 1
        rt = -1
        #print(f)
        for i in range(n): 
            if f[i] == 0:
                if rt != -1:
                    return False
                rt = i
            elif f[i] > 1:
                return False
        f = [0] * n
        vis(rt)
        if sum(f) != n:
            return False
        return True

第三题 5171.最接近的因数

https://leetcode-cn.com/conte...

方法很暴力,就是 solve 函数从 sqrt(n) 到 1 判断是否能正除,能整除的第一个就是差最小的。

class Solution:
    def closestDivisors(self, num: int) -> List[int]:
        def solve(n):
            s = math.ceil(math.sqrt(n))
            for i in range(s, 1, -1):
                if n % i == 0:
                    return [i, n//i]
            return [1, n]
        ans1 = solve(num+1)
        ans2 = solve(num+2)
        if ans2[1] - ans2[0] < ans1[1] - ans1[0]:
            return ans2
        return ans1

第一次交 for i in range(s, 1, -1): 写成了 for i in range(s, 2, -1): wa 了一次

第四题 5172.形成三的最大倍数

https://leetcode-cn.com/conte...

利用小学的时候学过的一个规律,一个整数能被三整除的充要条件是这个数各位数字相加能被 3 整除。

先求各位数字和,如果能被三整除,直接从大到小组合起来就好了。

如果不能被整除,我们尝试:

  1. 从 digits 中尝试去掉一个数字,让剩余的和可以被三整除
  2. 从 digits 中尝试去掉两个数字,让剩余的和可以被三整除

不用尝试去掉三个数字了,因为不会有这种情况。

去掉的数字要尽可能小,就保证结果最大。

我代码写的太乱,又有几个细节要注意,结果 wa 了 3 次。

import collections
class Solution:
    def largestMultipleOfThree(self, digits: List[int]) -> str:
        #digits.sort()
        s = sum(digits)
        c = collections.Counter(digits)
        ds = list(c.keys())
        ds.sort()
        f = False
        if s % 3 != 0:
            if len(digits) > 1: 
                for d in ds:
                    if d % 3 == s % 3:
                        #print(d)
                        c[d] -= 1
                        f = True
                        break
                if not f and len(digits) > 2:
                    #print('here')
                    for d in ds:
                        if d != 0:
                            for dd in ds:
                                if dd != 0:
                                    if (d + dd) % 3 == s % 3:
                                        #print(d, dd)
                                        if dd != d or c[d] > 1:
                                            c[d] -= 1
                                            c[dd] -= 1
                                            f = True
                                            break
                            if f: break
        else:
            f = True
        ans = ''
        print(f)
        if f:
            zf = True
            for d in ds:
                if d != 0 and c[d] > 0:
                    zf = False
            if zf: return '0'
            for d in ds[::-1]:
                ans += str(d) * c[d]
        return ans

欢迎来我的博客: https://codeplot.top/
我的博客刷题分类:https://codeplot.top/categories/%E5%88%B7%E9%A2%98/

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