第 32 講:待定數(shù)組
在之前,其實我們已經(jīng)提到了ALS(即待定數(shù)組)的一些基本的使用方式和手段,但實際上待定數(shù)組還有很多話題要說,現(xiàn)在我們就來看看,ALS在鏈的章節(jié)里面會產(chǎn)生哪些有趣的內(nèi)容和知識。
Part 1?強ALS
1-1?同區(qū)域異數(shù)強關(guān)系引入

如圖所示,可以看到此時我們把r1c2(2)和r3c1(1)用強關(guān)系連起來,而它們是不同的數(shù)值。這是為什么呢?現(xiàn)在我們就來學(xué)習(xí)一下。
觀察紫色的兩個單元格r1c2和r3c1,可以發(fā)現(xiàn)此時兩個單元格只含有1、2、8三種不同的數(shù)字。如果此時假設(shè)r1c2(2)為假的時候,這兩個單元格里就沒有2了,如果再讓r3c1(1)也一并消失的話,兩個單元格就都只剩下唯一的一種候選數(shù)8,使得出錯。所以r1c2(2)為假時,需要r3c1(1)為真才行。
那么,可以發(fā)現(xiàn)r3c1(1)為真后,顯然r3c4(1)是為假的,所以形成弱關(guān)系;繼續(xù)推導(dǎo)的話,依然套用剛才的邏輯:觀察到{r12c5, r3c4}三個單元格包含1、2、3、8四種數(shù)字,而此時的r3c4(1)為假,也就意味著這三個單元格里不含有1。如果此時,這三個單元格的所有2也都消失的話,這三個單元格就同時少了兩種數(shù)字,便只剩下3和8,但這是三個單元格,填入兩個數(shù)字是顯然不夠的,所以也會矛盾。所以我們就得到了r3c4(1)=r12c5(2)的結(jié)論。
于是,這條鏈成立了:
這個例子就分析完畢了。其中可以發(fā)現(xiàn),{r1c2, r3c1}兩個單元格包含三種不同的數(shù)字,因為最終填數(shù)是待定的,所以這兩個單元格組成了一個待定數(shù)組結(jié)構(gòu),即一個ALS區(qū)域;同理,{r12c5, r3c4}三個單元格包含了四種不同的數(shù)字,所以填數(shù)也是不確定的,因此我們也稱為一個ALS區(qū)域。
可以從例子里看到,實際上,我們利用的ALS區(qū)域的邏輯是:n個單元格里包含(n + 1)種不同的候選數(shù),如果少掉其中的兩種,就會變?yōu)?n - 1)種候選數(shù),使得無法填滿n個單元格,進而出錯的結(jié)果。這便是ALS的核心。
另外,這個結(jié)構(gòu)的頭尾各使用了一個ALS,而中間用了弱關(guān)系連起來,是一個長度為3的鏈。我們把長度為3,且內(nèi)部的兩個強關(guān)系都產(chǎn)生自ALS的鏈稱為ALS-XZ法則(或ALS-雙強鏈法則,ALS-XZ Rule)。X和Z都表示涉及的數(shù)值,其中X是弱關(guān)系涉及的數(shù),而Z是鏈頭和鏈尾兩端涉及的數(shù)。
實際上,ALS分兩種,強ALS和弱ALS。為了和后續(xù)的內(nèi)容作出區(qū)分,我們強制稱這個結(jié)構(gòu)為強ALS(Strong ALS,但一般都簡稱為ALS,而它一般不簡稱為SALS),因為在后面的內(nèi)容里,ALS內(nèi)存在一種與之相反的弱ALS(Weak ALS,簡稱WALS),這種ALS只產(chǎn)生弱關(guān)系。一般來說,只要我們不強調(diào)它和弱ALS的邏輯和定義不同,我們都直接簡稱之為ALS。
另外,你可能會有一種感覺,之前的假設(shè)推理都是“順序確切的”,也就是推導(dǎo)到這里的時候,一定能確定是某個節(jié)點為真(因為是共軛對的關(guān)系,前面假后面就必須為真),而此時我們感覺這個結(jié)構(gòu)里兩個數(shù)之間的這種關(guān)系還差一點。比如這兩個單元格里同樣包含數(shù)字8。如果此時我們假設(shè)r1c2和r3c1兩個8全消失的話,兩個單元格也只剩下數(shù)字1可填,而且其中r1c2還沒有候選數(shù)了,也照樣會出錯。那豈不是我還可以得到r1c2(2)={r1c2, r3c1}(8)的結(jié)論?準確的答案是,是的。強弱關(guān)系并不需要確切的順序得到,如果像是上面這種邏輯,我們照樣可以得到一樣的結(jié)果,因為在強弱關(guān)系的敘述文字里,我們并未提到在推導(dǎo)過程里,節(jié)點之間必須是明確的順次推導(dǎo)關(guān)系。比如這里,我們完全可以走候選數(shù)8的方向;當然,這個8是兩個不同行列的單元格,用起來不方便而已,但客觀來說,強關(guān)系確實是形成了。
那么,你真的了解ALS這個縮寫嗎?我相信大多數(shù)小伙伴在讀到這里都是把這個詞匯死記硬背記住的。ALS實際上是Almost Locked Set的縮寫,而Locked Set,實際上是數(shù)組在早期的英文稱呼,現(xiàn)在數(shù)組被廣泛采用“子集”一詞(Subset),所以這個說法應(yīng)當為Almost Subset。而為了保持兼容性(保留原始說法以照顧以前的習(xí)慣),故這個說法繼續(xù)采用了Locked Set這個古老的說法;當然,你也可以采用Almost Subset這種說法。不過,可以看到它們的縮寫一個是ALS,一個則是AS,差距并不大,而表示同一個東西難免會讓人覺得不好理解,所以注意區(qū)分和辨別。
1-2?ALS-XZ和偽數(shù)組
我們再來看一則示例。

