每日一题leetcode519.随机翻转矩阵

461 篇文章 1 订阅
本文介绍了一种高效的算法,用于在给定的二维矩阵中随机选择并标记未被赋值的单元格(值为0),同时减少对内置随机函数的依赖。通过巧妙地使用映射数组,实现了时间复杂度和空间复杂度的优化,便于后续的矩阵操作和管理。
摘要由CSDN通过智能技术生成

题目:
给你一个 m x n 的二元矩阵 matrix ,且所有值被初始化为 0 。请你设计一个算法,随机选取一个满足 matrix[i][j] == 0 的下标 (i, j) ,并将它的值变为 1 。所有满足 matrix[i][j] == 0 的下标 (i, j) 被选取的概率应当均等。

尽量最少调用内置的随机函数,并且优化时间和空间复杂度。

实现 Solution 类:

  • Solution(int m, int n) 使用二元矩阵的大小 m 和 n 初始化该对象
  • int[] flip() 返回一个满足 matrix[i][j] == 0 的随机下标 [i, j] ,并将其对应格子中的值变为 1
  • void reset() 将矩阵中所有的值重置为 0
    在这里插入图片描述

思路:
数组映射:

  • 矩阵中的位置:(i,j) -> map[i*n+j]
  • 在经过m×n−k 次翻转flip 后,我们会修改map 与矩阵的映射,使得当前矩阵中有m×n−k 个 1 和 k个 0
  • 利用数组中元素的交换,使得 map[0⋯k−1] 映射到矩阵中的 0,而 map[k⋯m×n−1] 映射到矩阵中的 1。该做法的好处:当进行下一次翻转操作时,我们只需要在 [0, k-1]这个区间生成随机数 x,并将 map[x] 映射到的矩阵的位置进行翻转即可
  • 在将map[x] 进行翻转后,此时矩阵中有k−1 个 0,所以我们需要保证 map[0…k−2] 都映射到矩阵中的 0。由于此时map[x] 映射到了矩阵中的 1,因此我们可以将map[x] 与map[k−1] 的值进行交换,即将这个新翻转的 1 作为map[k−1] 的映射,而把原本 map[k−1] 映射到的 0 交给 x

解答:

class Solution:

    def __init__(self, m: int, n: int):
        self.m = m
        self.n = n
        self.total = m * n
        self.map = {}

    def flip(self) -> List[int]:
        x = random.randint(0, self.total - 1)
        self.total -= 1
        # 查找位置 x 对应的映射,(key,default)返回指定键x的值,如果键不在字典中返回 default 设置的默认值
        idx = self.map.get(x, x)
        # 将位置 x 对应的映射设置为位置 total 对应的映射
        self.map[x] = self.map.get(self.total, self.total)
        return [idx // self.n, idx % self.n]
        
    def reset(self) -> None:
        self.total = self.m * self.n
        self.map.clear()



# Your Solution object will be instantiated and called as such:
# obj = Solution(m, n)
# param_1 = obj.flip()
# obj.reset()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值