首页 > 编程语言 >算法专题九: 哈希表与字符串

算法专题九: 哈希表与字符串

时间:2024-10-21 12:51:07浏览次数:3  
标签:hash string int ret ++ 算法 表与 哈希 left

目录

哈希表

1. 两数之和

在这里插入图片描述

固定一个数, 找前面有没有target - x这个数, 使用哈希表, 每次查找之后把这个数丢入到哈希表中, 哈希表中存储这个数字的下标, 时间复杂度为O(N) , 空间复杂度也为O(N).

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> hash;
        for(int i = 0; i < nums.size(); i++)
        {
            int x = target - nums[i];
            if(hash.count(x))
                return {hash[x], i};
            hash[nums[i]] = i;
        }
        return {-1,-1};
    }
};

2. 判断是否为字符重拍排

在这里插入图片描述

创建两个哈希表, 依次比较, 但是可以进行优化, 仅需创建一个哈希表, 前面我们可以先处理如果两个字符串长度不相等直接返回false, 然后遍历第二个字符串, 每次遍历之后讲hash对应的位置-- ,如果某个位置减到小于0, 则说明两个字符串不一样, 直接返回false即可

class Solution {
public:
    bool CheckPermutation(string s1, string s2) {
        if(s1.size () != s2.size()) return false;
        int hash[26] = {0};
        for(int i = 0; i < s1.size(); i++)
            hash[s1[i] - 'a']++;
        for(int i  = 0; i < s2.size(); i++)
            if(--hash[s2[i] - 'a'] < 0) 
                return false;
        return true;
    }
};

3. 是否存在重复元素

在这里插入图片描述

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_map<int,int> hash;
        for(int i = 0; i < nums.size(); i++)
        {
            if(hash.count(nums[i]))
                return true;
            hash[nums[i]]++;
        }
        return false;
    }
};

4. 存在重复元素Ⅱ

在这里插入图片描述

如果找到了key和当前元素一样, 那么还需要判断绝对值时候小于k, 只有小于k才能返回, 否则的话更新当前元素的下标存储到哈希表中

class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        unordered_map<int,int> hash;
        for(int i = 0; i < nums.size(); i++)
        {
            if(hash.count(nums[i]))
            {
                if(abs(hash[nums[i]] - i) <= k)
                    return true;
                else hash[nums[i]] = i;
            }
            hash[nums[i]] = i;
        }
        return false;
    }
};

5. 字母异位词分组

在这里插入图片描述

使用哈希表讲字母异位词进行分组, 快速判断是否是字母异位词的方法还有一种就是排序, 排序之后的字符串为key, 原字符串为val进行存储, 就直接进行了分类, 之后遍历hash表, 把y都尾插到返回vector即可.

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,vector<string>> hash;
        for(auto e : strs)
        {
            string tmp = e;
            sort(tmp.begin(),tmp.end());
            hash[tmp].push_back(e);
        }
        vector<vector<string>> ret; 
        for(auto [x,y] : hash)
            ret.push_back(y);
        return ret;
    }
};

字符串

1. 最长公共前缀

在这里插入图片描述

解法一: 两两比较, 然后求出公共部分
解法二: 同时进行比较, 这里使用解法二, 固定第一个字符串, 将后面所有的字符串都同时与第一个字符串的第一个元素进行比较, 如果不相同直接返回, 如果相同则在本次循环之后ret加上这个字符, 如果循环结束, 则说明第一个字符串就是最长公共前缀.

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        string ret;
        for(int i = 0; i < strs[0].size(); i++)
        {
            char tmp = strs[0][i];
            for(int j = 1; j < strs.size(); j++)
            {
                if(strs[j][i] != tmp)
                    return ret;
            }
            ret += tmp;
        }
        return strs[0];
    }
};

2. 最长回文子串

在这里插入图片描述

在这里插入图片描述

暴力解法: 依次枚举出所有的子数组, 然后在判断是否是回文子串, 时间复杂度为O(N^3) , 并且代码复杂, 这里我们可以使用中心拓展法, 以一个点为中心, 然后向两边进行扩展, 如果相同则指针往两边移动, 统计奇数时只需要left和right在同一个位置, 如果统计偶数回文串时把left = i , right = i + 1即可, 这样就可以统计出所有的回文子串.

class Solution {
public:
    string longestPalindrome(string s) {
        //中心拓展法
        int len = 0, begin = 0, n = s.size();
        for(int i = 0; i < n; i++)
        {
            //奇数回文串
            int left = i, right = i;
            while(left >= 0 && right < n && s[left] == s[right])
            {
                left--;
                right++;
            }
            if(right - left - 1 > len)
            {
                begin = left + 1;
                len = right - left - 1;
            }
            //偶数回文串
            left = i, right = i + 1;
            while(left >= 0 && right < n && s[left] == s[right])
            {
                left--;
                right++;
            }
            if(right - left - 1 > len)
            {
                begin = left + 1;
                len = right - left - 1;
            }
        }
        return s.substr(begin,len);
    }
};

3. 二进制求和

在这里插入图片描述

在这里插入图片描述

模拟列竖式即可

class Solution {
public:
    string addBinary(string a, string b) {
        string ret;
        int t = 0 , cur1 = a.size() - 1, cur2 = b.size() - 1;
        while(cur1 >= 0 || cur2 >= 0 || t)
        {
            if(cur1 >= 0) t += a[cur1--] - '0';
            if(cur2 >= 0) t += b[cur2--] - '0';
            ret += (t % 2) + '0';
            t /= 2;
        }
        reverse(ret.begin(),ret.end());
        return ret;
    }
};

