力扣每日一题2021-11-27随机翻转矩阵


519.随机翻转矩阵

题目描述

随机翻转矩阵


思路

哈希表记录交换+降维

首先将二维矩阵用一维数组表示,将(i, j)与i*n+j一一对应。但是m和n最大值都可以达到 1 0 4 10^4 104,维护这样的数组会消耗大量的空间。注意到flip最多进行一千次,所以可以只记录用过的数,并维护出上面想要的数组的样子。这时候可以使用哈希表。
假设一维数组为[0, 1, 2, 3, 4, 5],最后一个值为5;
第一次随机,假定是1,则下一次随机是想要在[0, 2, 3, 4, 5]中取一个,将5填入1的位置,就像做了一次1和5的交换,因此数组变为[0, 5, 2, 3, 4]。
第二次随机,从0到4随机取一个坐标,,假如不是1,则进行上一次的操作;假如是1,那么我们这次随机出来的数就相当于是5,则仍需要将1位置的映射更新,更新为4,因此,数组变为[0, 4, 2, 3]。
直到最后将全部数组随机出,被用过的数不再出现,因为始终会取没背用过的数。

Python实现

Python实现

class Solution:

    def __init__(self, m: int, n: int):
        self.m, self.n = m, n
        self.total = m * n - 1
        self.record = dict()


    def flip(self) -> List[int]:
        r = random.randint(0, self.total)
        idx = self.record.get(r, r)
        self.record[r] = self.record.get(self.total, self.total)
        self.total -= 1
        ans = [idx // self.n, idx % self.n]
        return ans


    def reset(self) -> None:
        self.total = self.m * self.n - 1
        self.record = dict()



# Your Solution object will be instantiated and called as such:
# obj = Solution(m, n)
# param_1 = obj.flip()
# obj.reset()
Java实现

Java实现

class Solution {
    
    private int m, n, total;
    private Map<Integer, Integer> map;
    private Random random;

    public Solution(int m, int n) {
        this.m = m;
        this.n = n;
        total = m * n - 1;
        map = new HashMap<>();
        random = new Random();
    }
    
    public int[] flip() {
        int r = random.nextInt(total + 1);
        int idx = map.getOrDefault(r, r);
        map.put(r, map.getOrDefault(total, total));
        total --;
        return new int[] {idx/n, idx%n};
    }
    
    public void reset() {
        total = m * n - 1;
        map = new HashMap<>();
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(m, n);
 * int[] param_1 = obj.flip();
 * obj.reset();
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值