I take a minute in class and ask you to write it. Here's my solution:
bool Sudoku::Is_Row_Ok(int r) const
{
vector <int> checker; /* Use this to make sure no digit is set twice. */
int c;
checker.clear();
checker.resize(10, 0);
for (c = 0; c < 9; c++) {
if (puzzle[r][c] != '-') {
if (checker[puzzle[r][c]-'0']) return 0;
checker[puzzle[r][c]-'0'] = 1;
}
}
return 1;
}
|
The solution uses a 10-element vector to keep track of whether we've seen a number before. The running time complexity of this is simple -- O(n) where n is the number of elements in the row. That's as well as you can do.
Let's look at some worse solutions:
bool Sudoku::Is_Row_Ok(int r) const
{
int i, j;
for (i = 0; i < puzzle[r].size(); i++) {
if (puzzle[r][i] != '-') {
for (j = i+1; j < puzzle[r].size(); j++) {
if (puzzle[r][i] == puzzle[r][j]) return false;
}
}
}
return true;
}
|
This is O(n2) because in the first iteration, the j loop can go n-1 elements. The next iteration is n-2 and so on. That's O(n2).
Here's another one:
bool Sudoku::Is_Row_Ok(int r) const
{
char i;
for (i = '1'; i <= '9'; i++) {
if (puzzle[i].find(i) != puzzle[i].find_last_of(i)) return false;
}
return true;
}
|
While this is clever, it's also O(n2) because find() and find_last_of() both can run through the entire string.
And a last one:
vector <string> puzzle;
bool Is_Row_Ok(int r)
{
char i;
for (i = '1'; i <= '9'; i++) {
if (puzzle[r].count(i) > 1) return false;
}
return true;
}
|
Well, first, there's no count() method of strings. And second, even if there were, it would be O(n2) again, because it would go through the entire string for each character.