zoukankan      html  css  js  c++  java
  • [Leetcode Weekly Contest]176

    链接:LeetCode

    [Leetcode]5340. 统计有序矩阵中的负数

    给一个(m * n)的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。 
    请你统计并返回 grid 中 负数 的数目。
    示例 1:

    输入:grid = ([[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]])
    输出:8
    解释:矩阵中共有 8 个负数。

    因为是非递增顺序排列,所以最小的数在矩阵左下角,每次跟矩阵左下角进行比较即可,时间复杂度(O(m+n))

    class Solution:
        def countNegatives(self, grid: List[List[int]]) -> int:
            m, n = len(grid), len(grid[0])
            r, c, cnt = m - 1, 0, 0
            while r >= 0 and c < n:
                if grid[r][c] < 0:
                    cnt += n - c
                    r -= 1
                else:
                    c += 1
            return cnt
    

    [Leetcode]5341. 最后 K 个数的乘积

    实现一个「数字乘积类」ProductOfNumbers,要求支持下述两种方法:
    1. add(int num)

    将数字 num 添加到当前数字列表的最后面。
    2. getProduct(int k)

    返回当前数字列表中,最后(k)个数字的乘积。
    你可以假设当前列表中始终 至少 包含(k)个数字。
    题目数据保证:任何时候,任一连续数字序列的乘积都在 32-bit 整数范围内,不会溢出。

    类似于在数组中寻找K个数的和,我们可以先求出从开始位到每一位的总积,然后用总积除以从开始位到最后k-1位的总积,即可。但有一种特殊情况就是出现了0,当出现0的时候,后面每一个位置的总积都是0,无法用这种方法,这个时候我们将数组清零即可,当判断最后(k)个数字的乘积,如果数组个数小于K个,则说明之前是出现了0。这也是最简单的一种判别方法了。

    class ProductOfNumbers:
    
        def __init__(self):
            self.products = []
    
        def add(self, num: int) -> None:
            if not num:
                self.products = []
            else:
                if not self.products:
                    self.products.append(num)
                else:
                    self.products.append(self.products[-1]*num)
            
        def getProduct(self, k: int) -> int:
            if k>len(self.products):
                return 0
            if k == len(self.products):
                return self.products[-1]
            n = len(self.products)
            return self.products[-1]//self.products[n-k-1]
    

    [Leetcode]5342. 最多可以参加的会议数目

    给你一个数组 events,其中(events[i] = [startDayi, endDayi]),表示会议(i)开始于 (startDay_i),结束于(endDay_i)
    你可以在满足(startDay_i <= d <= endDay_i)中的任意一天(d)参加会议(i)。注意,一天只能参加一个会议。
    请你返回你可以参加的最大会议数目。

    输入:events = ([[1,2],[2,3],[3,4]])
    输出:3
    解释:你可以参加所有的三个会议。
    安排会议的一种方案如上图。
    第 1 天参加第一个会议。
    第 2 天参加第二个会议。
    第 3 天参加第三个会议。

    这实际是一道考验贪婪法求解的题目。首先,我们很明确一个事情,就是给定一个event,如果我要参加其会议,当然是越早越好,这可以给后面的会议让出时间,所以选择不是问题,而问题在于排序。怎么明确,先参加哪个会议呢?
    答案是(endDay_i)最小的那个。假设我们先将(endDay_i)排序,那么对于(endDay_i)最小的那个会议,我选择其(startDay_i)一天参加会议不会影响后面的会议的选择。想想反证法:假设我们占用了任何一个其他会议(event_j)的时间,最佳的选择应该是会议(event_j)(startDay_i),而会议(event_i)在其他时间,那么这种情况对于(event_i)(endDay_i<=endDay_j),所以无论会议
    (event_i)选在哪个时间,(event_j)也可以选择那个时间。这说明,我们选任何一个其他会议(event_j)的情况,都能在先选(event_i)的策略中找到一样的,即选择(endDay_i)最小的那个会议先参加,其最大会议数目大于等于先参加其他任何会议。
    接下来,我们用一个集合set来存储我们参加会议的时间即可。

    class Solution:
        def maxEvents(self, events: List[List[int]]) -> int:
            if not events or not events[0]:
                return 0
            events = sorted(events, key=lambda x: x[1])
            visited = set()
            for s, e in events:
                for t in range(s, e+1):
                    if t not in visited:
                        visited.add(t)
                        break
            return len(visited)
    

    [Leetcode]5343. 多次求和构造目标数组

    给你一个整数数组 target 。一开始,你有一个数组 A ,它的所有元素均为 1 ,你可以执行以下操作:

    令 x 为你数组里所有元素的和
    选择满足 0 <= i < target.size 的任意下标 i ,并让 A 数组里下标为 i 处的值为 x 。
    你可以重复该过程任意次
    如果能从 A 开始构造出目标数组 target ,请你返回 True ,否则返回 False 。

    示例 1:
    输入:(target = [9,3,5])
    输出:true
    解释:从 ([1, 1, 1]) 开始
    ([1, 1, 1]), 和为 3 ,选择下标 1
    ([1, 3, 1]), 和为 5, 选择下标 2
    ([1, 3, 5]), 和为 9, 选择下标 0
    ([9, 3, 5]) 完成

    这是一道贪婪+堆的题目。
    首先,我们先看看例子,对于(target = [9,3,5]),虽然我们不知道([1, 1, 1])怎么开始求和构成成如此数组,但显然最后一层构造所替换掉的元素,必然是数组中的最大值,也就是9。接下来,我们要逆向思考,9之前替换的数字是什么呢?根据规则,我们知道,9,即x等于3加5加本来的元素,所以本来的元素是(1),那么此时,(target = [1,3,5]),接下来,我们再按照这种方式求最大值原来的值是多少,并进行替换即可。
    这里比较高效的方法是大顶堆,在每次进行(pop)的时候,提取出数组最大值,然后把替换前的数(push)进去,这里有两个技巧:
    1.因为是大顶堆,python默认的 heapq是小顶堆,所以我们放入的时候取负数即可。
    2.如果我们计算出的替换出的数<1,那么说明这是无法从([1, 1, 1]) 开始构造而成的,返回False即可。

    class Solution:
        def isPossible(self, target: List[int]) -> bool:
            total=sum(target)
            target=[-x for x in target]
            heapq.heapify(target)
            while target:
                curMax=-heapq.heappop(target)
                if curMax==1:
                    return len(target)==0 or max(target)==-1
                total-=curMax
                next_sum=curMax-total
                total+=next_sum
                if next_sum < 1:
                    return False
                heapq.heappush(target,-next_sum)
    
  • 相关阅读:
    抽象类和接口【转】
    JQuery中的事件总结
    ExecuteNonQuery()返回受影响行数不适用select语句
    用js获取对象之前首先检测元素是否存在
    页面如何自动出现滚动条(overflow属性用法)
    今天调试程序遇到了一个致命问题语法错误操作符丢失
    JQuery选择器学习总结JQuery选择器
    css !important用法CSS样式使用优先级判断
    JQuery操作DOM总结
    JQuery特效与动画总结
  • 原文地址:https://www.cnblogs.com/hellojamest/p/12318516.html
Copyright © 2011-2022 走看看