如圖所示,首先我們觀察到,r2c169三個單元格包含3、6、8、9四種數(shù)字,現(xiàn)在以r2c6(3)為假作為鏈的起點。假設(shè)它為假后,對于r2c9(8)而言,它必須為真,否則3和8沒有了之后,三個單元格里就只剩下了兩種數(shù)字,填不滿導(dǎo)致出錯。所以形成了強關(guān)系;然后用弱關(guān)系連接上r1c7(8)后,因為r1c7是雙值格的關(guān)系,顯然r1c7(3=8)成立,所以整體的鏈就成立了,刪數(shù)則是r2c6(3)和r1c7(3)的交集。
可以看到,這一則示例如果我們不使用鏈的視角,把鏈的線條去掉,并把8的涂色也去掉之后,{r1c7, r2c169}四個單元格將可以構(gòu)成偽數(shù)組結(jié)構(gòu):四個單元格里,除了數(shù)字3以外,其余的數(shù)字都只出現(xiàn)在一個區(qū)域里,即它們不可能有重復(fù)的填數(shù)情況,唯獨只有這里的3。而根據(jù)填數(shù)情況來分析可以發(fā)現(xiàn),3必須至少有一個要出現(xiàn),否則填不滿四個單元格。所以刪除掉數(shù)字3的交集。
所以,偽數(shù)組可以轉(zhuǎn)為ALS-雙強鏈結(jié)構(gòu),并且轉(zhuǎn)換方式是,把其中單獨跨區(qū)的那一個單元格分開單獨作為一個ALS;而剩下的單元格就必定在同一區(qū)域了,所以它們作為一個區(qū)域,于是我們連上強弱關(guān)系就可以形成ALS-XZ結(jié)構(gòu)了。
實際上,ALS最小可以只涉及一個單元格(只要這個單元格是雙值格,我們就可以使用ALS,因為從定義來看,它確實也符合條件,并且可以運用強關(guān)系:如果兩數(shù)同假,則“1個單元格只包含0個候選數(shù)”,這一點也都是符合剛才所說的推理過程的;而最多只能到8個單元格(因為此時最多包含了9種候選數(shù),也就是最大情況),不過實際上,這種結(jié)構(gòu)很少被使用,一般這種結(jié)構(gòu)都得不到什么合適的結(jié)論。
1-3?孿生ALS-XZ


如圖所示,我們來看這兩則示例,這兩則示例實際上是同一個題,而且結(jié)構(gòu)大部分內(nèi)容都是一樣的。
我們先來理解第一個示例,寫出它的文本表示形式。
在第一個示例里,是以r89c8(1)作為區(qū)塊節(jié)點起頭,假設(shè)為假的,顯然,r89c8兩個單元格里只有1、7、8三種候選數(shù),而如果r89c8(1)區(qū)塊節(jié)點為假,而且r8c8(7)也為假的話,則這兩個單元格就只剩下8這一種數(shù)字,顯然矛盾了;所以說r89c8(1)為假的時候,對于r8c8(1)來說就必須為真,所以它們形成強關(guān)系;然后,r5c8(7)和r46c9(1)的邏輯同理。
而第二個例子:
可以從例子看到,這里涉及了一個“拐彎的區(qū)塊”。我們嘗試把它看作和之前BUG區(qū)塊類型的那種“廣義的區(qū)塊”一樣的邏輯,把它們視為一起,那么這種結(jié)構(gòu)如果為真或為假兩種情況確實和普通的區(qū)塊節(jié)點的邏輯是一模一樣的。由于三個單元格同宮,所以視為一個節(jié)點后,它為假就只能使得其中沒有任意一個單元格填入這個數(shù);反之,如果這個節(jié)點為真,則也意味著其中只有一個單元格填入這個數(shù),這個說法和區(qū)塊節(jié)點的思維完全一樣。所以我們干脆就把它也稱為區(qū)塊節(jié)點。
首先,r89c8(8)=r8c8(7)是顯然的(這一點在上一情況已經(jīng)講到過);而對于r5c8(7)={r4c9, r5c89}(8),也是成立的:現(xiàn)在r5c8(7)是為假的,如果繼續(xù)向下推理,如果{r4c9. r5c89}(8)這個節(jié)點也為假的話,就意味著里面沒有一個單元格能放下8,此時8也沒有了,而細數(shù){r5c8, r456c9}四個單元格,里面一共是1、3、4、7、8五種數(shù)字,而此時由于兩個節(jié)點同假的假設(shè)的關(guān)系,四個單元格里同時少了全部的7和8,導(dǎo)致只剩下了1、3、4三種數(shù),而它必須放在這四個單元格里,這樣顯然是不夠放下的。所以,這樣便出現(xiàn)了矛盾。
可以看到,兩個情況下,除了開頭和結(jié)尾的節(jié)點不一致以外,弱關(guān)系相連的數(shù)字7是完全一樣的節(jié)點,而切換到不同的頭尾,就會產(chǎn)生不同的刪數(shù),我們稱之為孿生ALS-XZ(Siamese ALS-XZ),孿生一詞已經(jīng)在鏈列(魚)結(jié)構(gòu)里出現(xiàn)過,正好表達的是“大部分結(jié)構(gòu)相同,而不同的地方能導(dǎo)致不同的刪數(shù)”之意。而實際上,這種結(jié)構(gòu)和孿生鏈列一樣,我們依然可以合并為一個圖,如圖所示。請你思考一下這個合并的示例如果整體,應(yīng)該如何推理。
