【LeetCode】3.无重复字符串的最长子串
3.無(wú)重復(fù)字符串的最長(zhǎng)子串
一、問(wèn)題描述
給定一個(gè)字符串,請(qǐng)你找出其中不含有重復(fù)字符的?最長(zhǎng)子串?的長(zhǎng)度。
二、問(wèn)題簡(jiǎn)化
這個(gè)問(wèn)題本質(zhì)上是:
“從一個(gè)數(shù)組中,尋找最長(zhǎng)的子串,其元素均不相同”。
這里說(shuō)下子串和子序列的區(qū)別:子串是必須連續(xù)的,而子序列不一定連續(xù),但它們的順序是和原數(shù)組相同的。
字符串本質(zhì)是字符的數(shù)組,所以我們使用模板使其更通用化比較恰當(dāng)。
并且返回值仍然可以是多個(gè)。
所以整個(gè)函數(shù)可以表示為:
template<typename T> vector<T> GetSubLongest(const T& container)?三、功能實(shí)現(xiàn)
1.遍歷整個(gè)序列,iter0記為下標(biāo)。
2.從iter0遍歷到結(jié)束作為子串,或提前出現(xiàn)了不同元素。
3.第2步中保存的子序列,與最長(zhǎng)長(zhǎng)度判斷。如果更長(zhǎng),則刪除舊元素,加入自己到結(jié)果。如果一樣長(zhǎng)就只加入自己到結(jié)果中。如果更短,iter0自增,進(jìn)入下一個(gè)子串的開(kāi)始。
template<typename T> vector<T> GetSubLongest(const T& container) {vector<T> ret;int max_size = 0;T sub;//如果比最大長(zhǎng)度長(zhǎng),則加入返回值且更新最大長(zhǎng)度auto fn_addSub = [&](){if (sub.size() > max_size){ret.clear();ret.push_back(sub);max_size = sub.size();}else if (sub.size() == max_size){ret.push_back(sub);}};for (auto iter0 = container.begin(); iter0 != container.end(); ++iter0){sub.clear();auto iter1 = iter0;sub.push_back(*iter0);while (true){++iter1;if (iter1 == container.end()){//判斷加入,然后中斷fn_addSub();break;}auto iter_f = find(sub.begin(), sub.end(), *iter1);if (iter_f == sub.end()){//如果不是重復(fù)元素,則添加到subsub.push_back(*iter1);}else{//重復(fù)了,則檢測(cè)是否加入到返回值//判斷加入,然后中斷fn_addSub();break;}}}return ret; }四、測(cè)試結(jié)果
//輸入值如下:"我愛(ài)中國(guó),中國(guó)愛(ài)我!" { 1,1,2,5,3,2,2,7,8,8,9,1,0 } "abcabcbb" "pwwkew"可以看到,不僅對(duì)字符串有用,還對(duì)數(shù)字有效,甚至于任何事物(只要它們可以比較是否相同),這就是模板泛型算法的魅力。
在判斷子序列是否比以往的更長(zhǎng)時(shí),由于它會(huì)出現(xiàn)兩次,所以我寫(xiě)成了lambda表達(dá)式。盡量防止代碼重復(fù)出現(xiàn),是我編程的原則之一。
還有我使用的是wstring字符串,而不是string。前者是utf-16編碼,任何字符都只算一個(gè)。如果使用string,中文會(huì)算作兩個(gè),這樣算法就不可能正確處理漢字的相同判斷。在使用wcout輸出時(shí),需要設(shè)置一下本地化環(huán)境,調(diào)用wcout.imbue(locale("chs"));即可,但這還不是最通用化的寫(xiě)法,暫時(shí)這樣吧。
完整的代碼如下:
//3.無(wú)重復(fù)字符串的最長(zhǎng)子串#include <iostream> #include <string> #include <list> #include <vector> using namespace std;template<typename T> vector<T> GetSubLongest(const T& container) {vector<T> ret;int max_size = 0;T sub;//如果比最大長(zhǎng)度長(zhǎng),則加入返回值且更新最大長(zhǎng)度auto fn_addSub = [&](){if (sub.size() > max_size){ret.clear();ret.push_back(sub);max_size = sub.size();}else if (sub.size() == max_size){ret.push_back(sub);}};for (auto iter0 = container.begin(); iter0 != container.end(); ++iter0){sub.clear();auto iter1 = iter0;sub.push_back(*iter0);while (true){++iter1;if (iter1 == container.end()){//判斷加入,然后中斷fn_addSub();break;}auto iter_f = find(sub.begin(), sub.end(), *iter1);if (iter_f == sub.end()){//如果不是重復(fù)元素,則添加到subsub.push_back(*iter1);}else{//重復(fù)了,則檢測(cè)是否加入到返回值//判斷加入,然后中斷fn_addSub();break;}}}return ret; }int main() {wcout.imbue(locale("chs"));//0auto ret = GetSubLongest(wstring(L"我愛(ài)中國(guó),中國(guó)愛(ài)我!"));for (auto& iter : ret){wcout << iter << endl;}wcout << endl;//1auto ret1 = GetSubLongest(list<int>({ 1,1,2,5,3,2,2,7,8,8,9,1,0 }));for (auto& iter : ret1){for (auto& iter1 : iter){wcout << iter1;}wcout << endl;}wcout << endl;//2auto ret2 = GetSubLongest(wstring(L"abcabcbb"));for (auto& iter : ret2){for (auto& iter1 : iter){wcout << iter1;}wcout << endl;}wcout << endl;//3auto ret3 = GetSubLongest(wstring(L"pwwkew"));for (auto& iter : ret3){for (auto& iter1 : iter){wcout << iter1;}wcout << endl;}wcout << endl; }總結(jié)
以上是生活随笔為你收集整理的【LeetCode】3.无重复字符串的最长子串的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【LeetCode】2.两数相加
- 下一篇: 【LeetCode】4.寻找两个正序数组