【原创】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   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  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  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位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值