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实现
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实现
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();
*/