One suggestion is this:
you could have an array with values from 1 to N*N like this: (example)
int [] oneDim= {1,2,3,4,5,6,7,8,9};
Generate a random number from 0 to
8.
Take that number and put it inside the 2-sized array.Use a for loop that puts the first taken number to (0,0).
Then use a swap method that takes the selected number and puts it at the end of the 1-sized array:
example: if the random number was 4, Then the oneDim[4]=5 will be put at the target 2-sized array, and after the swap the oneDim will be like this: {1,2,3,4,
9,6,7,8,
5}
Then you will repeat the above procedure with one difference: the random generated number will be from 0 to
7. So when you go to the oneDim array you will take only the first 8 numbers: {1,2,3,4,9,6,7,8} and you will not take the last which is already used: 5
int [] oneDim= new int[N]
int [][] randoms=[N][N];
for (int i=0;i<N;i++) {
oneDim[i]=i+1;
}
int row=0;
int col=0;
for (int i=0;i<N;i++) {
int r = //random number from 0 to N-1
//put the value from oneDim to randoms
randoms[row][col] = oneDim[r];
//swap oneDim[r] with oneDim[N-1 - i] //N-1 - i : so not to keep swapping a number that was previously used and was put at the end
//alter row, col so as to put the next number at a new place
}