leetcode(24)其他题目
模拟
621. 任务调度器
假设 A有3个(maxCt = 3), n = 2, 需要 待命 说明'x'的位置都填不满, 实际完成任务时间 = (maxCt-1)*(n+1)+1 > len(tasks)
A x x
A x x
A
如果'x'的位置能填满的话, 实际完成任务时间 = len(tasks) > (maxCt-1)*(n+1)+1, 即
A B C D
A B C
A
另外要注意的是数量最大的任务可能有好几个, 比如A有3个(maxCt = 3), B也有3个, eleMaxCt = 2,
A B x
A B x
A B
那么最后一行的个数就不是1,而是eleMaxCt,
综上, 实际完成任务时间 = max((maxCt-1)*(n+1)+eleMaxCt , len(tasks))
class Solution:
def leastInterval(self, tasks: List[str], n: int) -> int:
dict_freq = list(collections.Counter(tasks).values()) # 所有任务的出现次数, AABBBC -> [2,3,1]
max_freq = max(dict_freq) # 最多的执行次数
max_num = dict_freq.count(max_freq) # 具有最多执行次数的任务数量
return max((max_freq - 1) * (n + 1) + max_num, len(tasks))
6214. 判断两个事件是否存在冲突
直接比较字符串即可
class Solution:
def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
return event1[0] <= event2[1] and event2[0] <= event1[1]
1620. 网络信号最好的坐标
从小到大遍历每一个坐标
class Solution:
def bestCoordinate(self, towers: List[List[int]], radius: int) -> List[int]:
res = [0, 0]
mx = 0
for i in range(51):
for j in range(51):
cur = 0
for x, y, q in towers:
d = sqrt((x - i) ** 2 + (y - j) ** 2)
if d <= radius:
cur += floor(q / (1 + d))
if cur > mx:
mx = cur
res = [i, j]
return res
816. 模糊坐标
class Solution:
def ambiguousCoordinates(self, s: str) -> List[str]:
def f(i, j):
ch_list = []
for k in range(1, j - i + 1):
l, r = s[i: k + i], s[k + i: j]
flag = (l == '0' or not l.startswith('0')) and not r.endswith('0')
if flag:
ch_list.append(l + ('.' if k < j - i else '') + r)
return ch_list
n = len(s)
return [f'({x}, {y})' for i in range(2, n - 1) #空格在 f'({x}, {y})'里添加
for x in f(1, i) for y in f(i, n - 1)]
1779. 找到最近的有相同 X 或 Y 坐标的点
class Solution:
def nearestValidPoint(self, x: int, y: int, points: List[List[int]]) -> int:
res, min_dis = -1, inf
for i, (a, b) in enumerate(points):
if a == x or b == y:
dis = abs(a - x) + abs(b - y)
if dis < min_dis:
res, min_dis = i, dis
return res
1742. 盒子中小球的最大数量
最大不超过10**5 那最大的结果 是 99999 9+9+9+9+9=45
class Solution:
def countBalls(self, lowLimit: int, highLimit: int) -> int:
cnt = [0] * 50
for i in range(lowLimit, highLimit + 1):
cur = 0
while i:
cur += i % 10
i //= 10
cnt[cur] += 1
return max(cnt)
6254. 划分技能点相等的团队
因为要保证“每一个团队的技能点之和 相等”,则一定是排序之后首尾相加
然后检查每一对的和是否都等于首尾之和,若是则对乘积求和;否则返回-1
class Solution:
def dividePlayers(self, skill: List[int]) -> int:
n = len(skill)
skill.sort()
res, i, j = skill[0] * skill[-1], 1, n - 2
if n == 2:return res
tmp = skill[0] + skill[-1]
while i < j:
cur = skill[i] + skill[j]
if cur != tmp:
return -1
else:
res += skill[i] * skill[j]
i += 1
j -= 1
return res
400. 第 N 位数字
2023.06.08腾讯一面
class Solution:
def findNthDigit(self, n: int) -> int:
# 以n = 200为例
cur = 1
base = 9
while n > cur * base:
n -= cur * base
cur += 1
base *= 10
# 得到 n 是三位数开始的第11个位置,从0开始计数就是10
n -= 1
# 得到num是第3个三位数,即103
num = 10 ** (cur - 1) + n // cur
# 得到idx是要取这个三位数的第1个位置,即0
idx = n % cur
return num // (10**(cur - 1 - idx)) % 10
递归
273. 整数转换英文表示
single = ['','One','Two','Three','Four','Five','Six','Seven','Eight','Nine']
teen = ['Ten','Eleven','Twelve','Thirteen','Fourteen','Fifteen','Sixteen','Seventeen','Eighteen','Nineteen']
ty = ['','Ten','Twenty','Thirty','Forty','Fifty','Sixty','Seventy','Eighty','Ninety']
posi = ['','Thousand','Million','Billion']
class Solution:
def numberToWords(self, num: int) -> str:
if not num:return 'Zero'
def recursion(num):
s = ''
if not num:return s
if num < 10:
s += single[num] + ' '
elif num < 20:
s += teen[num-10] + ' '
elif num < 100:
s += ty[num//10] + ' ' + recursion(num%10) # single[num%10]换成recursion空格才会对
else:
s += single[num//100] + ' Hundred ' + recursion(num%100)
return s
s = ''
uint = int(1e9)
for i in range(3, -1, -1): # 最多12位,按照 3 位一组划分最多有 4 组
cur = num // uint # 从最高位开始
if cur:
s += recursion(cur) + posi[i] + ' '
num -= cur * uint
uint //= 1000
return s.strip()
贪心
2448. 使数组相等的最小开销
根据中位数贪心,把所有数变成中位数是最优的。
不断累加cost[i],首次累加到>=sumCost/2时就找到了中位数。
class Solution:
def minCost(self, nums: List[int], cost: List[int]) -> int:
nlist = sorted(zip(nums, cost))
mid = sum(cost) // 2
cur = 0
for chosen, c in nlist:
cur += c
if cur >= mid:
return sum(abs(n - chosen)*c for n, c in nlist)
脑筋急转弯
2449. 使数组相似的最少操作次数
奇数不可能由偶数变成,偶数不可能由奇数变成,奇偶排序分组后一一对应计算每个部分正数和,除以二就是答案了,因为题目一定可以转换,所以也不用讨论成立的条件。
class Solution:
def makeSimilar(self, nums: List[int], target: List[int]) -> int:
nums.sort(key = lambda x:(x%2, x))
print(nums) # [2, 1, 5]
target.sort(key = lambda x:(x%2, x))
print(target) # [4, 1, 3]
return sum(abs(n - t) for n, t in zip(nums, target)) // 4
# return sum(n - t for n, t in zip(nums, target) if n > t) // 2
754. 到达终点数字
还没到达或越过终点时就一直走;越过的话判断与终点的距离是否是奇数
class Solution:
def reachNumber(self, target: int) -> int:
target = abs(target)
s = n = 0
while s < target or (s - target) % 2:
print(s)
n += 1
s += n
return n
1812. 判断国际象棋棋盘中一个格子的颜色
class Solution:
def squareIsWhite(self, coordinates: str) -> bool:
# 奇数 + 奇数 = 偶数;奇数 + 偶数 = 奇数;偶数 + 偶数 = 奇数
return bool((ord(coordinates[0]) + int(coordinates[1])) % 2)
数学题
470. 用 Rand7() 实现 Rand10()
题解参考:详细思路及优化思路分析,逐行解释
思路如下面这样构建:
\(\qquad (rand7() - 1)*7+rand7()\)
- 首先 rand7()−1 得到的数的集合为 \(\left\{ 0,1,2,3,4,5,6 \right\}\)
再乘 7 后得到的集合 A 为 \(\left\{ 0,7,14,21,28,35,42\right\}\)
后面 rand7() 得到的集合B为 \(\left\{ 1,2,3,4,5,6,7\right\}\)
取值范围为 1~49,需要舍弃 9 个。 - 同理,第二次(num - 40 - 1) * 7 + rand7()得到集合A为\(\left\{ 0,7,14,21,28,35,42,49,56\right\}\)
得到的集合B为 \(\left\{ 1,2,3,4,5,6,7\right\}\)
取值范围为 1~63,需要舍弃 3 个。 - 同理,第三次(num - 60 - 1) * 7 + rand7()得到集合A为\(\left\{ 0,7,14\right\}\)
得到的集合B为 \(\left\{ 1,2,3,4,5,6,7\right\}\)
取值范围为 1~21,即只要舍弃 1 个即可。
# The rand7() API is already defined for you.
# def rand7():
# @return a random integer in the range 1 to 7
class Solution:
def rand10(self):
while True:
num = (rand7() - 1) * 7 + rand7()
# 如果在40以内,那就直接返回
if num <= 40:
return num % 10 + 1
# 说明刚才生成的在41-49之间,利用随机数再操作一遍
num = (num - 40 - 1) * 7 + rand7()
if num <= 60:
return num % 10 + 1
# 说明刚才生成的在61-63之间,利用随机数再操作一遍
num = (num - 60 - 1) * 7 + rand7()
if num <= 20:
return num % 10 + 1
891. 子序列宽度之和
排序后计算每个值作为最大值最小值的贡献
如果将元素 nums[i]作为子序列的最大值,子序列的其他元素应该从左侧的 i个元素中选取,每个元素有两种选择,即选或不选,因此总共有 \(2^i\)个子序列。
同理,如果将元素 nums[i]作为子序列的最小值,那么总共有 \(2^{n-i-1}\)个满足条件的子序列。因此 nums[i]对答案的贡献为:
\(\begin{aligned} nums[i] \times (2^i - 2^{n-i-1}) \end{aligned}\)
class Solution:
def sumSubseqWidths(self, nums: List[int]) -> int:
MOD = 10**9 + 7
nums.sort()
n, res = len(nums), 0
for i, num in enumerate(nums):
res = (res + (pow(2,i,MOD) - pow(2,n - i - 1,MOD)) * num) % MOD
return res
1780. 判断一个数字是否可以表示成三的幂的和
将n转成3进制,如果每位都是0或者1则为True
class Solution:
def checkPowersOfThree(self, n: int) -> bool:
while n:
if n % 3 > 1:
return False
n //= 3
# print(n)
return True
二叉树
2471. 逐层排序二叉树所需的最少操作数目
# 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 minimumOperations(self, root: Optional[TreeNode]) -> int:
def check(nums):
if not nums: return 0
cnt = 0
dic = {}
for x, y in zip(nums, sorted(nums)):
if x != y:
while x in dic:
x = dic[x]
if x != y:
cnt += 1
dic[y] = x
return cnt
res = 0
q = deque([root])
while q:
nums = []
for _ in range(len(q)):
cur = q.popleft()
if not cur:continue
nums.append(cur.val)
q.append(cur.left)
q.append(cur.right)
res += check(nums)
return res