哈希字符串类题目常规思路—Leetcode-thinking_record12

目录

 

哈希表定义

字符哈希

哈希表排序整数

拉链法(解决一个key后面跟多个值的问题) 

理论描述

代码实现 

最长回文串

总体思路

细节设计

代码实现

词语模式

总体思路

细节设计

 代码实现 

同字符词语分组

Solve1

总体思路

细节设计

代码实现

Solve2

总体思路

代码实现

无重复字符的最长字串

总体思路

细节设计

代码实现

重复的DNA序列

Solve1

总体思路

代码实现

Solve2

总体思路

细节设计

代码实现

最小窗口字串

总体思路

 细节设计

代码实现


哈希表定义

字符哈希

哈希表排序整数

拉链法(解决一个key后面跟多个值的问题) 

理论描述

代码实现 

哈希表(拉链法).cpp

#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");
		}
		else{
			printf("%d is not in the hash table.\n");
		}
	}
	return 0;
}

最长回文串

LeetCode 409.Longest Palindrome

已知一个只包括大小写字符的字符串,求用该字符串中的字符可以生成的最长回文字符串长度。

例如s="abccccddaa",可生成的最长回文字符串长度为9,如dccaaaccd、adccbccda、acdcacdca等,都是正确的。

总体思路

细节设计

代码实现

#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;
}

词语模式

LeetCode 290.Word Pattern

已知字符串pattern与字符串str,确认str是否与pattern匹配。str与pattern匹配代表字符串str中的单词与pattern中的字符一一对应。(其中pattern中只包含小写字符,str中的单词只包含小写字符,使用空格分隔)

总体思路

细节设计

 代码实现 

#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;
}

同字符词语分组

LeetCode 49.Group Anagrams

已知一组字符串,将所有anagram(由颠倒字母顺序而构成的字)放到一起输出。

Solve1

总体思路

细节设计

代码实现

#include <stdio.h>

#include <vector>
#include <string>
#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;
    }
};

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;
}

Solve2

总体思路

代码实现

#include <stdio.h>

#include <vector>
#include <string>
#include <map>

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']++;
	}
}

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;
    }
};

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;
}

无重复字符的最长字串

LeetCode 3.Longest Substring Without Repeating Characters

 已知一个字符串,求用该字符串的无重复字符的最长子串的长度。

总体思路

细节设计

 

代码实现

#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 += s[i];
		    	if (result < word.length()){
	    			result = word.length();
	    		}
		    }
		    else{
    			while(begin < i && char_map[s[i]] > 1){
    				char_map[s[begin]]--;
		    		begin++;
		    	}
		    	word = "";
		    	for (int j = begin; j <= i; j++){
	    			word += s[j];
	    		}
    		}
	    }
    	return result;
    }
};

int main(){
	std::string s = "abcbadab";
	Solution solve;
	printf("%d\n", solve.lengthOfLongestSubstring(s));	
	return 0;
}

重复的DNA序列

LeetCode 187.Repeated DNA Sequences

将DNA序列看作是只包含['A','C','G','T']4个字符的字符串,给一个DNA字符串,找到所有长度为10的且出现超过1次的字串。

Solve1

总体思路

代码实现

#include <stdio.h>

#include <vector>
#include <string>
#include <map>

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);
	    	if (word_map.find(word) != word_map.end()){
	    		word_map[word] += 1;
	    	}
	    	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 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;
}

Solve2

总体思路

细节设计

代码实现

#include <stdio.h>

#include <vector>
#include <string>

int g_hash_map[1048576] = {0};

std::string change_int_to_DNA(int DNA){
	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;
}

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;
    }
};

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;
}

最小窗口字串

LeetCode 3.Longest Substring Without Repeating Characters

已知字符串S与字符串T,求在S中的最小窗口(区间),使得这个区间中包含了字符串T中的所有字符。

总体思路

 细节设计

代码实现

#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 += s[i];
		    	if (result < word.length()){
	    			result = word.length();
	    		}
		    }
		    else{
    			while(begin < i && char_map[s[i]] > 1){
    				char_map[s[begin]]--;
		    		begin++;
		    	}
		    	word = "";
		    	for (int j = begin; j <= i; j++){
	    			word += s[j];
	    		}
    		}
	    }
    	return result;
    }
};

int main(){
	std::string s = "abcbadab";
	Solution solve;
	printf("%d\n", solve.lengthOfLongestSubstring(s));	
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值