leetcode-49-字母異位詞分組(神奇的哈希)

題目描述:

給定一個字符串數組,將字母異位詞組合在一起。字母異位詞指字母相同,但排列不同的字符串。

示例:

輸入: ["eat", "tea", "tan", "ate", "nat", "bat"],
輸出:
[["ate","eat","tea"],["nat","tan"],["bat"]
]

說明:

  • 所有輸入均為小寫字母。
  • 不考慮答案輸出的順序。

    給定一個字符串數組,將字母異位詞組合在一起。字母異位詞指字母相同,但排列不同的字符串。

    示例:

    輸入: ["eat", "tea", "tan", "ate", "nat", "bat"],
    輸出:
    [["ate","eat","tea"],["nat","tan"],["bat"]
    ]

    說明:

    • 所有輸入均為小寫字母。
    • 不考慮答案輸出的順序。

?

要完成的函數:

vector<vector<string>> groupAnagrams(vector<string>& strs)

?

說明:

1、給定一個vector,里面裝著多個string,要求把這些string進行分組。

兩個字符串擁有相同的字母,就是同一組。(題目說字母相同,順序不同,但測試樣例中出現了字母相同順序也相同的,也在同一組)

字符串只含有小寫字母。

每一組存在一維vector中,所有組存放在二維vector中,最終返回二維vector。

?

2、這道題筆者最開始想用一個雙重循環,外層循環對每個字符串進行迭代,內層循環判斷當前字符串跟前面的字符串,有沒有哪個是相同字母的。

關于內層循環的判斷,筆者最開始想用異或來處理,但后來發現it和ro這四個不同的字母,i^t^r^o的結果為0……

也就是我們不能用異或結果是不是0來判斷字母是不是相同。

異或應該只是適用于只有一個字母不同,而其他字母都相同的情況。

?

那不能用異或,那就用普通的“空間換時間”,我們建立長度為26的vector,在內層循環中判斷兩個字符串是否擁有相同字母。

在對長度為26的vector進行操作前,我們先判斷兩個字符串的長度是否相等,這可以省去很多時間。

代碼如下:(附詳解)

    bool judge(string a,string b)//判斷兩個字符串是否擁有相同的字母{vector<int>table(26,0),t1(26,0);for(char i:a)table[i-'a']++;for(char i:b)table[i-'a']--;if(table!=t1)return false;//如果table不是全為0,返回falsereturn true;//否則返回true}vector<vector<string>> groupAnagrams(vector<string>& strs) {vector<vector<string>>res={{strs[0]}};//初始化最終要返回的二維vectorbool flag;for(int i=1;i<strs.size();i++)//循環迭代每個字符串{flag=0;for(int j=0;j<res.size();j++)//對當前的字符串,判斷是否跟前面出現過的字符串,擁有相同字母{if(strs[i].size()!=res[j][0].size())//長度的判斷continue;if(judge(strs[i],res[j][0]))//字母相同的兩個字符串{res[j].push_back(strs[i]);flag=1;break;}}if(flag==0)//前面所有字符串跟當前字符串的字母都不相同{res.push_back({strs[i]});}}return res;//最終返回res}

上述代碼也可以通過測試,但是實測1228ms,beats 2.20% of cpp submissions……太低了

那肯定還有更好的辦法==

?

我們分析一下上述代碼,發現耗費時間的地方在于:

①雙重循環,如果可以改成單重循環就最好了。

②二維vector的不斷申請空間、不斷插入

第二點似乎很難避免,我們要初始化res擁有多長的長度?跟給定的一維vector strs一樣長?那多出來那部分怎么處理……

不斷地pop_back()?這也是一個方法,但看了一下普遍的時間花費是36ms左右,我這樣改可能效果也不會很大……

那第一點要怎么改善?外層循環肯定不可少了,內層循環改成O(1)的時間復雜度?

?

我們想一下,如果是數字串而不是字母串,我們會怎樣判斷當前數字串有沒有出現過?

比如12,32,12,當前數字是第三個數字12,我們可以用vector,前面有了vector[12]=1,vector[32]=1,此時我們再查詢一下當前數字12的對應vector[12],是不是0。

如果是0,那么沒有出現過,如果不是0,那么出現過。

這個時候我們不用一個個地去循環,去遍歷,直接就訪問了。

那可不可以同樣利用這種方法來處理字母串呢?

答案是可以的,我們可以用哈希表。

?

哈希表其實就是數組+鏈表的結構,在c++中,筆者覺得map這種數據結構可能就是實現了哈希表的算法。

哈希表結合了數組的快速訪問、修改和鏈表的無限長度兩個特點,可以參考下面這張圖。

