資料結構與演算法 部分題目(字串)
1.求陣列中兩個字串的最小距離
題目:
給定一個數組 strs,其中的資料都是字串,給定兩個字串 str1,str2。如果這兩個字串都在 strs陣列中,就返回它們之間的最小距離;如果其中任何一個不在裡面,則返回 -1;如果兩個字串相等,則返回 0。
例如:給定[‘*’,’3’,’*’,’5’,’10’,’9’,’7’,’1’,’*’],再給定兩個字串’* ‘和’9’,通過函式求得返回值 3。
O(n**2)時間複雜度
def min_distance_1(strs, str1, str2): if str1 not in strs or str2 not in strs: return -1 if str1==str2: return 0 dist, min=1, len(strs) pos1, pos2=0, len(strs) for i in range(0, len(strs)): if str1==strs[i]: pos1=i for j in range(0, len(strs)): if str2==strs[j]: pos2=j dist=abs(pos1-pos2) if dist<min: min=dist return min
採用雜湊表,O(1)時間複雜度
def min_distance_2(strs, str1, str2): if str1 not in strs or str2 not in strs: return -1 if str1 == str2: return 0 def create_hash(strs): strs_set=list(set(strs)) dist_hash={} for i in range(0, len(strs_set)): temp={} for j in range(0, len(strs_set)): if strs_set[i]!=strs_set[j]: dist = min_distance_1(strs, strs_set[i], strs_set[j]) temp[strs_set[j]] = dist dist_hash[strs_set[i]] = temp return dist_hash return create_hash(strs)[str1][str2]
2.分解調整字串中的字元
題目:
給定一個字元型別的陣列 chas[],其中只有數字和 “*”星型字元,現在想把所有的星型字元挪到陣列的左邊,數字字元全部放到右邊,順序不許變。
def replace_starts(str_list): j=len(str_list)-1 for i in range(len(str_list), -1, -1): if str_list[i]!='*': str_list[j]=str_list[i]: j-=1 for i in range(0, j+1): str_list[i]='*' return str_list
3.將字串中的空字元全部替換為別的字串
題目:
給定一個字元型別的陣列 chas[], 其右半邊全部是空字元,左半邊沒有空字元;現在需要將左半邊所有的空格space替換為 “%20”,現在的假設是右半邊足夠大,不需要考慮這個空間。
例如:chas = [’ ‘,’a’,’ ‘,’b’,’ ‘,’ ‘,’g’]
輸出的結果是 [‘%’, ‘2’, ‘0’, ‘a’, ‘%’, ‘2’, ‘0’, ‘b’, ‘%’, ‘2’, ‘0’, ‘%’, ‘2’, ‘0’, ‘g’]
def replace_space(self, str_list): # 字串的調整與替換,時間複雜度o(n),空間複雜度o(1)
num = 1
for i in xrange(0, len(str_list)):
if str_list[i] == ' ':
num += 1
length = len(str_list) + 2 * num - 2
i = k = len(str_list)
while i < length:
str_list.append('0')
i += 1
i -= 1
for j in xrange(k-1, -1, -1): # 逆序
if str_list[j] == ' ':
str_list[i] = "0"
i -= 1
str_list[i] = "2"
i -= 1
str_list[i] = "%"
i -= 1
else:
str_list[i] = str_list[j]
i -= 1
return str_list
4.在有序但含有None的陣列中查詢字串
題目:
給定一個字串陣列 str[],其中有一些位置是 None,但在不是 None 的位置上,其字串是按照字典的順序由小到大依次出現的。再給定一個字串 str,返回 str在 strs中出現最左的位置。
例如:
strs = [‘a’, None, ‘b’, None, ‘d’, ‘d’, None, ‘k’,’m’]
str = ‘d’
返回 4。
如果沒有找到該字元,即不存在,或者str = None,都返回 -1
def get_index(alist, target):
index=-1
left=0
right=len(alist)-1
if target is None:
return -1
while left<=right:
mid=(left+right)/2
if alist[mid]==target:
index=mid
right=mid-1
elif alist[mid]==None:
i=mid-
while left <= right:
mid = (left + right) / 2
if str_list[mid] == str:
index = mid
right = mid - 1
elif str_list[mid] == None:
i = mid - 1
while 0 < i < mid:
if str_list[i] != None:
break
else:
i -= i
if ord(str_list[i]) == ord(str):
index = i
right = i - 1
elif ord(str_list[i]) > ord(str):
right = i
else:
left = mid + 1
else:
if ord(str_list[mid]) > ord(str):
right = mid - 1
else:
left = mid + 1
return index
5.判斷字元陣列中是否所有的字元都只出現過一次
題目:
給定一個數組,判斷其中所有的字元是不是都只出現過一次。
def is_unique_1(self, str_list): # 判斷字元型別陣列中的字元是否均只出現過一次,時間複雜度o(n)
if str_list == "":
return False
i, map = 0, [0]
while i < 256:
map.append(0)
i += 1
for i in xrange(0, len(str_list)):
map[ord(str_list[i])] += 1
if map[ord(str_list[i])] != 1:
return False
return True
6.獲取字串的統計字串
題目:
給定一個字串 str,返回 str 的統計字串。
例如:“fffjkk99999022____”,其統計字串是“f_3_j_1_k_2_9_5_0_1_2_2___4”
def get_count_str(string): # 獲取字串的統計字串
if string == "":
return ""
count = 0 # 計算某一種型別的字元的數量
char = string[0]
count_str = "" # 存放統計字串
for i in range(0, len(string)):
if char != string[i]:
count_str += char + "_" + str(count) + "_"
char = string[i]
count = 1
else:
count += 1
count_str += char + "_" + str(count)
return count_str
7.將整數字符串轉成整數值
題目
給定一個字串,如果其中所有的字元都是數字,且符合人們日常的書寫規範,則返回該整數值,否則返回0。
例如:“123”,返回123;
“038123”,返回0;
“dfa423”,返回0;
“-482”,返回-482;
“-03”,返回0。
def str_int(string):
if string == "":
return False
if len(string)==1:
if 48<ord(string)<=57:
return string
else:
if string[0]=='-':
if string[1]==0:
return 0
else:
return string
elif 48<ord(string[0])<=57:
return string
else:
return 0
8.判斷兩個字串是否互為旋轉詞
題目
如果將一個 str1 從任意的位置切分開,分成兩部分,將後面一部分放置在前面, 再組合起來成為 str2,構成了旋轉詞。
例如:str1 = “apple”,str2 = “leapp”,兩個詞就是旋轉詞.
def is_roatation(str1, str2):
if str1=="" or str2=="" or len(str1)!=len(str2):
return False
return str1==str2[::-1]
9.去掉字串當中的連續k個0
題目:
給定字串str 和一個整數k。如果str中恰好出現了連續的k個0,則將k個0刪除。
比如,給定字串str = “0000fw300001203h000ui0000re3_0000”,k=4。返回的結果為“fw31203h000uire3_”。
def remove_k_zeors(string, k):
a=str(0)*k
return string.replace(a, '')
10.計算字串中所有數字之和
題目:
給定一個字串,計算其中所有數字的和。其中,不考慮小數點,如果有奇數個“-”號,則數字為負,偶數個則數字為正。
例如,“a12b3mnh4”, 返回值19,
“-2fds—-43fnd”,返回值41。
def sum_of_num(string):
sum, num, pos=0, 0, 1
if string == " ":
return 0
for i in range(0, len(string)):
if 0<=string[i]<=9:
num=num*10+int(string[i])*pos
else:
sum+=num
num=0
if string[i]='-':
if i-1>1 and string[i-1]="-":
pos=-pos
else:
pos=-1
else:
pos=1
sum+=num
return sum
11.判斷兩字串是否互為變形詞
題目:
給定兩個字串,str1,str2,判斷兩個字串中出現的字元是否全部種類一樣,數量一樣。
例如:
str1 = “apple”, str2 = “paple”, 返回 True;
str1 = “pear”, str2 = “bears”, 返回 False。
def is_deformation(str1, str2):
if str1 is None or str2 is None or len(str1) != len(str2):
return False
i, map = 0, [0]
while i <= 256:
map.append(0)
i += 1
for i in range(0, len(str1)):
map[ord(str1[i])] += 1
for i in range(0, len(str2)):
if map[ord(str2[i])] == 0:
return False
return True
12.Anagrams 歸類
題目
給出一組字串,返回其中所有的 Anagrams。
比如, 給出 [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
返回
[
[“ate”, “eat”,”tea”],
[“nat”,”tan”],
[“bat”]
]
所有字母不分大小寫。
def group_anagrams(strings):
dict_1, ans={}, []
for i in strings:
i=i.lower()
sort_str=''.join(sorted(i))
if sort_str in dict_1:
dict_1[sort_str]+=[i]
else:
dict_1[sort_str]=[i]
for i in dict_1:
tmp=dict_1[i]
ans+=[tmp]
return dict_1, ans
13.括號字串的相關問題
題目:
1、給定一個字串,判斷這個字串是不是有效的括號字串,也就是滿足數學算式可算性。比如,str=”(()(())())”,返回 True,給定str = “(()((())(())”,返回False。如果括號字串中摻雜了其它的字元,則返回False
2、給定一個括號字串,找出其中最大的子串長度,比如:給定str = “(()((())(())”,返回 8。
def brackets_is_valid_1(str):
'''
判斷括號字串是不是有效括號字串,比如:"()()"為 True,"(()())"為 True,"())","(())"等等均為 False
方法1:建立一個棧操作,時間複雜度為一遍遍歷,但是空間複雜度較高。
:param str: 括號字串
:return: True 或者 False
'''
stack = []
for i in xrange(0, len(str)):
if str[i] != "(" and str[i] != ")":
return False
if str[i] == "(":
stack.append("(")
else:
stack.pop()
if stack != []:
return False
else:
return True
def brackets_is_valid_2(str):
'''
判斷括號字串是不是有效括號字串,比如:"()()"為 True,"(()())"為 True,"())","(())"等等均為 False
方法2:時間複雜度不變,仍是一遍遍歷的,但是空間複雜度只有o(1)。
:param str: 括號字串
:return: True 或者 False
'''
num1, num2 = 0, 0
for i in xrange(0, len(str)):
if str[i] != "(" and str[i] != ")":
return False
if str[i] == "(":
num1 += 1
else:
num2 += 1
if num1 < num2:
return False
if num1 == num2:
return True
else:
return False
def longest_sub_brackets(str):
'''
給定一個括號字串 str,返回最長的有效括號字串
方法:動態規劃求解,做到時間複雜度 o(n),空間複雜度 o(n)。建立一個與字元串同等長度的陣列 dp[],
其含義是對應 str[i]結尾的字串的最長有效子串的長度。然後即可開始求解。
:param str: 給定的括號字串
:return: 最長有效子串
'''
print str
dp = []
for _ in xrange(0, len(str)):
dp.append(0)
for i in xrange(0, len(str)):
if str[i] == "(":
dp[i] = 0
if str[i] == ")":
if i != 0:
pre = i - dp[i-1] - 1
if str[pre] == "(":
dp[i] = dp[i-1] + 2 + dp[pre-1]
return max(dp)