HashMap
IntuitionAssume matrix(nxm) as flattened 1D array
[i,j] -> n*i+ j in 1D Array
And keep a map to check and update if already flipped value flipped againApproachI
# Intuition
Assume matrix(nxm) as flattened 1D array 
[i,j] -> n*i+ j in 1D Array
And keep a map to check and update if already flipped value flipped again

# Approach
Init rows, col and Use Random random = new Random() to generate a random number and keep reducing the range ensuring new Picks

```java []
Eg : 0 1 2 in 1D  : [0,1,2,3,4,5,6,7,8]
     3 4 5 total Range = [0,8]
     6 7 8
```
Let r = 2 () mappedIdx = 2 (1st time ) and flipped will map it to last Idx , ensuring to contract range from last
so flipped {{2,8}}
 then nextRange = [0,7] let r = 4 them flipped = {{2,8},{4,7}}
Range = [0,6]
then r=2 (again randomly chosen then mapped Idx give 8)
but then flipped will be update to[0,6] range : {{2,6},{4,7}}

This makes sure random indices are always unpicked because:
total represents the number of unflipped spots.
Random picks from [0, total - 1] always avoid previously picked spots.

Then while return return as per 2D matrix
hence mappedIdx : m then i = m/cols and j = m%cols
eg 5 in matrix is at [1,2] but in 1D array : its at 5th index so m = 5 and cols = 3 so 
i = 5/3 = 1 
j = 5%3 = 2
[1,2] -> 5th index in 1D
# Complexity
- Time complexity: O(n*m) 1D flattened length
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: O(n*m)
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```java []
class Solution {
    int rows, cols, total; 
    Random random;
    Map<Integer,Integer> flipped;

    public Solution(int m, int n) {
        rows = m;
        cols = n;
        total = m*n;
        random  = new Random();
        flipped = new HashMap<>();
    }
    
    public int[] flip() {
        int r = random.nextInt(total);
        total -= 1;// shriking range to ensure unique picks
        // give the rowNo
        int mappedIdx = flipped.getOrDefault(r,r);// if r first time then init to r

        flipped.put(r , flipped.getOrDefault(total,total));// get the last position (if occupied then change it)
        // 2D to 1D
        return new int[]{mappedIdx / cols, mappedIdx%cols};
    }
    
    public void reset() {
        total = rows*cols;
        flipped.clear();
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(m, n);
 * int[] param_1 = obj.flip();
 * obj.reset();
 */
```
['Java']