Day-07- hash table, and string Leetcode-409, 290, 49, 3, 187, 76






// //最简单的哈希,字符哈希
#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;
}

Example One: 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;
}

Example two: 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;
}

Example Three: 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;
} 

Example Four: 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;
}

Example five: 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;
}

Six cases: 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;
}

Guess you like

Origin www.cnblogs.com/lihello/p/11520914.html