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

posted @ 2022-06-05 22:04  YTT77  阅读(25)  评论(0编辑  收藏  举报