哈希表和字符串专题1—205. 同构字符串 1002. 查找共用字符 925. 长按键入 844.比较含退格的字符串 C++实现

news2024/12/27 1:44:10

文章目录

  • 205. 同构字符串
  • 1002. 查找共用字符
  • 925. 长按键入
  • 844.比较含退格的字符串
    • 栈模拟
    • 双指针

205. 同构字符串

在这里插入图片描述

class Solution {
public:
    bool isIsomorphic(string s, string t) {
        unordered_map<char, char> map1;
        unordered_map<char, char> map2;
        for(int i=0, j=0; i<s.size(); i++, j++)
        {
            // map1保存s[i] 到 t[j]的映射
            if(map1.find(s[i]) == map1.end()) map1[s[i]] = t[j];
            // map2保存t[j] 到 s[i]的映射
            if(map2.find(t[j]) == map2.end()) map2[t[j]] = s[i];
            //比较
            if(map1[s[i]] != t[j] || map2[t[j]] != s[i]) return false;
        }
        return true;
    }
};

1002. 查找共用字符

在这里插入图片描述
统计出搜索字符串里26个字符的出现的频率,然后取每个字符频率最小值,最后转成输出格式

void *memset(void *s, int ch, size_t n);

函数解释:将s中当前位置后面的n个字节(typedef unsigned int size_t)用 ch 替换并返回s。
memset的作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法,也就是将已开辟内存空间 s 的首 n 个字节的值设为值(非数值型字符) c。

class Solution {
public:
    vector<string> commonChars(vector<string>& words) {
        vector<string> result;//保存输出结果
        int hash[26] = {0};//统计所有字符的频率
        //1.剔除
        if(words.size() == 0) return result;
        //2.用words的第一个字符初始化hash
        for(int j=0; j<words[0].size(); j++)
        {
            hash[words[0][j] - 'a']++;
        }
        //for(int word : words[0]) hash[word - 'a']++;

        //3.统计words其他字符串的频率 并更新hash
        int hash1[26] = {0};//统计words中除第一个字符串的频率
        for(int i=1; i<words.size(); i++)
        {
            //清零hash1 0填充hash1 大小是26*sizeof(int)
            memset(hash1, 0, 26*sizeof(int));
            for(int j = 0; j <words[i].size(); j++)
            {
                //统计words其他字符串的频率
                hash1[words[i][j] - 'a']++;
            }
            
            //用hash1更新hash中的最小频率 遍历26个字母
            for(int i=0; i<26; i++)
            {
                hash[i] = min(hash[i], hash1[i]);
            }
        }
        //4.转化输出结果 遍历26个字母
        for(int i=0; i<26; i++)
        {
            //题目中包括重复字符
            while(hash[i] != 0)
            {
                string temp(1, i + 'a');//char转string
                result.push_back(temp);
                hash[i]--;//保存一次字符 频率减少一次
            }
        }
        return result;
    }
};

925. 长按键入

在这里插入图片描述
双指针,同时遍历name和type, 时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1),有三种情况

  1. name和type都遍历完了
  • name[i]和type[j]相同,i和j继续移动
  • name[i]和type[j]不相同
    • 如果type[j]的第一个字符就不同,即j=0时就不相同,false
    • 如果type[j]的第一个字符相同,j继续移动,跳过重复项。再次比较name[i]和type[j],如果相同,i和j继续移动;如果不相同,false
  1. name没有遍历完,false
  2. type没有遍历完,遍历剩余项,比较type[j]和type[j-1]
class Solution {
public:
    bool isLongPressedName(string name, string typed) {
        int i=0, j=0;
        while(i<name.size() && j<typed.size())
        {
            if(name[i] == typed[j])
            {
                i++;
                j++;
            }
            else
            {
                if(j == 0) return false;//如果第一位就不相同 返回false
                // j跨越重复项,向后移动,同时防止j越界
                while(j<typed.size() && typed[j] == typed[j-1]) j++;
                //跨越重复项后继续比较
                if(name[i] == typed[j])
                {
                    i++;
                    j++;
                }
                else return false;
            }
        }
        //name没有匹配完
        if(i < name.size()) return false;
        //type没有匹配完
        while(j < typed.size())
        {
            if(typed[j] == typed[j-1]) j++;
            else return false;
        }
        return true;
    }
};

844.比较含退格的字符串

在这里插入图片描述

栈模拟

  • 空间复杂度 O ( n + m ) O(n+m) O(n+m),时间复杂度 O ( n + m ) O(n+m) O(n+m)
  • 如果不是#字符,累加字符;如果是#字符且栈非空,弹出栈顶字符。最后比较两个栈是否一样

写法1

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        //方法1 栈模拟
        string ss;//当成栈
        string st;//当成栈
        for(int i=0; i<s.size(); i++)
        {
            if(s[i] != '#') ss += s[i];
            else if(!ss.empty()) ss.pop_back();
        }

        for(int i=0; i<t.size(); i++)
        {
            if(t[i] != '#') st += t[i];
            else if(!st.empty()) st.pop_back();
        }

        if(ss == st) return true;
        return false;
    }
};

