目录
本文题目编译自 Donne Martin 的开源项目
002确定字符串是否是另一个的排列
实现一个算法来识别一个字符串 str2
是否是另一个字符串 str1
的排列。排列的解释如下:
- 如果将
str1
的字符拆分开,重新排列后再拼接起来,能够得到str2
,那么就说字符串str2
是字符串str1
的排列。
解:
本题初看想用全排列,再思发觉用sorted函数快速解决
sorted(str1)==sorted(str2)
sorted方法用来进行排序操作,如数字,字符串组成的list,根据dict类型的key或者value排序,现将平时使用的sorted的方法和数据类型进行整理。本题是罕见的直接对字符串排序
003确定字符串是否是另一个的旋转
实现一个算法来识别一个字符串 s2
是否是另一个字符串 s1
的旋转。旋转的解释如下:
- 如果将
s1
从某个位置断开,拆分成两个字符串(可能有一个为空字符串),再将这两个字符串调换顺序后拼接起来,能够得到s2
,那么说字符串s2
是字符串s1
的旋转。
解:
class Rotation(object):
def is_substring(self, s1, s2):
return s1 in s2
def is_rotation(self, s1, s2):
if s1 is None or s2 is None:
return False
if len(s1)!=len(s2):
return False
return self.is_substring(s1,s2+s2)
由于s2字符串旋转点的不确定性、子字符串判断函数is_substring()考虑到了有序性,巧妙地利用加倍延长证明全等(中学数学)的思想,对s2加倍,在长度判断后判断子字符串。
005压缩字符串
实现一个算法来压缩一个字符串。压缩的要求如下:
- 需要判断压缩能不能节省空间,仅在压缩后字符串比原字符串长度更短时进行压缩。
- 压缩的格式是将连续相同字符替换为字符+数字形式,例如
"AAABCCDDDD"
变为"A3BC2D4"
。
解:(标答)
class CompressString(object):
def compress(self, string):
if string is None or not string:
return string
st_char=string[0]//当前压缩字符标志位
count=0
result=''
for char in string:
if char==st_char:
count+=1
else:
result+=self.add(st_char,count)
st_char=char//更换压缩字符
count=1
result+=self.add(st_char,count)
return result if len(result)<len(string) else string//长度判断避免发生AA->A2的情况
def add(self,st_char,count)://专用于返回压缩后的字符加数字
return st_char+(str(count) if count>1 else '')
本题陷阱:压缩结果未必一定比原字符串短,只有更短才能输出,含有AA、AABB的双型字符串要警惕长度不变。
006找到给定字符串中的不同字符
在不考虑字符排列的条件下,对于相差只有一个字符的两个字符串,实现一个算法来识别相差的那个字符。要求如下:
- 当传入的字符串为
'aad'
和'ad'
时,结果为'a'
。 - 当传入的字符串为
'aaabccdd'
和'abdcacade'
时,结果为'e'
。
解:
第一种思路是字符数字化后,再字符化,利用差额转换。
class Solution(object):
def find_diff(self, str1, str2):
if str1 is None or str2 is None:
raise TypeError('str1 or str2 cannot be None')
s1,s2=0,0
for char in str1:
s1+=ord(char)
for char in str2:
s2+=ord(char)
return chr(abs(s1-s2))//仅相差一个字符,可以用Unicode编码转换数字化后再字母化
第二种思路是利用异或运算,出现两次的不影响结果,出现一次的留下痕迹
class Solution(object):
def find_diff(self, str1, str2):
if str1 is None or str2 is None:
raise TypeError('str1 or str2 cannot be None')
result = 0
for char in str1:
result ^= ord(char)
for char in str2:
result ^= ord(char)
return chr(result)
此外,raise TypeError('错误原因相关语句')使用较少
007查找两个总和为特定值的索引
给定一个数组,找到两个总和为特定值的索引。
- 例如给定数组
[1, 2, 3, -2, 5, 7]
,给定总和7
,则返回索引[1, 4]
。
解:(标答)
传统解法是双重遍历,复杂度过高。
引入枚举enumerate,方便同时遍历索引和数值;引入字典,以差值为键存入当前索引(记作x),当遍历到差值时,可以直接取出x;这是以空间换时间的解法。
class Solution(object):
def two_sum(self, nums, val):
if nums is None or val is None:
raise TypeError('Type is None')
if len(nums)==0:
raise ValueError('Value is not existed')
lth=len(nums)
dic={}
for i,num in enumerate(nums)://使用枚举,更便捷地对索引和数值同时遍历
res=val-num
if num in dic:
return [dic[num],i]
else:
dic[res]=i
return None