Day-07-哈希表和字符串 Leetcode-409, 290, 49, 3, 187, 76

目錄

例一:LeetCode409

例二:LeetCode290

例三:LeetCode49

例四:LeetCode3

例五:LeetCode187

例六:LeetCode76


// //最簡單的哈希,字符哈希
#include <stdio.h>
#include <string>
int main() {
       int char_map[128] = { 0 };
       std::string str = "abcdefgaaxxy";
       for (int i = 0; i < str.length(); i++) {
              char_map[str[i]]++;
       }
       for (int i = 0; i < 128; i++) {
              if (char_map[i] > 0) {
                     printf("[%c][%d] : %d\n", i, i, char_map[i]);
              }
       }
       return 0;
}
//利用哈希表排序整數 時間複雜度爲O(表長 + n)n爲元素個數
#include <stdio.h>
int main() {
       int random[10] = { 999, 1, 444, 7, 20, 9, 1, 3, 7, 7 };
       int hash_map[1000] = { 0 };
       for (int i = 0; i < 10; i++) {
              hash_map[random[i]]++;
       }
       for (int i = 0; i < 1000; i++) {
              for (int j = 0; j < hash_map[i]; j++) {
                     printf("%d\n", i);
              }
       }
       return 0;
}
//拉鍊法構造哈希表的具體代碼
#include <stdio.h>
#include <vector>
//哈希表數據結構
struct ListNode {
       int val;
       ListNode* next;
       ListNode(int x) : val(x), next(NULL) {}
};
//哈希函數
int hash_func(int key, int table_len) {
       return key % table_len;
}
//插入數值
void insert(ListNode* hash_table[], ListNode* node, int table_len) {
       int hash_key = hash_func(node->val, table_len);
       node->next = hash_table[hash_key];  //使用頭插法插入節點,以減小時間複雜度
       hash_table[hash_key] = node;
}
//查找數值
bool search(ListNode* hash_table[], int value, int table_len) {
       int hash_key = hash_func(value, table_len);
       ListNode* head = hash_table[hash_key];
       while (head) {
              if (head->val == value) {
                     return true;
              }
              head = head->next;
       }
       return false;
}
int main() {
       const int TABLE_LEN = 11;
       ListNode* hash_table[TABLE_LEN] = { 0 };
       std::vector<ListNode*> hash_node_vec;
       int test[8] = { 1, 1, 4, 9, 20, 30, 150, 500 };
       for (int i = 0; i < 8; i++) {
              hash_node_vec.push_back(new ListNode(test[i]));
       }
       for (int i = 0; i < hash_node_vec.size(); i++) {
              insert(hash_table, hash_node_vec[i], TABLE_LEN);
       }
       printf("Hash table:\n");
       for (int i = 0; i < TABLE_LEN; i++) {
              printf("[%d]: ", i);
              ListNode* head = hash_table[i];
              while (head) {
                     printf("->%d", head->val);
                     head = head->next;
              }
              printf("\n");
       }
       printf("\n");
       printf("Test search:\n");
       for (int i = 0; i < 10; i++) {
              if (search(hash_table, i, TABLE_LEN)) {
                     printf("%d is in the hash table.\n", i);
              }
              else {
                     printf("%d is not in the hash table.\n", i);
              }
       }
       for (int i = 0; i < hash_node_vec.size(); i++) {
              delete hash_node_vec[i];
       }
       return 0;
}
// 哈希map 與 stl map , 映射
#include <stdio.h>
#include <map>
#include <string>
struct ListNode {
       std::string key;
       int val;
       ListNode* next;
       ListNode(int x) : val(x), next(NULL) {}
};
int main() {
       std::map<std::string, int> hash_map;
       std::string str1 = "abc";
       std::string str2 = "aaa";
       std::string str3 = "xxxxx";
       hash_map[str1] = 1;
       hash_map[str2] = 2;
       hash_map[str3] = 100;
       if (hash_map.find(str1) != hash_map.end()) {
              printf(" %s is in hash_map, value is %d\n", str1.c_str(), hash_map[str1]);
       }
       std::map<std::string, int> ::iterator it;
       for (it = hash_map.begin(); it != hash_map.end(); it++) {
              printf("hash_map[%s] = %d\n", it->first.c_str(), it->second);
       }
       return 0;
}

