多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > [劍指Offer] 第5章課后題詳解

[劍指Offer] 第5章課后題詳解

來源:程序員人生   發布時間:2016-08-15 08:14:54 閱讀次數:3608次

[劍指Offer] 第5章課后題詳解

目錄

  • 劍指Offer 第5章課后題詳解
    • 目錄
    • 刪除指定字符
      • 分析
      • 解法
      • 優化
    • 刪除重復元素
      • 分析
      • 解法
    • 判斷變位詞
      • 分析
      • 解法
    • 求助

刪除指定字符

本題為《劍指Offer》“面試題35:第1個只出現1次的字符”1節中的“相干題目”。

定義1個函數,輸入兩個字符串,從第1個字符串中刪除在第2個字符串中出現過的所有字符。

分析

字符是1個長度為8的數據類型,共256種可能。創建1個長度為256的bool型數組,數組下標為字符對應的ASCII碼值,分別記錄字符是不是在第2個字符串中出現過。由于直接調用erase函數刪除元素效力較低,且在遍用時改變容器可能會造成嚴重毛病,所以創建1個臨時字符串將不會被刪除的字符保存下來,再賦值給第1個字符串。

解法

auto DeleteAppearanceChar(string &s1, const string &s2) -> void{ //如果s1或s2為空,則直接返回 if(!s1.size() || !s2.size()){ return; } //創建臨時字符串 string tempString; //創建bool數組 const int tableSize = 256; bool hashTable[tableSize]; //將所有bool值初始化為false for(unsigned int i = 0; i < tableSize; ++i){ hashTable[i] = false; } //遍歷s2,如果字符出現,則將數組對應位置標志為true auto begin = s2.begin(); while(begin != s2.end()){ hashTable[*(begin ++)] = true; } //遍歷s1,如果字符沒在s2中出現過就加入到tempString中 begin = s1.begin(); while(begin != s1.end()){ if(!hashTable[*begin]){ tempString.push_back(*begin); } begin++; } //用臨時字符串的值替換s1原本的內容 s1.assign(tempString); }

優化

使用臨時字符串會增加空間開消,可能使空間復雜度上升O(n),刪除s1中字符的時候可使用兩個1前1后的迭代器,前面的迭代器尋覓后面第1個沒在s2中出現的字符,然后復制到前1個迭代器所指的位置,再將兩個迭代器順次后移1步,如此循環直到后面的迭代器抵達s1末尾。最后再將兩個迭代器之間的元素刪除,這樣刪除操作就全在字符串尾部進行了,時間復雜度照舊為O(n)。刪除s1中字符的代碼可以用下面的代碼替換。

//使用1前1后兩個迭代器 begin = s1.begin(); auto behind = s1.begin(); //任意迭代器抵達字符串尾部后停止 while(begin != s1.end() && behind != s1.end()){ //如果字符沒在s2中出現,則進行復制操作 if(!hashTable[*begin]){ *(behind++) = *(begin++); continue; } //迭代器begin向后直到尋覓到下1個沒在s2中出現的字符或抵達字符串尾部為止 while(begin++ != s1.end() && hashTable[*begin]); if(begin == s1.end()){ break; } //找到以后進行復制操作,此行代碼可省略 *(behind++) = *(begin++); } //刪除s1末尾的字符 s1.erase(behind, begin);

刪除重復元素

本題為《劍指Offer》“面試題35:第1個只出現1次的字符”1節中的“相干題目”。

定義1個函數,刪除字符串中所有重復出現的字符。

分析

本題與上題大體類似,遍歷1個字符串,如果遇到沒出現過的字符便存入臨時字符串中,并將對應的標志位設為true(表示出現過),遇到出現過的則直接跳過。

解法

auto DeleteRepeatChar(string &s) -> void{ if(!s.size()){ return; } string tempString; const int tableSize = 256; bool hashTable[tableSize]; for(unsigned int i = 0; i < tableSize; ++i){ hashTable[i] = false; } auto begin = s.begin(); while(begin != s.end()){ if(!hashTable[*begin]){ tempString.push_back(*begin); //遇到沒出現過的字符,將數組對應位置標志為true hashTable[*(begin)] = true; } begin++; } s.assign(tempString); }

判斷變位詞

本題為《劍指Offer》“面試題35:第1個只出現1次的字符”1節中的“相干題目”。

在英語中,如果兩個單詞中出現的字母相同,并且每一個字母出現的次數也相同,那末這兩個單詞互為變位詞。

分析

與前面兩題類似,用1個int型數組來統計其中1個單詞中所有字符出現的次數,再遍歷另外一個單詞,每遇到1個字符,便將數組對應位置的值減1,如果最后數組全部元素都未0,則說明是變位詞,需要注意的是無效輸入的處理。

解法

//定義1個全局變量監控輸入毛病 bool invaildInput = false; auto IsAnagram(const string &s1, const string &s2) -> bool{ //如果最少有1個單詞為空,則報輸入毛病,并返回false。這里認定兩個單詞都為空也返回false(由于空字符串不是單詞),這些邊界條件可以跟面試官溝通如何判定,同時可以溝通的是完全相同的單詞是不是算做換位詞 if(!s1.size() || !s2.size()){ invaildInput = true; return false; } //檢查是不是有非字母之外的非法輸入,如果有則報輸入毛病,并返回false auto begin = s2.begin(); while(begin != s2.end()){ if (!((*begin >= 'a' && *begin <= 'z') || (*begin >= 'A' && *begin <= 'Z'))){ invaildInput = true; return false; } begin++; } begin = s1.begin(); while(begin != s1.end()){ if (!((*begin >= 'a' && *begin <= 'z') || (*begin >= 'A' && *begin <= 'Z'))){ invaildInput = true; return false; } begin++; } const int tableSize = 256; int hashTable[tableSize]; for(unsigned int i = 0; i < tableSize; ++i){ hashTable[i] = 0; } begin = s2.begin(); while(begin != s2.end()){ hashTable[*(begin ++)] ++; } begin = s1.begin(); while(begin != s1.end()){ //將遇到的每一個字符在數組對應位置的值⑴,如果出現負值則直接返回false if(--hashTable[*begin]< 0 ){ return false; } begin++; } //遍歷數字,檢查是不是有不為0的值 for(unsigned int i = 0; i < tableSize; ++i){ if(hashTable[i] != 0){ return false; } } return true; }

求助

《劍指Offer》“面試題35:第1個只出現1次的字符”1節中的“本題拓展”

在字符串中找出第1個只出現1次的字符,斟酌漢字的情況。

關于本題,個人斟酌了兩個思路:
第1:照瓢畫葫蘆,與原題采取完全1樣的解法,只是將ASCII碼換為中文Unicode編碼,由于漢字的Unicode編碼位數較多,范圍為0x3000到0x9FFF,雖然也能夠將空間效力解釋為O(1),但這個常量很大,最少需要用2的15次方級的空間,空間開消太大,感覺不太公道。
第2:使用哈希表,這個方法用java可行,但是C++標準庫中沒有哈希表,自定義哈希表的代碼量較大,不合適在面試時書寫。

所以懇請熱情的高手能夠解答我的疑惑,不勝感激!

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 波多野结衣视频在线观看地址免费 | 亚洲在线播放视频 | 亚洲欧美日韩中文字幕在线 | 在线xx视频 | 男女视频在线免费观看 | 亚洲tv精品一区二区三区 | 天天视频国产免费入口 | 在线 v亚洲 v欧美v 专区 | 精品一区二区乱码久久乱码 | 老司机午夜精品 | 亚洲人成网站在线观看播放 | 成人高清毛片a | 一区自拍 | 免费大片在线观看www | 国产性色视频 | 一区二区三区在线免费观看视频 | 成年人视频在线观看免费 | 欧美jizz18性欧美 | 18videosex性欧美69免费播放 | 在线观看中文字幕第一页 | 大陆三级午夜理伦三级三 | 欧美午夜免费一级毛片 | 欧美日本在线 | 久久99国产精一区二区三区! | 欧美日韩无线在码不卡一区二区三区 | 国产精品第1页 | 成人欧美一区二区三区视频不卡 | 久久受www免费人成_看片中文 | 91精品一区二区三区久久久久 | 亚洲成年网站在线777 | 国产三级在线观看播放 | www.亚洲天堂网 | 亚洲精品自拍愉拍第二页 | 毛片毛片毛是个毛毛片 | 国产精品揄拍一区二区 | 黄色网址在线免费 | 欧美一级片手机在线观看 | 2018一级毛片免费观看 | 日本在线中文 | 操操综合网 | 国产精品亚洲国产三区 |