1. 程式人生 > >【原創】python處理 面試題:迴文…

【原創】python處理 面試題:迴文…

今日面試題:迴文分割

對一個字串按照迴文進行分割,例如aba|b|bbabb|a|b|aba就是字串ababbbabbababa的一個迴文分割,每一個字串都是一個迴文。請找到可以分割的最少的字串數。例如:

  1. ababbbabbababa最少4個字串,分割三次:a|babbbab|b|ababa

  2. 如果字串整體是迴文,則需要0次分割,最少1個字串

==========================================================

刪除字元分析

原題

刪除字串中的“b”和“ac”,需要滿足如下的條件:

  1. 字串只能遍歷一次

  2. 不能夠使用額外的空間

例如:

  1. acbac   ==>  ""

  2. aaac    ==>  aa

  3. ababac  ==>  aa

  4. bbbbd   ==>  d

進一步思考:如何處理aaccac呢,需要做哪些改變呢?

分析

首先要明白從字串中刪除某些字元該如何實現,顯而易見我們可以把保留的字元拷貝新的字串中來實現刪除。但是題目要求不能使用額外的空間。那就是將要刪除的字元全部交換到字串的尾部,然後設定一個'\0'表示字串的結尾。

其次,如果要刪除的都是單個字元的字串,就很直接:我們使用i和j兩個變數遍歷字串,i表示不會刪除的字元的位置,j從0開始,只要i所在位置 的字元不是要刪除的字元,就str[j]=str[i](str表示字串),然後j++指向下一個位置。一次遍歷即可,不需要額外申請空間,只需要兩個 變數。

但是,現在刪除的字串中有多個字元的,如:“ac”。那要如何處理呢?這裡介紹一個小技巧:狀態機。這裡,我們有兩個狀態:ONE和TWO。TWO表示,前一個字元時‘a’的狀態,其他的都用ONE表示。還是採用前面所描述的遍歷方法:

  1. 如果當前狀態為ONE,則拷貝:str[j]=str[i];但如果當前字元滿足以下兩種狀態的任一個,則不進行拷貝:

    1. 當前字元是‘b’,因為我們要刪除b

    2. 當前字元是‘a’,我們要考慮下一個字元是c

  2. 如果當前狀態為TWO:

    1. 當前字元不是‘c’,那麼我們要先拷貝前一個字元‘a’

    2. 然後考慮當前字元,如果不是‘b’或者‘a’,則拷貝字元

狀態轉換非常簡單,就是每次都檢查,是前一個字元為‘a’。基本程式碼如下:

【原創】python處理 <wbr>面試題:迴文分割、及刪除字元分析

下面進一步考慮: 根據上面的演算法,我們考慮aaccac,最終得到ac。ac在題目中要求的也是要刪除的。是否要刪除這個ac,就需要和麵試官進行交流了,無論如何,總是 要考慮這種情況。還是採用上面的演算法,怎麼解決刪除之後還可以刪除的情況?其實非常簡單,只需要做很小的修改,我們在迴圈最後加上這個程式碼即可:

【原創】python處理 <wbr>面試題:迴文分割、及刪除字元分析

【分析完畢】

轉自:微信 

試著用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') ? : 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位