写法2

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        //方法1 栈模拟 写法2
        string ss = stackStr(s, '#');//当成栈
        string st = stackStr(t, '#');//当成栈
        if(ss == st) return true;
        return false;
    }
private:
    string stackStr(string& s, char c)
    {
        string ss;
        for(int i=0; i<s.size(); i++)
        {
            if(s[i] != c) ss += s[i];
            else if(!ss.empty()) ss.pop_back();
        }
        return ss;
    }
};

双指针

  • 空间复杂度 O ( 1 ) O(1) O(1),时间复杂度 O ( n + m ) O(n+m) O(n+m)
  • 双指针同时从后向前遍历S和T,记录#的数量,模拟消除的操作,就是#的数量减1。
  • 如果#用完了,比较S[i]和T[j],如果S[i]和T[j]不相同返回false。如果S或者T其中一个遍历完了,也返回false。
  • 最后如果S和T同时遍历完了,返回true,否则false。
class Solution {
public:
    bool backspaceCompare(string s, string t) {
        //方法2 双指针模拟
        int sSkipNum = 0;//记录s中#数量
        int tSikpNum = 0;//记录t中#数量
        int i = s.size()-1;
        int j = t.size()-1;
        while(1)
        {
            //处理s中#字符
            while(i >= 0)
            {
                //模拟s中#退回操作
                if(s[i] == '#') sSkipNum++;//记录#数量
                else
                {
                    if(sSkipNum > 0) sSkipNum--;//相当于用了一次# 模拟退回操作
                    else break;//文本为空 跳出循环
                }
                i--;
            }

            while(j >= 0)
            {
                //模拟t中#退回操作
                if(t[j] == '#') tSikpNum++;
                else
                {
                    if(tSikpNum > 0) tSikpNum--;
                    else break;
                }
                j--;
            }

            //s和t有一个遍历完了跳出循环
            if(i < 0 || j < 0) break;
            //比较s和t剩余字符
            if(s[i] != t[j]) return false;
            i--;
            j--;
        }
        //说明S和T同时遍历完毕
        if(i == -1 && j == -1) return true;
        else return false;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/734030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI绘画:StableDiffusion炼丹Lora攻略-实战萌宠图片生成

Lora攻略-实战萌宠图片生成 写在前面的话一&#xff1a;准备二、Lora作用1.AI模特2.炼衣服Lora3.改变画风/画面背景Lora模型究竟是什么&#xff1f; 三、如何炼制自己的Lora模型&#xff1f;四、炼丹前的准备&#xff08;**下载整合包**&#xff09;五、选择合适的大模型六、高…

管理类联考——逻辑——记忆篇——数字编码——公式

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;考取过HCIE Cloud Computing、CCIE Security、CISP、RHCE、CCNP RS、PEST 3等证书。&#x1f433; &#x1f495;兴趣爱好&#xff1a;b站天天刷&…

MySQL练习题(2)

创建如下员工标表 插入数据 1-- 按员工编号升序排列不在10号部门工作的员工信息 2-- 查询姓名第二个字母不是A且薪水大于1000元的员工信息&#xff0c;按薪水降序排列 4-- 求每个部门的平均薪水 5-- 求每个部门的最高薪水 6-- 求每个部门…

Coverity 2021.9 for win Coverity 2022.6 for linux

Coverity是一款快速、准确且高度可扩展的静态分析 (SAST) 解决方案&#xff0c;可帮助开发和安全团队在软件开发生命周期 (SDLC) 的早期解决安全和质量缺陷&#xff0c;跟踪和管理整个应用组合的风险&#xff0c;并确保符合安全和编码标准。Coverity 是一款精确的综合静态分析与…

JVM04-优化JVM内存分配以及内存持续上升问题和CPU过高问题排查

1-JVM内存分配 1.1-JVM内存分配性能问题 JVM内存分配不合理最直接的表现就是频繁的GC&#xff0c;这会导致上下文切换等性能问题&#xff0c;从而降低系统的吞吐量、增加系统的响应时间。因此&#xff0c;如果你在线上环境或性能测试时&#xff0c;发现频繁的GC&#xff0c;且…

密码学入门——分组密码模式

文章目录 参考书一、简介二、ECB模式三、CBC模式四、CFB模式五、OFB模式六、CTR模式 参考书 图解密码技术&#xff0c;第三版 一、简介 分组密码工作模式指的是将明文分成固定长度的块&#xff0c;并对每个块应用相同的加密算法进行加密的过程。这些块的长度通常是64位或128…

leetcode 654. 最大二叉树

2023.7.9 又是一道递归构造二叉树的题&#xff0c;和昨天做的那道题从中序与后序遍历序列构造二叉树类似&#xff0c;5分钟AC了。 大致思路就是通过找到数组中的最大值&#xff0c;并将其作为根节点&#xff0c;然后递归地构建左子树和右子树&#xff0c;最终返回整个最大二叉树…

PMP项目管理-敏捷

敏捷知识体系&#xff1a; 传统项目特点 1> 一开始就对详细的需求进行很高的投入 2> 价值只有到项目结束的时候才能体现, 风险较高 3> 一开始就要编写很多的文档 4> 客户参与度不高, 澄清完需求之后基本不参与 5> 需要花大量的时间来汇报当前的项目状态 6> 无…

Freertos-mini智能音箱项目---IO扩展芯片PCA9557

项目上用到的ESP32S3芯片引脚太少&#xff0c;选择了PCA9557扩展IO&#xff0c;通过一路i2c可以扩展出8个IO。这款芯片没有中断输入&#xff0c;所以更适合做扩展输出引脚用&#xff0c;内部寄存器也比较少&#xff0c;只有4个&#xff0c;使用起来很容易。 输入寄存器 输出寄存…

线程本地变量交换框架-TransmitterableThreadLocal(阿里开源)

上文 &#xff1a;秒级达百万高并发框架-Disruptor TransmitterableThreadLocal介绍 TransmitterableThreadLocal简称TTL 是阿里巴巴开源的一个框架。TransmittableThreadLocal是对Java中的ThreadLocal进行了增强和扩展。它旨在解决在线程池或异步任务调用链中&#xff0c;Thre…

MAC电脑查看SHA256方式

背景 现在很多网站下载大文件时&#xff0c;以往通过查看文件大小来确定是否下载正确&#xff0c;但是很多情况下&#xff0c;文件下载后大小差不多&#xff0c;但是很多时候却时候出现无法安装的问题&#xff0c;有可能还是下载的文件出现错误&#xff0c;导致文件无法正常使…

机器学习 day25(softmax在神经网络模型上的应用)

输出层采用softmax 在识别手写数字的模型中&#xff0c;预测y只有两个结果&#xff0c;所以输出层采用sigmoid激活函数且只有一个神经元。若预测y有10个结果&#xff08;0-9&#xff09;&#xff0c;该模型的前向传播计算方式与识别数字的模型完全相同&#xff0c;即隐藏层的…

dubbo概念及基本架构

一. Dubbo概念 1、Dubbo是一个开源的高性能&#xff0c;轻量级的Java RPC框架 RPC&#xff1a;远程服务调用 2、RPC的远程服务调用和SOA的服务治理两种功能。 二. Dubbo架构 0、服务提供方首先启动 1、服务提供方启动后&#xff0c;将其注射到注册中心里 2、消费者想调用提供…

线程随机性

目录 线程随机性的展现 执行start()的顺序不代表执行run()的顺序 在使用多线程技术时&#xff0c;代码运行的结果与代码执行顺序或者调用顺序无关。线程是一个子任务&#xff0c;而CPU是以不确定的方式&#xff0c;或者说是以随机的时间来调用线程中的run方法的。所以说线程执…

nvm 下载nodejs 失败

解决办法&#xff1a; 1.查看nvm安装路径 nvm root2、在安装路径下找到setting.txt,添加两句话 node_mirror: http://npm.taobao.org/mirrors/node/ npm_mirror: https://npm.taobao.org/mirrors/npm/3.再执行nvm install 就可以了。

【uniapp开发小程序】实现读取手机剪切板第一条,识别并以姓名/手机号/收货地址格式输出

效果图&#xff1a; 完整代码&#xff1a; <template><view class""><text>测试</text><view click"pasteContent()" class"content">点击此处可快速识别 您的收货信息</view></view> </templat…

使用chatGPT + AI 绘图生成自己的专属头像

案例介绍 微信头像是朋友认识我们时的第一印象,或许是可爱、妖娆,或许是帅气、成熟,还有自然、厚重、调皮… 我们都有自己独特的故事,独特的思想,独特的爱好,对于头像当然有着自己独到的设计眼光。 接下来请允许我向大家展示如何使用chatGPT、AI绘图工具生成出自己的专属…

【vue学习】权限管理系统前端实现6-主页面布局

1.新建layout文件夹 新建index.vue 添加router const routes [{path: /,name: 首页,component: () > import(../layout)}, 2.登录添加跳转 loginRef.value.validate(async (valid)>{if(valid){try{let resultawait requestUtil.post("login?"qs.stringify(l…

人工智能面试总结-Transformer专题

B站:啥都会一点的研究生 公众号试读:啥都会一点的研究生 目录 说说什么是Transformer?说说Transformer中的Encoder?说说Transformer中的Decoder?说说Transformer在训练与测试阶段Decoder的输入、输出是什么?说说Transformer Encoder和Decoder有哪些不同?说说什么是Tran…

Qt/C++原创项目作品精选(祖传原创/性能凶残)

00 前言说明 从事Qt开发十年有余&#xff0c;一开始是做C#.NET开发的&#xff0c;因为项目需要&#xff0c;转行做嵌入式linux开发&#xff0c;在嵌入式linux上做可视化界面开发一般首选Qt&#xff0c;当然现在可选的方案很多比如安卓&#xff0c;但是十多年前那时候板子性能低…