T36. Valid Sudoku【Medium】
題目
這是一道數(shù)獨(dú)題,如何確定數(shù)獨(dú)有效,參考 數(shù)獨(dú)規(guī)則
數(shù)獨(dú)板可以是部分填充的,其中空單元填充字符'.'。
以上是一個(gè)部分填充了的有效的數(shù)獨(dú)游戲。
注意:
有效的 數(shù)獨(dú)游戲 板(部分填充)不一定可解。需要驗(yàn)證的只有已經(jīng)填充的單元格。
思路
首先,審題,不用算是否可解,那題目一下子就變得簡(jiǎn)單了起來(lái),這時(shí)候就是理解規(guī)則并且按規(guī)則來(lái)判斷就可以了。
總的來(lái)說(shuō),要判斷三個(gè)方面:
① 同行有沒(méi)有重復(fù)
② 同列有沒(méi)有重復(fù)
③ 同九宮格有沒(méi)有重復(fù)
(不知道為什么的看數(shù)獨(dú)規(guī)則哈:))
代碼很巧妙,
① 通過(guò) 給數(shù)字編碼(加標(biāo)簽)來(lái)限定范圍
② 依靠了 HashSet 來(lái)判斷重復(fù)
編碼方式:
- 第 7 行的數(shù)字 '4' 編碼以后是 "(4)7"
- 第 7 列的數(shù)字 '4' 編碼以后是 "7(4)"
- 右上方九宮格(第 1 行 第 3 列)的數(shù)字 '4' 編碼以后是 "0(4)2"
具體看代碼以及注釋~
代碼
代碼取自 Top Solution,稍作注釋
public boolean isValidSudoku(char[][] board) {
Set seen = new HashSet();
for (int i=0; i<9; ++i) {
for (int j=0; j<9; ++j) {
if (board[i][j] != '.') {
//給數(shù)字加()
String b = "(" + board[i][j] + ")";
//先編碼再加入數(shù)組,然后若重復(fù),則 add() 方法返回false,然后進(jìn)入 if,return false
if (!seen.add(b + i) || !seen.add(j + b) || !seen.add(i/3 + b + j/3))
return false;
}
}
}
return true;
}
補(bǔ)充
① 先補(bǔ)充一下 HashSet 的 add() 方法:
public boolean add(Object o)方法用來(lái)在Set中添加元素,當(dāng)元素值重復(fù)時(shí)則會(huì)立即返回false,如果成功添加的話會(huì)返回true。
② 然后總結(jié)收獲 (*?????)?。
這題讓我學(xué)到了:
判斷是否重復(fù)可以用 HashSet 的 add() 方法的返回值來(lái)判斷。
同時(shí),自己制定規(guī)則通過(guò)給 String 加上特定編碼也是一種簡(jiǎn)單好用的分類(lèi)方法。