面試之演算法基礎系列(1)最長子字串 字串同構

2021-10-13 18:02:49 字數 3365 閱讀 9250

題目為:

最容易想到的是暴力解法,就是遍歷求出字串的所有子串,並找出不同字元為k的最長字元,python**如下:

def

find_max_substring

(string, k)

: str_length =

len(string)

sub_string_list =

(string[i:i + j +1]

for j in

range

(str_length)

for i in

range

(str_length - j)

) length_list =

for sub_string in sub_string_list:

iflen

(set

(list

(sub_string)))

== k:

len(sub_string)

)return

max(length_list)

if __name__ ==

'__main__'

: string =

input()

k =int(

input()

) max_length = find_max_substring(string, k)

print

(max_length)

顯然,這種實現方式效率是很低的,雖然使用了生成器,但是在效能方面還是有很大的問題,同時未考慮特殊情況。

後來查詢了一些資料,使用了同向雙指標和字典來對實現方式進行了優化:

def

find_max_substring

(string, k)

: str_length =

len(string)

if str_length ==

0or k ==0:

return

0 count =

0 left =

0 right =

0 res =

0 count_dic =

while right < str_length:

if string[right]

notin count_dic or count_dic[string[right]]==

0:count +=

1 count_dic[string[right]]=

1else

: count_dic[string[right]]+=

1 right +=

1while count > k:

count_dic[string[left]]-=

1if count_dic[string[left]]==

0:count -=

1 left +=

1 res =

max(res, right - left)

return res

if __name__ ==

'__main__'

: string =

input()

k =int(

input()

) max_length = find_max_substring(string, k)

print

(max_length)

在字串長度為0或者k為0時直接返回0;

通過使用同向雙指標的方式,可以做到只遍歷一次字串就能得到答案,從而使時間複雜度為o(n),在字串上移動滑動視窗的兩個指標,來保證視窗內的字元不超過k個,具體如下:

此時執行結果如下:

可以看到,執行效率還是相對較快的。

可以在使用ide進行執行測試和效能評估。

題目為:

可以看到,實際上就是判斷字串是否結構相同,可以按照如下思路實現:

兩個字串對應位置上的字母要具有一一對應的關係,如果s[i]為a、t[i]=b,則a對應的就是b,如果後面s[j]為a,則t[j]也必須為b,若t[j]為其他字母,則判定為非同構

要實現這種一一對應關係,可以使用字典,具體如下:

如果兩個字串長度不同,直接返回false;

如果字典中沒有相應成對字母,就在字典中加入字母對;

如果鍵已經存在,判斷一下t中對應的字母是否和字典中對應的值相同,不相同則肯定是非同形態,相同則繼續迴圈;

如果s中不同的字母,對應了t中相同的值,即不同的鍵對應的值相同,例如s='mn't=『mm』,這是屬於非同構的,可以通過判斷鍵、值的唯一值個數來判斷是否屬於這種情況。

python**實現如下:

def

is_isomorphic

(s, t)

: s_len =

len(s)

if s_len !=

len(t)

:return

false

char_pair =

for i in

range

(s_len)

:if s[i]

notin char_pair:

char_pair[s[i]

]= t[i]

elif char_pair[s[i]

]!= t[i]

:return

false

return

len(char_pair)

==len

(set

(char_pair.values())

)if __name__ ==

'__main__'

: s =

'egg'

t ='add'

res = is_isomorphic(s, t)

print

(res)

示例輸出:

true
leetcode測試結果如下:

面試演算法 1 無重複字元的最長子串

示例 1 輸入 abcabcbb 輸出 3 解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。示例 2 輸入 bbbbb 輸出 1 解釋 因為無重複字元的最長子串是 b 所以其長度為 1。示例 3 輸入 pwwkew 輸出 3 解釋 因為無重複字元的最長子串是 wke 所以其長度為 3。請...

最長子序列問題之系列一

求解最大連續子串行和問題,最直接的辦法就是求出每個連續子串行的和,然後找出最大和即可,但這種演算法的效率為o n 2 如下,int ls return max 這種演算法適用於資料量比較小的情況。在這種方法裡,有許多不必要的重合計算,而正是這些不必要的計算影響了程式的執行效率。為了提高演算法的效率,...

1 無重複字元的最長子串

給定乙個字串,請你找出其中不含有重複字元的最長子串的長度。示例 1 輸入 abcabcbb 輸出 3解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。示例 2 輸入 bbbbb 輸出 1解釋 因為無重複字元的最長子串是 b 所以其長度為 1。示例 3 輸入 pwwkew 輸出 3解釋 因為...