Leetcode Weekly Contest 113

做了几次leetcode的周赛,还是菜的不行,每次基本上就做3道题,偶尔在规定时间内做完了4道题。仅以此记录一下自己每次刷题的一点点思考,慢慢学习。


949. 给定数字能组成的最大时间

Leetcode Weekly Contest 113_第1张图片
该题不是很难,四个数作为4位数不同的排列最多24种,最简单的方式是枚举24种数值,取其中满足条件的最大值即可。
对于 abcd 因此满足条件的值范围 0≤cd≤59 and 0≤ab≤23,例如1234 代表12:34。

class Solution:
    def is_hour(self,hour):
        return 0<=hour<=23
    
    def is_m(self,m):
        return 0<=m<60
    
    def largestTimeFromDigits(self, A):
        """
        :type A: List[int]
        :rtype: str
        """
        hour_max = 0
        m_max = 0
        # 记录是否能够组成时间
        flag = False
        for i in range(0,3):
            for j in range(i+1,4):
                tmp = [0,1,2,3]
                tmp.remove(i)
                tmp.remove(j)
                # 查找能组成的小时数
                h1 = A[i] * 10 +A[j]
                h2 = A[j] * 10 + A[i]
                h_flag = self.is_hour(h1) or self.is_hour(h2)
                h1 = h1 if self.is_hour(h1) else 0
                h2 = h2 if self.is_hour(h2) else 0
                
                h1 = max(h1,h2)
                # print(tmp)
                
                #查找能够组成的分钟数
                i1,j1 = tmp
                m1 = A[i1]*10 + A[j1]
                m2 = A[j1]*10 + A[i1]
                m_flag = self.is_m(m1) or self.is_m(m2)
                m1 = m1 if self.is_m(m1) else 0
                m2 = m2 if self.is_m(m2) else 0
                m1 = max(m1,m2)
                # print(h1,m1)
                # 记录时间,小时数大于等于原始最大值,修改结果
                if (h_flag and m_flag):
                    flag = True
                    if h1 >= hour_max:
                        hour_max = h1
                        m_max = m1
        # 格式化时间
        if flag:
            hour_max = "0"+str(hour_max) if hour_max< 10 else str(hour_max)
            m_max = "0"+str(m_max) if m_max< 10 else str(m_max)
            return hour_max+":"+m_max
        return ""        

951. 翻转等价二叉树

Leetcode Weekly Contest 113_第2张图片
Leetcode Weekly Contest 113_第3张图片

如果只是通过左右翻转,每一棵子树在结构上呈现出的特点如下:

  1. 左子树和右子树所有的节点仍在相应的根节点下
  2. 每一层的节点仅仅是位置发生改变

对应的使用递归检查每一层的节点。如果两科树的根节点均为null或值相同,则检查对应的子节点是否能够匹配对应,递归检查相应匹配的子树。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def flipEquiv(self, root1, root2):
        """
        :type root1: TreeNode
        :type root2: TreeNode
        :rtype: bool
        """
        if root1 == None and root2 == None:
            return True
        if root1 == None or root2 == None:
            return False
        if root1.val != root2.val:
            return Flase
        r1_l = root1.left.val if root1.left else -1
        r1_r = root1.right.val if root1.right else -1
        r2_l = root2.left.val if root2.left else -1
        r2_r = root2.right.val if root2.right else -1
        if r1_l == r2_l and r1_r == r2_r:
            return self.flipEquiv(root1.left,root2.left) and self.flipEquiv(root1.right,root2.right)
        if r1_l == r2_r and r1_r == r2_l:
            return self.flipEquiv(root1.left,root2.right) and self.flipEquiv(root1.right,root2.left)
        return False

950. 按递增顺序显示卡牌

Leetcode Weekly Contest 113_第4张图片

嗯。。。其实很简单的一道题。。。将题目描述的过程简单的反过来就好了。。。排序后,元素从大到小遍历,每次循环右移列表然后在列表第一位插入新元素,即可得到结果。直接上代码吧???

class Solution:
    
    def left_rotate(self,a):
        if len(a) ==0:
            return a
        tmp = a[-1]
        a = [tmp] + a[:-1]
        return a
    
    def deckRevealedIncreasing(self, deck):
        """
        :type deck: List[int]
        :rtype: List[int]
        """
        deck.sort()
        # print(deck)
        res = []
        index = len(deck) - 1
        while(index >= 0):
            tmp = deck[index]
            res = self.left_rotate(res)
            res = [tmp] + res
            # print(res)
            index -= 1
        # self.left_rotate(deck)
        # print(res)
        return res

952. 按公因数计算最大组件大小

Leetcode Weekly Contest 113_第5张图片

还是有点难度的一道题,涉及到的点:并查集。
在比赛榜上看到的一个代码(排行榜第7位cuiaoxiang的代码),思路简单清晰,拿来学习一下。
简单的说,首先记录所有因数对应的元素集合,然后根据并查集将具有相同因子的元素进行合并并记录个数,最后找出所有因子对应的最大集合元素数量即可。

class Solution {
public:
    static const int N = 100000+1;
    int f[N], c[N];
    
    int find(int a){
        if(f[a] != f[f[a]])
            f[a] = find(f[a]);
        return f[a];
    }
    
    int largestComponentSize(vector<int>& A) {
        int m = 100000;
        vector<vector<int>> yinzi(m,vector<int>());
        // 遍历得到所有元素对应的因子。
        for (int x : A) {
            int y = x;
            for (int i = 2; i * i <= y; ++i) {
                if (y % i == 0) {
                    while (y % i == 0) y /= i;
                    yinzi[i].push_back(x);
                }
            }
            if (y > 1) yinzi[y].push_back(x);
        }
        // 每个元素初始化为单个的节点
        for (int i = 1; i < N; ++i) {
            f[i] = i;
            c[i] = 1;
        }
        for (int i = 2; i < m; ++i) {
            if (yinzi[i].size() < 2) continue;
            for (int j = 1; j < yinzi[i].size(); ++j) {
                int x = yinzi[i][j - 1];
                int y = yinzi[i][j];
                //cout << i << " " << x << " " << y << endl;
                //通过并查集来合并包含相同因子的元素
                int rx = find(x), ry = find(y);
                if (rx != ry) {
                    f[ry] = rx;
                    c[rx] += c[ry];
                }
            }
        }
        int ret = 1;
        for (int i = 1; i < N; ++i) {
            if (find(i) == i) {
                ret = max(ret, c[i]);
            }
        }
        return ret;
    }
};

你可能感兴趣的:(leetcode)