leetcode part7 哈希表与字符串

#include
#include
#include
using namespace std;

/**
哈希表和字符串

哈希表(hash table),是根据关键字值(key)直接进行访问的数据结构
它通过把关键字值映射到表中一个位置(数组下标)来直接访问
以加快查找关键字值的速度
(python中的字典数据结构就是基于哈希表实现的)
映射函数被称为哈希函数,存放记录的数组称为哈希表

给定表M,存在函数f(key),对任意的关键字值key,带入函数后若能得到包含
该关键字的表中地址,称表M为哈希表
**/

int main(){
    int char_map[128]={0};
    string a="abcdefgaaxxy";
    // 统计字符串中各个字符的数量

    for(int i=0;i
#include
#include
using namespace std;

/**
使用哈希表对数组进行排序:要求数组中的元素必须是非负的整数
使用数组的下标对正整数进行排序
哈希表的长度就等于待排序数组中可能的最大元素
**/

int main(){
    int random[10]={999,1,444,7,20,9,1,3,7,7};
    int hash_map_temp[1000]={0};

    for(int i=0;i<10;i++){
        hash_map_temp[random[i]]++;
    }

    for(int i=0;i<1000;i++){
        for(int j=0;j
#include
#include
#include
using namespace std;

/**
用拉链法解决冲突,构造哈希表
此时哈希表为指针数组,数组中的每个元素是一个指针
由指针引申出一条单链表

不同的元素value经过哈希函数映射后,可能得到相同的hash_key下标
此时为了避免冲突,并不是在哈希表的该索引位置处进行数值的累加
而是首先以value为数据域构建新的链表节点,
再以头插法的形式将新的链表节点插入到哈希表的对应位置处
**/

struct ListNode{
    int val;
    ListNode *next;
    ListNode(int x):val(x),next(NULL){}
};

int hash_func(int key,int table_len){
    // 哈希函数,将key映射成在哈希表中的下标
    return key%table_len;
}

void insert_head(ListNode *hash_table[],ListNode *node,int table_len){
    int hash_key=hash_func(node->val,table_len);
    node->next=hash_table[hash_key]->next;
    hash_table[hash_key]->next=node;
}

bool search_temp(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;
        }
        else{
            head=head->next;
        }
    }
    return false;
}

int main(){
    const int TABLE_LEN=11;
    ListNode *hash_table[TABLE_LEN]={NULL};
    for(int i=0;i has_node_vec;
    int test[8]={1,1,4,9,20,30,150,500};

    for(int i=0;i<8;i++){
        has_node_vec.push_back(new ListNode(test[i]));
    }


    for(int i=0;i<8;i++){
        insert_head(hash_table,has_node_vec[i],TABLE_LEN);
    }

    cout<<"Hash table: "<next;

        while(temp_row!=NULL){
            cout<<"->"<val;
            temp_row=temp_row->next;
        }

        cout<next;
        bool find_flag=false;
        while(temp_row!=NULL){
            if(temp_row->val==i){
                cout<next;
        }
        if(find_flag==false){
            cout<
#include
#include
using namespace std;
/**
leetcode 409 最长回文串
使用哈希表统计字符出现的次数
    如果字符串出现的次数是偶数,则直接将出现次数累加到最终的次数上
    如果字符串出现的次数是奇数,则将次数-1,累加到最终的次数上
**/

class Solution {
public:
    int longestPalindrome(string s) {
        // 统计字符串中各个字符出现的次数
        int hash_map_temp[256]={0};
        for(int i=0;i
#include
using namespace std;
#include
#include
/**
leetcode 290. 单词规律
给定一种规律 pattern 和一个字符串 str
判断 str 是否遵循相同的规律。
这里的 遵循 指完全匹配,
例如,pattern里的每个字母和字符串 str 中的每个非空单词之间
存在着双向连接的对应规律

算法:
    动态地扫描输入的长字符串str,并以空格为关键字分隔符得到
    每一个单词,并得到当前pattern所对应的的字符,
    构建哈希函数,即字符串与pattern中字符的映射关系

**/

class Solution {
public:
    bool wordPattern(string pattern, string str) {
        string hash_dict[256]={""};
        // 构建哈希表,数组的每个元素是字符串类型

        int i=0;
        int word_index=0;
        string temp_word="";
        while(i
#include
#include
using namespace std;

/**
leetcode 49. 字母异位词分组
给定一个字符串数组,将字母异位词组合在一起。
字母异位词指字母相同,但排列不同的字符串。

输入字符串数组中的每个元素——字符串对应一个哈希表
将原始的字符串数组转换成哈希表数组后
再遍历哈希表数组,将哈希表数组相同的字符串放到同一个vector中

C++中局部变量的作用域
    C++中变量的作用域是使用花括号{} 区分的
    花括号内部的变量的作用域在整个花括号中都有效
    比如我之前的bug
    在for循环中定义了整型数组  int a[26]
    在for循环中之后又有语句将数组push到vector b中
    则下一次循环过程中对于整型数组a的修改将直接修改vector b中的元素

    为了避免这个问题,使用vector来替代整型数组,但还是超时了
**/

class Solution {
public:
    bool is_equal(vector a,vector b){
        for(int i=0;i<26;i++){
            if(a[i]!=b[i]){
                return false;
            }
        }
        return true;
    }

    vector > groupAnagrams(vector& strs) {
        vector > result;
        vector > hash_table_array;
        vector temp_hash_table;
        for(int i=0;iis_equal(hash_table_array[k],temp_hash_table)==true){
                    result[k].push_back(strs[i]);
                    find_hash=true;
                    break;
                }
            }
            if(find_hash==false){
                hash_table_array.push_back(temp_hash_table);
                vector temp_str;
                temp_str.push_back(strs[i]);
                result.push_back(temp_str);
            }
        }
        return result;
    }
};

int main(){
    string a[6]={"eat", "tea", "tan", "ate", "nat", "bat"};
    vector strs;
    for(int i=0;i<6;i++){
        strs.push_back(a[i]);
    }

    Solution s;
    vector > result=s.groupAnagrams(strs);

    cout<
#include
#include
#include
using namespace std;


class Solution {
public:
    bool is_equal(vector a,vector b){
        for(int i=0;i<26;i++){
            if(a[i]!=b[i]){
                return false;
            }
        }
        return true;
    }

    vector > groupAnagrams(vector& strs) {
        vector > result;
        map,vector > hash_table_array;
        // 使用STL模板库实现的map映射函数
        // 哈希表的key是当前字符串的对于各个字符的词频向量
        // 哈希表的value是string
        // STL 中的map对象具有find方法,查找当前的字典中是否包含某个键

        vector temp_hash_table;
        for(int i=0;i temp_str;
                temp_str.push_back(strs[i]);
                hash_table_array.insert(make_pair(temp_hash_table,temp_str));
            }
            else{
                hash_table_array[temp_hash_table].push_back(strs[i]);
            }
        }

        // C++中对于map的遍历
        map,vector >::iterator iter;
        for(iter=hash_table_array.begin();iter!=hash_table_array.end();iter++){
            result.push_back((*iter).second);
        }

        return result;
    }
};

int main(){
    string a[6]={"eat", "tea", "tan", "ate", "nat", "bat"};
    vector strs;
    for(int i=0;i<6;i++){
        strs.push_back(a[i]);
    }

    Solution s;
    vector > result=s.groupAnagrams(strs);

    cout<
#include
#include
#include
using namespace std;

/**
leetcode 3. 无重复字符的最长子串
    给定一个字符串,
    请你找出其中不含有重复字符的 最长子串 的长度。

**/

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.length()<=1){
            return s.length();
        }

        map > hash_dict;
        int start_index=0;
        int end_index=0;
        int max_length=1;
        while(end_index >::iterator iter;
            iter=hash_dict.find(s[end_index]);

            if(iter==hash_dict.end()){
                // 如果在当前的字典中并没有找到字符
                vector temp;
                temp.push_back(end_index);
                hash_dict.insert(make_pair(s[end_index],temp));
            }
            else{
                if(end_index-start_index>max_length){
                    max_length=end_index-start_index;
                }
                vector temp_vector;
                temp_vector=(*iter).second;
                if(start_index<=temp_vector[temp_vector.size()-1]){
                    start_index=temp_vector[temp_vector.size()-1]+1;
                }
                (*iter).second.push_back(end_index);
            }
            end_index++;
        }
        if(end_index-start_index>max_length){
            max_length=end_index-start_index;
        }
        return max_length;
    }
};

int main(){
    Solution s;
    cout<
#include
#include
#include
#include
using namespace std;


/**
leetcode 187
所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,
例如:“ACGAATTCCG”。
在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来查找 DNA 分子中所有出现超多一次的10个字母长的序列(子串)。
**/

class Solution {
public:
    vector findRepeatedDnaSequences(string s) {
        map word_map;
        vector result;

        for(int i=0;i ::iterator iter;
        for(iter=word_map.begin();iter!=word_map.end();iter++){
            if((*iter).second>1){
                result.push_back((*iter).first);
            }
        }
        return result;
    }
};


int main(){
    Solution s;

    vector result;
    result=s.findRepeatedDnaSequences("AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT");

    for(int i=0;i

 

你可能感兴趣的:(C++)