【演算法拾遺】阿里實習生電面題目:輸出給定字串的全部連續子串
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/21043665
今天下午阿里電面的題目,給定一個字串,輸出其所有連續子串,如:給定字串為abcd,則要輸出的其全部連續子串為:a,b,c,d,ab,bc,cd,abc,bcd,abcd。
很快給出了最簡單的方法,就是先從第一個字元遍歷,向後輸出,再從第二個字元開始遍歷,向後輸出,依此類推,直到開始遍歷的字元為陣列的最後一個字元。這個時間複雜度很高啊,要O(n*n*n)。
接下來就假設字串很大,想優化的方法,不知道腦子是短路了還是咋地,居然聯想到Trie樹上去了,完全不沾邊的東西。電面後想了下,感覺應該用遞迴,吃完飯,去圖書館用紙畫了下,就是遞迴(還是A題A的少啊!)。後來寫出來程式碼感覺貌似木有提高時間複雜度哦!
先貼出來吧,首先是最簡單的遍歷法,時間複雜度為O(n*n*n)
/*
蠻力求解法
*/
void AllSubstring1(const char *str,int high)
{
int i, j, k;
if(!str)
return;
for(i=0;i<=high;i++)
{
for(j=i; j<=high;j++)
{
for(k = i; k<=j; k++)
printf("%c", str[k]);
printf("\t");
}
printf("\n");
}
}
而後我又減少了一層迴圈,增加了一個遞迴操作,如下:
/*
遞迴求解法
*/
void AllSubstring2(const char *str,int low,int high)
{
int i;
int cur = high;
if(!str)
return;
while(low <= cur)
{
for(i=low;i<=cur;i++)
printf("%c",str[i]);
printf("\t");
cur--;
}
printf("\n");
if(low<high)
{
AllSubstring2(str,low+1,high);
}
}
但是感覺時間複雜度沒有提高啊(分治策略的遞迴代替迴圈,可以將時間複雜度從O(n)降到O(logn),當然是每次將問題減到一半分治策略,若果是類似斐波那契序列的分治,效果更差。每層遞迴只減少一個元素的遞迴無法降低時間複雜度)!我在紙上大致算了下。遞迴求解的時間複雜度按如下公式推導:T(n) = T(n-1) + n*n
這樣應該得到:
T(n) = n*n + (n-1)*(n-1) +...+2*2 + 1 = n(n+1)(2n+1)/6
時間複雜度還是O(n*n*n)!!
而且感覺還可以用一個遞迴來替代上面的一層迴圈,沒時間想了,圖書館要關門了,還要去跑步,明天又要跟導師彙報,暫時先擱一擱吧!忙完了再回來思考下,大家有好的思路的話,希望在下面貼出來!
後續
沒想到發生來一天不到,那麼多人回覆,很感謝大家的熱心思考啊!而且看時間有些人是熬夜寫的程式碼啊,不由心生佩服,不過希望要多注意身體哈。
很多人都採用瞭如下程式碼來進行優化(我稍微做了些改動,測試通過)
/*
迴圈輸出子串
*/
void AllSubstring3(const char *str,char *arr)
{
//穿入的arr的長度為len+1,最後一個位置儲存'\0'
int i,j;
unsigned int len = strlen(str);
strcpy(arr,str);
for(i=len-1;i>=0;i--)
{
arr[i+1] = '\0';
for(j=i;j>=0;j--)
printf("%s\t",&arr[j]);
printf("\n");
}
}
採用直接列印子串的方法,減少了一個迴圈,18樓說的在理,這樣只是程式碼間簡潔了些,但直接輸出字串和諸葛輸出字元效果是一樣的,因此複雜度並沒有降低。
假設沒有重複的情況,連續子串的數目為sum = n + n-1 + n-2 +...+2+1 = n(n-1)/2,但是因為基本的操作是輸出單個字元,因此輸出次數也就達到了sum*n的級別了,時間複雜度最優貌似也就是O(n*n*n)了,這樣看來貌似就沒什麼可優化的餘地嘍!!求解。。
再次感謝大家的思考和回覆,最近忙死鳥,不能一一細看和回覆,望見諒!!
相關文章
- 【演算法拾遺】三種方法求連續子陣列的最大和演算法陣列
- python3字串輸出常見面試題目有哪些?Python字串面試題
- 【演算法拾遺】子陣列的最大乘積演算法陣列
- 阿里實習生內推電面總結阿里
- 尋找連續或不連續的子字串字串
- 一道演算法題:求出異或和為零的最長連續子串演算法
- [資料結構拾遺]字串排序演算法總結資料結構字串排序演算法
- JS字串學習之計算給定字元的全部出現位置JS字串字元
- C#拾遺補闕【01】:字串C#字串
- 【演算法拾遺】階乘演算法
- 編寫將給定字串倒序輸出的函式[Java筆試題]字串函式Java筆試
- Java 的字串和子串Java字串
- 演算法之字串——最長迴文子串演算法字串
- 刪除字串中的子串字串
- [C#.NET拾遺補漏]01:字串操作C#字串
- .NET 基礎拾遺(3): 字串、集合和流字串
- 用三種方式取出給定字串中的目標字串字串
- 【演算法拾遺】最大公約數演算法
- python3字串垂直輸出教程Python字串
- JS字串學習之怎麼返回給定下標間的子串JS字串
- mongoose 拾遺Go
- 【演算法拾遺】最大數和最小數演算法
- C# 輸出一個字串的字首、字尾和它的子串(資訊內容安全 實驗一)C#字串
- 查詢字串中連續出現的字元字串字元
- 給出一個由[-100,100]之間整陣列成的陣列,求其相加和最大的連續子陣列 輸入 一個連續整陣列成的陣列 輸出 子陣列相加的最大值 樣例輸入 -......陣列
- 兩個字串的最長公共子串字串
- 31:字串中最長的連續出現的字元字串字元
- 前端技能拾遺前端
- Linux拾遺Linux
- Java Web 拾遺JavaWeb
- [MASM拾遺]OffsetASM
- Python連線兩個字串並去除首尾重複子串Python字串
- java_求列舉所有的連續(或單個字元)的子串.Java字元
- (字串雜湊表)找到字串中不重複出現字元的最長子串長度字串字元
- 處理若干行輸出的題目
- 演算法練習:求字串的最長重複子串(Java實現)演算法字串Java
- 輸出儲存在記憶體中的字串(迴圈輸出每一個的字元和一次性全部輸出)記憶體字串字元
- 物件導向拾遺物件