例一:LeetCode409

/**
Given a string which consists of lowercase or uppercase letters, find the length
of the longest palindromes that can be built with those letters.
This is case sensitive, for example "Aa" is not considered a palindrome here.
Note:
Assume the length of given string will not exceed 1,010.
已知一個只包含大小寫字符的字符串,求用該字符中的字符可以生成最長迴文字符串的長度
 */
#include <stdio.h>
#include <string>
class Solution {
public:
       int longestPalindrome(std::string s) {
              int char_map[128] = { 0 };
              int max_length = 0;
              int flag = 0;
              for (int i = 0; i < s.length(); i++) {
                     char_map[s[i]]++;
              }
              for (int i = 0; i < 128; i++) {
                     if (char_map[i] % 2 == 0) {
                           max_length += char_map[i];
                     }
                     else {
                           max_length += char_map[i] - 1;
                           flag = 1;
                     }
              }
              return max_length + flag;
       }
};
int main() {
       std::string s = "abccccddaa";
       Solution solve;
       printf("%d\n", solve.longestPalindrome(s));
       return 0;
}

例二:LeetCode290

/**
 Given a pattern and a string str, find if str follows the same pattern.
 Here follow means a full match, such that there is a bijection between
 a letter in pattern and a non-empty word in str.
 已知字符串pattern與字符串str,確定str是否與pattern匹配。
 */
#include <stdio.h>
#include <string>
#include <map>
class Solution {
public:
       bool wordPattern(std::string pattern, std::string str) {
              std::map<std::string, char> word_map;
              char used[128] = { 0 };
              std::string word;
              int pos = 0;
              str.push_back(' ');
              for (int i = 0; i < str.length(); i++) {
                     if (str[i] == ' ') {
                           if (pos == pattern.length()) {
                                  return false;
                           }
                           if (word_map.find(word) == word_map.end()) {
                                  if (used[pattern[pos]]) {
                                         return false;
                                  }
                                  word_map[word] = pattern[pos];
                                  used[pattern[pos]] = 1;
                           }
                           else {
                                  if (word_map[word] != pattern[pos]) {
                                         return false;
                                  }
                           }
                           word = "";
                           pos++;
                     }
                     else {
                           word += str[i];
                     }
              }
              if (pos != pattern.length()) {
                     return false;
              }
              return true;
       }
};
int main() {
       std::string pattern = "abba";
       std::string str = "dog cat cat dog";
       Solution solve;
       printf("%d\n", solve.wordPattern(pattern, str));
       return 0;
}

例三:LeetCode49

//更優解
class Solution {
public:
       std::vector<std::vector<std::string>> groupAnagrams(std::vector<std::string>& strs) {
              std::map<std::string, std::vector<std::string>> anagram;
              std::vector<std::vector<std::string>> result;
              for (int i = 0; i < strs.size(); i++) {
                     std::string str = strs[i];
                     std::sort(str.begin(), str.end());
                     if (anagram.find(str) == anagram.end()) {
                           std::vector<std::string> item;
                           anagram[str] = item;
                     }
                     anagram[str].push_back(strs[i]);
              }
              std::map<std::string, std::vector<std::string>> ::iterator it;
              for (it = anagram.begin(); it != anagram.end(); it++) {
                     result.push_back((*it).second);
              }
              return result;
       }
};

/**
 Given an array of strings, group anagrams together.
 已知一組字符串,將所有由顛倒字母順序組成的字符串放到一起輸出
 */
#include <stdio.h>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
 // class Solution{
 // public:
 //    std::vector<std::vector<std::string>> groupAnagrams(std::vector<std::string> &strs){
 //           std::map<std::string, std::vector<std::string>> anagram;
 //           std::vector<std::vector<std::string>> result;
 //           for(int i = 0; i < strs.size(); i++){
 //                  std::string str = strs[i];
 //                  std::sort(str.begin(), str.end());
 //                  if(anagram.find(str) == anagram.end()){
 //                         std::vector<std::string> item;
 //                         anagram[str] = item;
 //                  }
 //                  anagram[str].push_back(strs[i]);
 //           }
 //           std::map<std::string, std::vector<std::string>> ::iterator it;
 //           for(it = anagram.begin(); it != anagram.end(); it++){
 //                  result.push_back((*it).second);
 //           }
 //           return result;
 //    }
 // };