4. 字符串相乘

#

算法原理:

整体思路就是模拟我们⼩学列竖式计算两个数相乘的过程。但是为了我们书写代码的⽅便性,我们选择⼀种优化版本的,就是在计算两数相乘的时候,先不考虑进位,等到所有结果计算完毕之后,再去考虑进位

在这里插入图片描述

class Solution {
public:
    //无进位相乘
    string multiply(string n1, string n2) {
        //1.反转
        reverse(n1.begin(),n1.end());
        reverse(n2.begin(),n2.end());
        int m = n1.size(), n = n2.size();
        vector<int> tmp(m + n - 1);
        //无进位相乘相加
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                tmp[i + j] += (n1[i] - '0') * (n2[j] - '0');
        //处理进位
        int t = 0, cur = 0;
        string ret;
        while(cur < m + n - 1 || t)
        {
            if(cur < m + n - 1) t += tmp[cur++];
            ret += t % 10 + '0';
            t /= 10;
        }
        //处理前导0
        while(ret.size() > 1 && ret.back() == '0') ret.pop_back();
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

标签:hash,string,int,ret,++,算法,表与,哈希,left
From: https://blog.csdn.net/2201_75644377/article/details/143092090

相关文章

  • 1.基础算法
    [[ACM技能树]]1.1构造定义:构造算法,顾名思义,是指直接构造出问题的一个解决方案的方法。这类算法通常适用于那些有明确解决方案或者解的结构可以直接描述的问题。与暴力搜索或试错法不同,构造算法往往需要对问题有更深的理解和分析,通过逻辑或数学方法直接构造出答案。特点......
  • 【贪心算法】(第七篇)
    目录最⻓回⽂串(easy)题目解析讲解算法原理编写代码增减字符串匹配(easy)题目解析讲解算法原理编写代码最⻓回⽂串(easy)题目解析1.题目链接:.-力扣(LeetCode)2.题目描述给定⼀个包含⼤写字⺟和⼩写字⺟的字符串s,返回通过这些字⺟构造成的最⻓的回⽂串。在构造过程......
  • 【贪心算法】(第六篇)
    目录按⾝⾼排序(easy)题目解析讲解算法原理编写代码优势洗牌(⽥忌赛⻢)(medium)题目解析讲解算法原理编写代码按⾝⾼排序(easy)题目解析1.题目链接:.-力扣(LeetCode)2.题目描述给你⼀个字符串数组names,和⼀个由互不相同的正整数组成的数组heights。两个数组的⻓度......
  • 算法比赛中常用的快读
    在算法比赛中,快读是一个常用的技巧,用于提高输入数据的速度。常见的快读方法有以下几种:1.C++中的快读C++中常用scanf和getchar进行快读。#include<cstdio>#include<cstring>inlineintread(){intx=0,f=1;charc=getchar();while(c<'0'......
  • Python 自编码器(Autoencoder)算法详解与应用案例
    目录Python自编码器(Autoencoder)算法详解与应用案例引言一、自编码器的基本原理1.1自编码器的结构1.2自编码器的类型二、Python中自编码器的面向对象实现2.1`Autoencoder`类的实现2.2`Trainer`类的实现2.3`DataLoader`类的实现三、案例分析3.1手写数字去噪自......
  • Python Bagging算法详解与应用案例
    这里写目录标题PythonBagging算法详解与应用案例引言一、Bagging的基本原理1.1Bagging的概念1.2Bagging的步骤1.3Bagging的优势与挑战二、Python中Bagging的面向对象实现2.1`DecisionTree`类的实现2.2`Bagging`类的实现2.3`Trainer`类的实现三、案例分析3.1......
  • 普通人,适合做算法吗?大语言模型有未来吗?
    直接说结论:目前来说,算法领域不适合,但是大语言模型工程可以!发展背景AI发展的几个阶段,统计、算法策略、机器学习、深度学习和大语言模型在2013~2014年的时候,岗位极度稀缺,大厂也是非常需要。所以背景显得没那么重要了。到了2015年~2020年,机器学习相关的培训课程和学校教学,......
  • 最强总结!十大回归类算法模型 !!!
     【转载】 最强总结!十大回归类算法模型!!! 今儿和大家分享的回归类算法有:线性回归Ridge回归Lasso回归弹性网络回归多项式回归决策树回归随机森林回归支持向量回归K近邻回归梯度提升回归1.线性回归线性回归是一种用于描述两个或多个变量......
  • 泥石流山体滑坡监控AI视觉识别检测算法
    泥石流山体滑坡监控AI视觉识别检测算法基于AI视觉识别技术,泥石流山体滑坡监控AI视觉识别检测算法通过监控摄像头采集到的图像和视频流,利用先进的视觉识别算法分析和判断监控画面中是否出现泥石流和山体滑坡现象。泥石流山体滑坡监控AI视觉识别检测算法一旦系统识别到灾害事件的发......
  • 支持国密算法的数字证书-国密SSL证书详解
    在互联网中,数字证书作为标志通讯各方身份信息的数字认证而存在,常见的数字证书大都采用国际算法,比如RSA算法、ECC算法、SHA2算法等。随着我国加强网络安全技术自主可控的大趋势,也出现了支持国密算法的数字证书-国密SSL证书。那么什么是国密SSL证书?国密SSL证书支持哪种国密算法呢......