【原創】python處理 面試題:迴文…
今日面試題:迴文分割
對一個字串按照迴文進行分割,例如aba|b|bbabb|a|b|aba就是字串ababbbabbababa的一個迴文分割,每一個字串都是一個迴文。請找到可以分割的最少的字串數。例如:
-
ababbbabbababa最少4個字串,分割三次:a|babbbab|b|ababa
-
如果字串整體是迴文,則需要0次分割,最少1個字串
==========================================================
刪除字元分析
原題
刪除字串中的“b”和“ac”,需要滿足如下的條件:
-
字串只能遍歷一次
-
不能夠使用額外的空間
例如:
-
acbac ==> ""
-
aaac ==> aa
-
ababac ==> aa
-
bbbbd ==> d
進一步思考:如何處理aaccac呢,需要做哪些改變呢?
分析
首先要明白從字串中刪除某些字元該如何實現,顯而易見我們可以把保留的字元拷貝新的字串中來實現刪除。但是題目要求不能使用額外的空間。那就是將要刪除的字元全部交換到字串的尾部,然後設定一個'\0'表示字串的結尾。
其次,如果要刪除的都是單個字元的字串,就很直接:我們使用i和j兩個變數遍歷字串,i表示不會刪除的字元的位置,j從0開始,只要i所在位置 的字元不是要刪除的字元,就str[j]=str[i](str表示字串),然後j++指向下一個位置。一次遍歷即可,不需要額外申請空間,只需要兩個 變數。
但是,現在刪除的字串中有多個字元的,如:“ac”。那要如何處理呢?這裡介紹一個小技巧:狀態機。這裡,我們有兩個狀態:ONE和TWO。TWO表示,前一個字元時‘a’的狀態,其他的都用ONE表示。還是採用前面所描述的遍歷方法:
-
如果當前狀態為ONE,則拷貝:str[j]=str[i];但如果當前字元滿足以下兩種狀態的任一個,則不進行拷貝:
-
-
當前字元是‘b’,因為我們要刪除b
-
當前字元是‘a’,我們要考慮下一個字元是c
-
-
如果當前狀態為TWO:
-
-
當前字元不是‘c’,那麼我們要先拷貝前一個字元‘a’
-
然後考慮當前字元,如果不是‘b’或者‘a’,則拷貝字元
-
狀態轉換非常簡單,就是每次都檢查,是前一個字元為‘a’。基本程式碼如下:
下面進一步考慮: 根據上面的演算法,我們考慮aaccac,最終得到ac。ac在題目中要求的也是要刪除的。是否要刪除這個ac,就需要和麵試官進行交流了,無論如何,總是 要考慮這種情況。還是採用上面的演算法,怎麼解決刪除之後還可以刪除的情況?其實非常簡單,只需要做很小的修改,我們在迴圈最後加上這個程式碼即可:
【分析完畢】
轉自:微信
試著用python寫寫 >>> def work(string): state=1 loc=0 st='' for i in range(len(string)): if state == 1 and string[i] != 'a' and string[i] != 'b': st +=string[i] loc += 1 if state == 2 and string[i] != 'c': st += 'a' loc += 1 if string[i] != 'a' and string[i] != 'b': st +=string[i] loc += 1 state = (string[i] == 'a') and 2 or 1 if state == 2: st += 'a' loc += 1 return st >>> work('aaccac') 'ac' >>> work('abcac') 'ac' >>> work('abbac') 'a' >>> work('acbac') '' >>> work('aaac') 'aa' >>> work('ababac') 'aa' >>> work('bbbbd') 'd' >>> 如上所示,雖然是照著程式碼搬下來的,但是成功了哦~ 特別提醒:state = (string[i] == 'a') and 2 or 1 同三元運算子有相同的效果,python不支援三元運算子,但是and or 在python中是十分強大的功能,前面有文章提到的《python Boolean/Bool - and, or, not》 三元運算子這麼寫的:state = (string[i] == 'a') ? 2 : 1 接著再看,原題,假如執行之後結果是ac,是否需要再次處理: >>> def work(string): state=1 loc=0 st='' for i in range(len(string)): if state == 1 and string[i] != 'a' and string[i] != 'b': st +=string[i] loc += 1 if state == 2 and string[i] != 'c': st += 'a' loc += 1 if string[i] != 'a' and string[i] != 'b': st +=string[i] loc += 1 state = (string[i] == 'a') and 2 or 1 if len(st)>1 and st[-1]== 'c' and st[-2]=='a': st=st[0:-2] if state == 2: st += 'a' loc += 1 return st >>> work('abcac') '' >>> 可以看到,同原題一樣在for迴圈最後加了一個判斷 if len(st)>1 and st[-1]== 'c' and st[-2]=='a': st=st[0:-2] 這是python資料型別特有的分片,簡單介紹一下,list tuple 通用。 st='abcdefg' st[0:2] --> 'abc' st[2:] --> 'cdefg' st[:-2] --'abcde' [x:] 第x位開始,至末尾(0開始) [x:y] 第x位至第y位 [:-x]0位開始,至倒數x位