LeetCode双周赛 19

LeetCode双周赛 19

5311. 将数字变成 0 的操作次数

题目描述

给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。

分析

解题方法非常简单, 直接按照题目意思就可以了.

class Solution:
    def numberOfSteps (self, num: int) -> int:
        ans = 0
        while num:
            num, ans = num - 1 if num % 2 else num / 2, ans + 1
        return ans

算法复杂度:O(n), nnum, 空间复杂度: O(1).

5312. 大小为 K 且平均值大于等于阈值的子数组数目

题目描述

给你一个整数数组 arr 和两个整数 kthreshold

请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。

分析

使用滑动窗口求解, 这里必须说明一下, 必须判断数组大小len(arr)小于k的情况, 否则会出错.

滑动窗口: 先计算前k-1个元素的和. 然后从第k个元素假定为i开始, 加上当前元素arr[i], 判断是否符合要求, 然后减去在他之前的第 k-1个元素arr[i-k+1]. 直到数组结束.

class Solution:
    def numOfSubarrays(self, arr: List[int], k: int, threshold: int) -> int:
        if len(arr) < 0: return 0
        total, ans = sum(arr[:k-1]), 0
        for i in range(k - 1, len(arr)):
            total += arr[i]
            if total >= k * threshold: ans = ans + 1
            total -= arr[i-k+1]
        return ans

算法复杂度:O(n), n为数组长度, 空间复杂度:O(1)

5313. 时钟指针的夹角

题目描述

给你两个数 hourminutes 。请你返回在时钟上,由给定时间的时针和分针组成的较小角的角度(60 单位制)。

分析

思路: 分别求解时针,分针与12点的夹角, 然后相减就可以. 注意: 返回的角度应该小于180度.

class Solution:
    def angleClock(self, hour: int, minutes: int) -> float:
        h = ((hour + minutes / 60) / 12) * 360
        m = minutes * 6
        return abs(h - m) if abs(h - m) < 180 else 360 - abs(h-m)

算法复杂度:O(1), n为数组长度, 空间复杂度:O(1)

5314. 跳跃游戏 IV

题目描述

给你一个整数数组 arr ,你一开始在数组的第一个元素处(下标为 0)。
每一步,你可以从下标 i 跳到下标:

  • i + 1 满足:i + 1 < arr.length
  • i - 1 满足:i - 1 >= 0
  • j 满足:arr[i] == arr[j]i != j
    请你返回到达数组最后一个元素的下标处所需的 最少操作次数
    注意:任何时候你都不能跳到数组外面。

分析

最少操作次数 , 一般使用BFS(宽度优先搜索), 这题也不例外, 不过这题难点在于按组进行BFS, 如果按照元素BFS, 会超出时间限制.

首先使用map(int, list)将相同元素的下标记录下来, 然后按照规则进行BFS即可.

class Solution:
    def minJumps(self, arr: List[int]) -> int:
        if len(arr) == 1: return 0
        memo = {}
        for i, v in enumerate(arr):
            if v in memo: memo[v].append(i)
            else: memo[v] = [i]
        step, q, stat = 1, collections.deque([0]), [True] * len(arr)
        stat[0] = False
        while q:
            l = len(q)
            for i in range(len(q)):
                top = q.popleft()
                if top + 1 < len(arr) and stat[top+1]:
                    stat[top+1] = False
                    q.append(top + 1)
                    if top + 1 == len(arr) - 1: return step
                if top - 1 > 0 and stat[top - 1]:
                    stat[top - 1] = False
                    q.append(top - 1)
                if arr[top] in memo:
                    for i in memo[arr[top]]:
                    	if stat[i]:
                            stat[i] = False
                            q.append(i)
                            if i == len(arr) - 1: return step
                    del memo[arr[top]]
					'''#如果使用:
                    for i in memo[arr[top]]:
                    	if stat[i]:
                            stat[i] = False
                            q.append(i)
                            if i == len(arr) - 1: return step
                     #则会超时'''
            step += 1
        return -1

算法复杂度:O(n), nlen(arr),统计相同元素出现位置时需遍历一次O(n), DFS每个元素只需要搜索一次O(n) , 空间复杂度: O(n).

posted @ 2020-02-09 00:08  CYHua  阅读(297)  评论(0编辑  收藏  举报