class Solution {
public:
       std::vector<std::vector<std::string>> groupAnagrams(std::vector<std::string>& strs) {
              std::map<std::vector<int>, std::vector<std::string>> anagram;
              std::vector<std::vector<std::string>> result;
              for (int i = 0; i < strs.size(); i++) {
                     std::vector<int> vec;
                     change_to_vector(strs[i], vec);
                     if (anagram.find(vec) == anagram.end()) {
                           std::vector<std::string> item;
                           anagram[vec] = item;
                     }
                     anagram[vec].push_back(strs[i]);
              }
              std::map<std::vector<int>, std::vector<std::string>> ::iterator it;
              for (it = anagram.begin(); it != anagram.end(); it++) {
                     result.push_back((*it).second);
              }
              return result;
       }
private:
       void change_to_vector(std::string& str, std::vector<int>& vec) {
              for (int i = 0; i < 26; i++) {
                     vec.push_back(0);
              }
              for (int i = 0; i < str.length(); i++) {
                     vec[str[i] - 'a']++;
              }
       }
};
int main() {
       std::vector<std::string> strs;
       strs.push_back("eat");
       strs.push_back("tea");
       strs.push_back("tan");
       strs.push_back("ate");
       strs.push_back("nat");
       strs.push_back("bat");
       Solution solve;
       std::vector<std::vector<std::string>> result =
              solve.groupAnagrams(strs);
       for (int i = 0; i < result.size(); i++) {
              for (int j = 0; j < result[i].size(); j++) {
                     printf("[%s]", result[i][j].c_str());
              }
              printf("\n");
       }
       return 0;
} 

例四:LeetCode3

#include <stdio.h>
#include <string>
class Solution {
public:
       int lengthOfLongestSubstring(std::string s) {
              int begin = 0;
              int result = 0;
              std::string word = "";
              int char_map[128] = { 0 };
              for (int i = 0; i < s.length(); i++) {
                     char_map[s[i]]++;
                     if (char_map[s[i]] == 1) {
                           word.push_back(s[i]);
                           if (result < word.length()) {
                                  result = word.length();
                           }
                     }
                     else {
                           while (char_map[s[i]] > 1 && begin < i) {
                                  char_map[s[begin]] --;
                                  begin++;
                           }
                           word = "";
                           for (int j = begin; j <= i; j++) {
                                  word.push_back(s[j]);
                           }
                     }
              }
              return result;
       }
};
int main() {
       std::string s = "abcbadab";
       Solution solve;
       printf("%d\n", solve.lengthOfLongestSubstring(s));
       return 0;
}

例五:LeetCode187

/**
 All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T,
  for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify
   repeated sequences within the DNA.
Write a function to find all the 10-letter-long sequences (substrings) that occur
more than once in a DNA molecule.
將DNA序列看作是隻包含A, C, G, T 四個字符的字符串,給一個DNA字符串,找出所有長度爲10的
且出現超過一次的子串。
 */
#include <stdio.h>
#include <vector>
#include <map>
#include <string>
 // // O(n)
 // class Solution{
 // public:
 //    std::vector<std::string> findRepeatedDnaSequences(std::string s){
 //           std::map<std::string, int> word_map;
 //           std::vector<std::string> result;
 //           for(int i = 0; i < s.length(); i++){
 //                  std::string word = s.substr(i, 10);  //返回一個新建的初始化爲string對象的子串的拷貝string對象。
 //                  if(word_map.find(word) != word_map.end()){
 //                         word_map[word]++;
 //                  }
 //                  else{
 //                         word_map[word] = 1;
 //                  }
 //           }
 //           std::map<std::string, int> :: iterator it;
 //           for(it = word_map.begin(); it != word_map.end(); it++){
 //                  if(it->second > 1){
 //                         result.push_back(it -> first);
 //                  }
 //           }
 //           return result;
 //    }
 // };
 // 更優解
