做了几次leetcode的周赛,还是菜的不行,每次基本上就做3道题,偶尔在规定时间内做完了4道题。仅以此记录一下自己每次刷题的一点点思考,慢慢学习。
该题不是很难,四个数作为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 ""
如果只是通过左右翻转,每一棵子树在结构上呈现出的特点如下:
对应的使用递归检查每一层的节点。如果两科树的根节点均为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
嗯。。。其实很简单的一道题。。。将题目描述的过程简单的反过来就好了。。。排序后,元素从大到小遍历,每次循环右移列表然后在列表第一位插入新元素,即可得到结果。直接上代码吧???
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
还是有点难度的一道题,涉及到的点:并查集。
在比赛榜上看到的一个代码(排行榜第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;
}
};