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.