12.5周赛复盘
5942.找出3位偶数
题目链接:https://leetcode-cn.com/problems/finding-3-digit-even-numbers/
解题思路:
-
先是对数组做一个处理,因为是构造三位偶数,所以一个数字出现的次数超过3时,就当其出现了三次即可(否则会超时)。
-
因为结果需要排序,所以先对处理好的数组做个排序即可。
-
利用回溯算法构造三位偶数。
python解法:
class Solution:
def findEvenNumbers(self, digits: List[int]) -> List[int]:
from collections import Counter
d = Counter(digits)
l = []
for i in d:
if d[i] > 3:
l += [i] * 3
else:
l += [i] * d[i]
l.sort()
res = []
def back(select,path):
nonlocal res
if len(path) == 3:
t = path[0] * 100 + path[1] * 10 + path[2]
if t % 2 == 0 and t not in res:
res.append(t)
return
for i in range(len(select)):
if not path and select[i] == 0:
continue
path.append(select[i])
back(select[:i]+select[i+1:],path)
path.pop()
back(l,[])
return res
2095. 删除链表的中间节点
解题思路:
-
利用两个指针,一个是遍历每个节点,另外一个是每两个往后走一次。这样就可以指到要删除的节点。
-
这样同时要记录好中间节点的前一个节点,方便删除操作的执行。
-
最后处理一下长度为一的链表这种情况。
题目链接:https://leetcode-cn.com/problems/delete-the-middle-node-of-a-linked-list/
python解法:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def deleteMiddle(self, head: Optional[ListNode]) -> Optional[ListNode]:
l1,l2 = head,head
n = 0
while l2:
l2 = l2.next
n += 1
if n % 2 == 0:
pre = l1
l1 = l1.next
if n == 1:
return None
else:
pre.next = l1.next
return head
2096. 从二叉树一个节点到另一个节点每一步的方向
题目链接:https://leetcode-cn.com/problems/step-by-step-directions-from-a-binary-tree-node-to-another/
解题思路:
- dfs 寻找出所有的路径。利用一个字典,记录出所有的路线。
- 将根节点到StartNode和DestNode的路线都记录出来。
- 将根节点到最小公共节点的部分剔除掉。
- 将路线构建出来,StartNode部分踢掉公共部分全部替换成U,DestNode部分踢掉公共部分直接添加到finalPath去。
python解法:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def getDirections(self, root: Optional[TreeNode], startValue: int, destValue: int) -> str:
Father_Node = {}
StartNode = None
DestNode = None
def dfs(curr) :
nonlocal StartNode, DestNode
if curr.val == startValue:
StartNode = curr
if curr.val == destValue:
DestNode = curr
if curr.left:
Father_Node[curr.left] = curr
dfs(curr.left)
if curr.right:
Father_Node[curr.right] = curr
dfs(curr.right)
dfs(root)
def path(curr):
res = []
while curr != root:
par = Father_Node[curr]
if par.left == curr:
res.append("L")
elif par.right == curr:
res.append("R")
curr = par
return res[::-1]
sp = path(StartNode)
dp = path(DestNode)
l1,l2 = len(sp),len(dp)
i = 0
while i < min(l1,l2):
if sp[i] == dp[i] :
i += 1
else:
break
finalpath = 'U' * (l1 - i) + ''.join(dp[i:])
return finalpath
2097. 合法重新排列数对
题目链接 : https://leetcode-cn.com/problems/valid-arrangement-of-pairs/
python解法:
class Solution:
def validArrangement(self, pairs: List[List[int]]) -> List[List[int]]:
# 存储图
edges = defaultdict(list)
# 存储入度和出度
indeg, outdeg = Counter(), Counter()
for x, y in pairs:
edges[x].append(y)
indeg[y] += 1
outdeg[x] += 1
# 寻找起始节点
start = pairs[0][0]
for x in outdeg:
# 如果有节点出度比入度恰好多 1,那么只有它才能是起始节点
if outdeg[x] == indeg[x] + 1:
start = x
break
ans = list()
# 深度优先搜索(Hierholzer 算法)求解欧拉通路
def dfs(u: int) -> None:
while edges[u]:
v = edges[u].pop()
dfs(v)
ans.append([u, v])
dfs(start)
return ans[::-1]