You are given the number of rows n_rows
and number of columns n_cols
of a 2D binary matrix where all values are initially 0. Write a function flip
which chooses a 0 value uniformly at random, changes it to 1, and then returns the position [row.id, col.id]
of that value. Also, write a function reset
which sets all values back to 0. Try to minimize the number of calls to system's Math.random()and optimize the time and space complexity.
Note:
1 <= n_rows, n_cols <= 10000
0 <= row.id < n_rows
and0 <= col.id < n_cols
flip
will not be called when the matrix has no 0 values left.- the total number of calls to
flip
andreset
will not exceed 1000.
Example 1:
Input:
["Solution","flip","flip","flip","flip"]
[[2,3],[],[],[],[]]
Output: [null,[0,1],[1,2],[1,0],[1,1]]
Example 2:
Input:
["Solution","flip","flip","reset","flip"]
[[1,2],[],[],[],[]]
Output: [null,[0,0],[0,1],null,[0,0]]
Explanation of Input Syntax:
The input is two lists: the subroutines called and their arguments. Solution
's constructor has two arguments, n_rows
and n_cols
. flip
and reset
have no arguments. Arguments are always wrapped with a list, even if there aren't any.
模拟一遍1..row*col
import random
class Solution:
def __init__(self, n_rows, n_cols):
"""
:type n_rows: int
:type n_cols: int
"""
self.n_rows=n_rows
self.n_cols=n_cols
self.l=[[i,j,False] for j in range(n_cols) for i in range(n_rows)]
self.cnt=n_rows*n_cols
def flip(self):
"""
:rtype: List[int]
"""
idx=random.randint(1,self.cnt)
p = 0
while idx:
while self.l[p][2]: p+=1
idx-=1
if idx==0:
self.l[p][2]=True
self.cnt-=1
return [self.l[p][0],self.l[p][1]]
p+=1
def reset(self):
"""
:rtype: void
"""
self.cnt=self.n_rows*self.n_cols
self.l=[[i,j,False] for j in range(self.n_cols) for i in range(self.n_rows)]
# Your Solution object will be instantiated and called as such:
# obj = Solution(n_rows, n_cols)
# param_1 = obj.flip()
# obj.reset()
TLE,那就每次flip跟数字末尾的数swap一下
import random
class Solution:
def __init__(self, n_rows, n_cols):
"""
:type n_rows: int
:type n_cols: int
"""
self.n_rows=n_rows
self.n_cols=n_cols
self.l=[[i,j] for j in range(n_cols) for i in range(n_rows)]
self.cnt=n_rows*n_cols
def flip(self):
"""
:rtype: List[int]
"""
idx=random.randint(0,self.cnt-1)
self.l[idx], self.l[self.cnt-1]=self.l[self.cnt-1], self.l[idx]
self.cnt-=1
return self.l[self.cnt]
def reset(self):
"""
:rtype: void
"""
self.cnt=self.n_rows*self.n_cols
# Your Solution object will be instantiated and called as such:
# obj = Solution(n_rows, n_cols)
# param_1 = obj.flip()
# obj.reset()
继续TLE,看来还得优化建立数组这一过程,那就用Map,每次flip idx的时候,吧idx实际指向数组的最后一位
import random
class Solution:
def __init__(self, n_rows, n_cols):
"""
:type n_rows: int
:type n_cols: int
"""
self.n_rows=n_rows
self.n_cols=n_cols
self.d={}
self.cnt=n_rows*n_cols
def flip(self):
"""
:rtype: List[int]
"""
idx=random.randint(0,self.cnt-1)
res=self.d.get(idx, idx)
self.d[idx]=self.d.get(self.cnt-1, self.cnt-1)
self.cnt-=1
return res//self.n_cols, res%self.n_cols
def reset(self):
"""
:rtype: void
"""
self.cnt=self.n_rows*self.n_cols
self.d={}
# Your Solution object will be instantiated and called as such:
# obj = Solution(n_rows, n_cols)
# param_1 = obj.flip()
# obj.reset()
Given a blacklist B
containing unique integers from [0, N)
, write a function to return a uniform random integer from [0, N)
which is NOT in B
.
Optimize it such that it minimizes the call to system’s Math.random()
.
Note:
1 <= N <= 1000000000
0 <= B.length < min(100000, N)
[0, N)
does NOT include N. See interval notation.
Example 1:
Input: ["Solution","pick","pick","pick"] [[1,[]],[],[],[]] Output: [null,0,0,0]
Example 2:
Input: ["Solution","pick","pick","pick"] [[2,[]],[],[],[]] Output: [null,1,1,1]
Example 3:
Input: ["Solution","pick","pick","pick"] [[3,[1]],[],[],[]] Output: [null,0,0,2]
Example 4:
Input: ["Solution","pick","pick","pick"] [[4,[2]],[],[],[]] Output: [null,1,3,1]
Explanation of Input Syntax:
The input is two lists: the subroutines called and their arguments. Solution
's constructor has two arguments, N
and the blacklist B
. pick
has no arguments. Arguments are always wrapped with a list, even if there aren't any.
类似的思路,要对blacklist先排序才work,因为是从末尾删除的,删除了就不能在修改了
import random
class Solution(object):
def __init__(self, N, blacklist):
"""
:type N: int
:type blacklist: List[int]
"""
self.cnt=N-1
self.d={}
blacklist.sort(reverse=True)
for t in blacklist:
self.d[t]=self.d.get(self.cnt, self.cnt)
self.cnt-=1
def pick(self):
"""
:rtype: int
"""
n=random.randint(0,self.cnt)
return self.d.get(n, n)
# Your Solution object will be instantiated and called as such:
# obj = Solution(N, blacklist)
# param_1 = obj.pick()