[Leetcode Weekly Contest]177

链接:LeetCode

[Leetcode]5169. 日期之间隔几天

编写一个程序来计算两个日期之间隔了多少天。

日期以字符串形式给出,格式为 YYYY-MM-DD,如示例所示。

示例 1:
输入:date1 = "2019-06-29", date2 = "2019-06-30"
输出:1

求两个日期之间的间隔,要考虑的几个问题有:注意是否是闰年;间隔要取绝对值。我们可以分别求两个日期与1971年1月1日的间隔,然后取差即可。另外,也可以直接调用python库求解。

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

    def daysBetweenDates(self, date1: str, date2: str) -> int:
        self.month = [[0,31,28,31,30,31,30,31,31,30,31,30,31],[0,31,29,31,30,31,30,31,31,30,31,30,31]]
        self.day = [365,366]
        year1,month1,day1 = [int(x) for x in date1.split('-')]
        year2,month2,day2 = [int(x) for x in date2.split('-')]
        s1,s2 = self.gap(year1,month1,day1),self.gap(year2,month2,day2)
        return abs(s1-s2)

    def gap(self,year,month,day):
        res = 0
        flag = self.isleapyear(year)
        for i in range(1971,year):
            res += self.day[self.isleapyear(i)]
        for i in range(month):
            res += self.month[self.isleapyear(year)][i]
        res += day
        return res

    def isleapyear(self,year):
        if (year%4 == 0 and year%100!=0) or year%400==0:
            return True
        return False

[Leetcode]5170. 验证二叉树

二叉树上有n个节点,按从 0 到 n - 1 编号,其中节点 i 的两个子节点分别是leftChild[i]rightChild[i]
只有 所有 节点能够形成且 只 形成 一颗 有效的二叉树时,返回 true;否则返回 false。
如果节点i没有左子节点,那么leftChild[i]就等于1。右子节点也符合该规则。
注意:节点没有值,本问题中仅仅使用节点编号。
示例 1:
示例 1
输入:n = 4, leftChild = [1,1,3,1], rightChild = [2,1,1,1]
输出:true
示例 2:
示例 2
输入:n = 4, leftChild = [1,1,3,1], rightChild = [2,3,1,1]
输出:false
示例 3:
示例 3
输入:n = 2, leftChild = [1,0], rightChild = [1,1]
输出:false
示例 4:
示例 4
输入:n = 6, leftChild = [1,1,1,4,1,1], rightChild = [2,1,1,5,1,1]
输出:false

这一题的示例比较重要,我们可以从示例中找到很多case。对于一个二叉树,它有以下特征:

  • 一个结点最多只有另外一个结点指向它(bad case:示例 2)
  • 两个结点不能相互指向(bad case:示例 3)
  • 必须是一个连通图(bad case:示例 4)

找出这三个case,那么其他不满足的都是非二叉树。第一个条件,我们只需要遍历以下数组即可,第二个条件,我们可以通过并查集在O(N)时间复杂度判断出来,最后一个条件也可以通过并查集解决。

class Solution:
    def validateBinaryTreeNodes(self, n: int, leftChild: List[int], rightChild: List[int]) -> bool:
        children = leftChild+rightChild
        count = collections.Counter(children)
        for i in range(n):
            if count[i] > 1:
                return False

        dic = {}
        def find(p):
            while p!=dic[p]:
                p = dic[p]
            return p
        def union(p,q):
            root1,root2 = find(p),find(q)
            if root1==root2:
                return False
            else:
                dic[root1] = root2
                return True
        for i in range(n):
            dic[i] = i
        for i in range(n):
            if leftChild[i]!=-1:
                if not union(leftChild[i],i):
                    return False
            if rightChild[i]!=-1:
                if not union(rightChild[i],i):
                    return False
        root = find(0)
        for i in range(n):
            if find(i) != root:
                return False
        return True

[Leetcode]5171.最接近的因数

给你一个整数 num,请你找出同时满足下面全部要求的两个整数:
两数乘积等于  num + 1 或 num + 2
以绝对差进行度量,两数大小最接近
你可以按任意顺序返回这两个整数。

示例 1:
输入:num = 8
输出:[3,3]
解释:对于 num + 1 = 9,最接近的两个因数是 3 & 3;对于 num + 2 = 10, 最接近的两个因数是 2 & 5,因此返回 3 & 3 。

由于是查找最接近的两个因数,从平方根可以查起即可,当出现积为target,则必定是最近的两个数。并且可以将判断num+2 以及判断num+1放在一个for循环中,因为i是确定的,如果(num+1)%i==0 (num+1)/i-i肯定是小于(num+2)/i-i。

class Solution:
    def closestDivisors(self, num: int) -> List[int]:
        n1,n2 = num+1,num+2
        val = int((n2)**0.5)
        for i in reversed(range(val+1)):
            if n1%i == 0:
                return [i,n1//i]
            if n2%i == 0:
                return [i,n2//i]

[Leetcode]5172. 形成三的最大倍数

给你一个整数数组 digits,你可以通过按任意顺序连接其中某些数字来形成3的倍数,请你返回所能得到的最大的3的倍数。
由于答案可能不在整数数据类型范围内,请以字符串形式返回答案。
如果无法得到答案,请返回一个空字符串。

示例 1:
输入:digits = [8,1,9]
输出:"981"
示例 2:
输入:digits = [8,6,7,1,0]
输出:"8760"
示例 3:
输入:digits = [1]
输出:""
示例 4:
输入:digits = [0,0,0,0,0,0]
输出:"0"

这道题的关键是"3"的最大倍数,如果是一个普通的数,一般的朴素思想是dfs,但因为这里规定了是3,那么我们便可以找出3的倍数的一些特征。
首先,很明显的,对3的倍数的几个数字相加一定任然是3的倍数;并且,对于一个数而言,对3求余,只会出现0,1,2三张情况。那么我们可以得到以下结论:
如果取模3等于0,那其实可以都要,如果是1,那就得去掉一个1或者两个2,如果是2那就得去掉一个2或者两个1.而这些删掉一个数的函数其实是类似的,可以反复调用。注意在如果全是0输出0而不是00000. 而且要在删完数之后判断。并且,我们通过哈希表存储个数,最后输出的时候也不需要另外排序了,从大到小输出即可。

import collections
class Solution:
    def largestMultipleOfThree(self, digits: List[int]) -> str:
        count = collections.Counter(digits)
        sum_ = sum(digits)
        if sum_%3 == 1:
            if not self.delDigit(count,1):
                for i in range(2):
                    self.delDigit(count,2)
        if sum_%3 == 2:
            if not self.delDigit(count,2):
                for i in range(2):
                    self.delDigit(count,1)
        res = ''
        for i in reversed(range(10)):
            for _ in range(count[i]):
                res += str(i)
        if res and int(res) == 0:
            return '0'
        return res

    def delDigit(self,count,num):
        for i in range(num,10,3):
            if count[i]:
                count[i] -= 1
                return True
        return False
posted @   Jamest  阅读(168)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示