int g_hash_map[1048576] = { 0 }; // 哈希表太大了,需要全局數組,大小爲2^20
class Solution {
public:
       std::vector<std::string> findRepeatedDnaSequences(std::string s) {
              std::vector<std::string> result;
              if (s.length() < 10) {
                     return result;
              }
              for (int i = 0; i < 1048576; i++) {
                     g_hash_map[i] = 0;
              }
              int char_map[128] = { 0 };
              char_map['A'] = 0;
              char_map['C'] = 1;
              char_map['G'] = 2;
              char_map['T'] = 3;
              int key = 0;
              for (int i = 9; i >= 0; i--) {
                     key = (key << 2) + char_map[s[i]];
              }
              g_hash_map[key] = 1;
              for (int i = 10; i < s.length(); i++) {
                     key = key >> 2;
                     key = key | (char_map[s[i]] << 18);
                     g_hash_map[key]++;
              }
              for (int i = 0; i < 1048576; i++) {
                     if (g_hash_map[i] > 1) {
                           result.push_back(change_int_to_DNA(i));
                     }
              }
              return result;
       }
private:
       std::string change_int_to_DNA(int DNA) { // 將 int 轉化爲 string
              static const char DNA_CHAR[] = { 'A', 'C', 'G', 'T' };
              std::string str;
              for (int i = 0; i < 10; i++) {
                     str += DNA_CHAR[DNA & 3];
                     DNA = DNA >> 2;
              }
              return str;
       }
};
int main() {
       std::string s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT";
       Solution solve;
       std::vector<std::string> result = solve.findRepeatedDnaSequences(s);
       for (int i = 0; i < result.size(); i++) {
              printf("%s\n", result[i].c_str());
       }
       return 0;
}

例六:LeetCode76

/**
 Given a string S and a string T, find the minimum window in
  S which will contain all the characters in T in complexity O(n).
  已知字符串S與字符串T,求在S中的最小窗口(區間),使得這個區間包含字
  符串T中的所有字符。
 */
#include <stdio.h>
#include <string>
#include <vector>
class Solution {
public:
       std::string minWindow(std::string s, std::string t) {
              const int MAX_ARRAY_LEN = 128;
              int map_t[MAX_ARRAY_LEN] = { 0 };
              int map_s[MAX_ARRAY_LEN] = { 0 };
              std::vector<int> vec_t; // 記錄 t 字符串中有哪些字符
              for (int i = 0; i < t.length(); i++) {
                     map_t[t[i]]++;
              }
              for (int i = 0; i < MAX_ARRAY_LEN; i++) {
                     if (map_t[i] > 0) {
                           vec_t.push_back(i);
                     }
              }
              int window_begin = 0;
              std::string result;
              for (int i = 0; i < s.length(); i++) {
                     map_s[s[i]]++;
                     while (window_begin < i) {
                           char begin_ch = s[window_begin];
                           if (map_t[begin_ch] == 0) {
                                  window_begin++;
                           }
                           else if (map_s[begin_ch] > map_t[begin_ch]) {
                                  map_s[begin_ch]--;
                                  window_begin++;
                           }
                           else {
                                  break;
                           }
                     }
                     if (is_window_ok(map_s, map_t, vec_t)) {
                           int new_window_len = i - window_begin + 1;
                           if (result == "" || new_window_len < result.length()) {
                                  result = s.substr(window_begin, new_window_len);
                           }
                     }
              }
              return result;
       }
private:
       // 檢測 t 中的字符是否都在 s 中出現
       bool is_window_ok(int map_s[], int map_t[], std::vector<int>& vec_t) {
              for (int i = 0; i < vec_t.size(); i++) {
                     if (map_s[vec_t[i]] < map_t[vec_t[i]]) {
                           return false;
                     }
              }
              return true;
       }
};
int main() {
       Solution solve;
       std::string result = solve.minWindow("ADOBECODEBANC", "ABC");
       printf("%s\n", result.c_str());
       result = solve.minWindow("MADOBCCABEC", "ABCC");
       printf("%s\n", result.c_str());
       result = solve.minWindow("aa", "aa");
       printf("%s\n", result.c_str());
       return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章