左邊是數組,快速訪問和修改,右邊的鏈表延伸出去,無限長度。

?我們以字母串作為鍵值,像用vector查看數字串一樣去判斷。

?

但有的同學可能有想法,比如“ate”和“eat”這兩個鍵值都不一樣,你怎么判斷?

“ate”和“eat”是不一樣,但它們有共性,那就是擁有的字母相同,我們可以對它們的字母排下序,就可以轉化為相同的鍵值了。

代碼如下:(附詳解)

    vector<vector<string>> groupAnagrams(vector<string>& strs) {vector<vector<string>>res;//最終要返回的二維vectorunordered_map<string,int>m1;//定義一個map作為哈希表int index=0;vector<string> strs1=strs;//用于重新排序strs中的每個字符串,strs是原本for(int i=0;i<strs1.size();i++){sort(strs1[i].begin(),strs1[i].end());//對字符串中的字母進行排序if(!m1.count(strs1[i]))//如果之前沒有出現過{m1[strs1[i]]=index;//更新一下index++;//index作為res中的索引res.push_back({strs[i]});//插入一個一維的vector}else//如果有出現過了{res[m1[strs1[i]]].push_back(strs[i]);//res找到對應的索引,插入當前字符串}}return res;//最終返回res}

上述代碼實測28ms,beats 93.68% of cpp submissions。

哈希表其實就是我們平時常用的vector的升級版本,用map實現時,既可以實現快速訪問,又有好的哈希函數,使得空間充足。

神奇神奇~

轉載于:https://www.cnblogs.com/chenjx85/p/9477896.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450916.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450916.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450916.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【精心總結】java內存模型和多線程必會知識

內存模型 &#xff08;1&#xff09;java內存模型到底是個啥子東西&#xff1f; java內存模型是java虛擬機規范定義的一種特定模型&#xff0c;用以屏蔽不同硬件和操作系統的內存訪問差異&#xff0c;讓java在不同平臺中能達到一致的內存訪問效果&#xff0c;是在特定的協議下…

工作流 activity 視頻教程 + redis 視頻教程 百度網盤分享地址

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 云盤下載都沒有密碼&#xff0c;直接下載&#xff0c;解壓有密碼&#xff1a;chongxiangmengxiangjiaoyu&#xff0c; 解壓完成后就可以…

快速解決 GRADLE 項目下載 gradle-*-all.zip 慢的問題

1、首先根據項目中 gradle\wrapper\gradle-wrapper.properties 文件的 distributionUrl 屬性的值 #Tue Feb 06 12:27:20 CET 2018 distributionBaseGRADLE_USER_HOME distributionPathwrapper/dists zipStoreBaseGRADLE_USER_HOME zipStorePathwrapper/dists distributionUrlht…

[Python] 程序結構與控制流

1. 條件語句 if、else與elif語句用于控制條件代碼的執行。條件語句的一般格式如下&#xff1a; if expression:statements elif expression:statements elif expression:statements ... else:statements 如果不需要執行任何操作&#xff0c;可以省略條件語句的else和elif子句。…

webrtc 源碼結構

apiWebRTC 接口層。包括 DataChannel, MediaStream, SDP相關的接口。各瀏覽器都是通過該接口層調用的 WebRTC。call存放的是 WebRTC “呼叫&#xff08;Call&#xff09;” 相關邏輯層的代碼。audio存放音頻網絡邏輯層相關的代碼。音頻數據邏輯上的發送&#xff0c;接收等代碼。…

mysql查詢流程解析及重要知識總結

時光荏苒啊&#xff01;在過兩個月我就工作滿三年了&#xff0c;大學畢業的情景還歷歷在目&#xff0c;而我已經默默的向油膩中年大叔進發了。作為一名苦逼的后端工程師&#xff0c;我搞過一段時間python&#xff0c;現在靠java糊口&#xff0c;但后來才發現&#xff0c;始終不…

界面無小事(八):RecyclerView增刪item

界面無小事(一): RecyclerViewCardView了解一下 界面無小事(二): 讓RecyclerView展示更多不同視圖 界面無小事(三):用RecyclerView Toolbar做個文件選擇器 界面無小事(四):來寫個滾動選擇器吧! 界面無小事(五):自定義TextView 界面無小事(六):來做個好看得側拉菜單! 界面無小事…

Failed to install Tomcat7 service 解決

見&#xff1a; http://blog.csdn.net/desow/article/details/21446197 tomcat 安裝時出現 Failed to install Tomcat7 service 今天在安裝tomcat時提示 Failed to install Tomcat7 service了&#xff0c;花了大半天的時間找到了原因&#xff0c;下面分享給大家&#xff0c;希望…

保守官僚 諾基亞就這樣迷失在智能機時代?

7月19日&#xff0c;諾基亞發布了二季度財報&#xff0c;凈虧損達到了17億美元&#xff0c;其中智能手機份額和銷售量進一步下滑&#xff0c;這個智能手機的領導者&#xff0c;正在因智能手機而急速墜落。諾記亞領先業界近十年就把握住了智能手機的趨勢&#xff0c;并推出了首款…

django集成ansibe實現自動化

動態生成主機列表和相關參數 def create_admin_domain(admin_node):workpath BASE_DIR /tools/ansible/scripthosts_file BASE_DIR /tools/ansible/host/ createhostfile()yml_file BASE_DIR /tools/ansible/yml/ create_admin_domain.ymldomain_path admin_node.doma…

extend 對象繼承

function extend(o, n, override) {for (var p in n) {if (n.hasOwnProperty(p) && (!o.hasOwnProperty(p) || override))o[p] n[p];} }// 默認參數 var options {pageIndex: 1,pageTotal: 2 };// 新設置參數 var userOptions {pageIndex: 3,pageSize: 10 }extend(o…

【spring容器啟動】之bean的實例化和初始化(文末附:spring循環依賴原理)

本次我們通過源碼介紹ApplicationContext容器初始化流程&#xff0c;主要介紹容器內bean的實例化和初始化過程。ApplicationContext是Spring推出的先進Ioc容器&#xff0c;它繼承了舊版本Ioc容器BeanFactory&#xff0c;并進一步擴展了容器的功能&#xff0c;增加了bean的自動識…

如何將自己的Java項目部署到外網

見&#xff1a;http://jingyan.baidu.com/article/90bc8fc864699af653640cf7.html 做b/s模式的web開發不同于c/s模式的客戶端開發&#xff0c;c/s模式我們只要做好生成可執行文件發送給其他人&#xff0c;其他人就可以用了。但是c/s模式不同&#xff0c;在同一局域網下&#xf…

[Swift]LeetCode916.單詞子集 | Word Subsets

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★?微信公眾號&#xff1a;山青詠芝&#xff08;shanqingyongzhi&#xff09;?博客園地址&#xff1a;山青詠芝&#xff08;https://www.cnblogs.com/strengthen/&#xff09;?GitHub地址&a…

揭秘騰訊研究院輸出策略:產品和人才的孵化器

直到現在&#xff0c;騰訊研究院創始人鄭全戰仍堅持面試招入研究院的每一個人&#xff0c;并做詳細記錄。天賦上的靈性、性格中的包容是他看重的&#xff0c;當然首先人要踏實。大約6年前&#xff0c;鄭全戰加入騰訊&#xff0c;負責籌建中國互聯網公司中的第一個研究院&#x…

java后端必會【基礎知識點】

&#xff08;一&#xff09;java集合類&#xff08;done&#xff09; 在java集合類中最常用的是Collection和Map的接口實現類。Collection又分為List和Set兩類接口&#xff0c;List的實現類有ArrayList、LinkedList、Vector、Stack&#xff0c;Set接口的實現類有HashSet、Tree…

無法連接虛擬設備ide1:0,主機上沒有相對應的設備... 解決

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 運行虛擬機出現報錯&#xff1a; 無法連接虛擬設備ide1:0&#xff0c;主機上沒有相對應的設備&#xff0c;您 要在每次開啟此虛擬機時都…

繳滿15年能領多少錢 養老金計算公式網上瘋傳

社保人員稱我省計算方式與各設區市平均工資掛鉤&#xff0c;與網上不同 最近&#xff0c;關于“延遲退休”引起各方高度關注&#xff0c;成為廣大居民十分關心的話題。是否延遲退休尚無定論&#xff0c;但在網上有不少關于養老金的計算。那網上流傳的計算方法是否科學&#xff…

48_并發編程-線程-資源共享/鎖

一、數據共享多個線程內部有自己的數據棧&#xff0c;數據不共享&#xff1b;全局變量在多個線程之間是共享的。1 # 線程數據共享不安全加鎖2 3 import time4 from threading import Thread, Lock5 6 7 num 1008 9 def func(t_lock): 10 global num 11 t_lock.acquire…

移動硬盤提示無法訪問設備硬件出現致命錯誤,導致請求失敗的資料尋回方案

J盤打不開設備硬件出現致命錯誤,導致請求失敗&#xff0c;是因為這個I盤的文件系統內部結構損壞導致的。要恢復里面的數據就必須要注意&#xff0c;這個盤不能格式化&#xff0c;否則數據會進一步損壞。具體的恢復方法看正文 工具/軟件&#xff1a;星空數據恢復軟件 步驟1&…