1. 程式人生 > >資料結構與演算法 部分題目(字串)

資料結構與演算法 部分題目(字串)

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)