先驗知識記錄:
遇到哈希問題,想到三種數據結構:
①數組:適用于哈希值比較小,范圍較小,
②set:適用于哈希值較大。
③map:如果需要用到鍵值對,則用之。
242.有效的字母異位符。
代碼隨想錄鏈接
力扣鏈接
問題描述:
就是看兩個字符串里面的字符是不是一樣的,它們包含的字母以及個數是否是一致的。
思路:
因為單個字母總共有26個,所以建立數組形式的hash表。初始的hash表各個元素為0。經過字符串1的遍歷后,hash表此時對應位置的字母數為字符串1的字母數。
再去遍歷字符串2,如果遍歷后的hash字母表存在字母對應的值不為0,則說明兩個字符串包含的字母及字母數不同。如果每個hash表中每個位置的字母都為0,那么說明兩個字符串中是異位關系。
注意,此時hash表中的字母位置,使用hash[string1[i]-'a']
表示,這個很妙,因為這就相當于取出字符串每個字符對應到hash數組中且一一對應。
偽代碼:
新建數組hash字母表
遍歷字符串1對對應位置的hash字母表數值+1,表示字符串1中的hash字母表中字母個數
遍歷字符串2對對應位置的hash字母表數值-1,表示字符串2中的hash字母表字母個數-字符串1中對應位置的字母個數
遍歷hash字母表如果某個位置不為0說明兩個字符串不是異味關系,返回false
遍歷完成后,返回true
代碼:
bool isAnagram(string s, string t) {int hash[26]={0};for(int i =0 ; i<s.size();i++){//遍歷字符串s,使得s對應的字母表每個都有其對應次數。//s[i]就是s的每個字符,s[i]-‘a’代表了其對應哈希表的索引從0-25。字符串t同理。hash[s[i]-'a']++;}for(int i = 0 ; i< t.size() ; i++){hash[t[i]-'a']--;}for(int i = 0 ; i < 26; i++){if (hash[i]!=0){return false;}}return true;
}
349.兩個數組的交集。
代碼隨想錄鏈接
力扣鏈接
問題描述
兩個數組,取交集,最后的結果要不重復。
思路:
有兩種思路解決:
①set,將數組1的元素存入set去重。遍歷數組2,如果元素在set中,則放入另個集合中,作為返回值返回。
遍歷數組1,將數組中每個元素去重后放入number_set中
遍歷數組2如果數組2中有元素在number_set中則放入result_set中
將result_set轉為vector,作為返回值返回
②數組,力扣上有數組中單個元素大小限制,故將hash表數組設置為1000出頭的大小。
新建hash表,大小為1000出頭
遍歷數組1對數組1的每個元素放到hash數組中,為1.
遍歷數組2如果數組中有數字對應hash值為1將元素放入result_set中
將result_set轉為vector,作為返回值返回
解法①代碼:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {set<int> result_set;//方法1set<int> number_set ;for(int i = 0 ; i < nums1.size() ; i++){number_set.insert(nums1[i]);}for(int i = 0 ; i< nums2.size();i++){if (number_set.find(nums2[i])!= number_set.end()){result_set.insert(nums2[i]);}}vector <int> vt;vt.assign(result_set.begin(),result_set.end());return vt;
}
解法②代碼:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {set<int> result_set;//方法2int hash[1001]={0};//遍歷nums1,若有數字,則為1for(int i = 0 ; i < nums1.size() ; i++){hash[nums1[i]]=1;}for(int i = 0 ; i < nums2.size();i++){if (hash[nums2[i]]){result_set.insert(nums2[i]);}}vector <int> vt;vt.assign(result_set.begin(),result_set.end());return vt;
}