leetcode 面试经典 150 题:同构字符串

news/2025/1/9 0:44:52/
链接字符串>同构字符串
题序号205
题型字符串
解法哈希表
难度简单
熟练度✅✅✅✅

题目

  • 给定两个字符串 s 和 t ,判断它们是否是同构的。

  • 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串同构的。

  • 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

  • 示例 1:
    输入:s = “egg”, t = “add”
    输出:true

  • 示例 2:
    输入:s = “foo”, t = “bar”
    输出:false

  • 示例 3:
    输入:s = “paper”, t = “title”
    输出:true

  • 提示:
    1 <= s.length <= 5 * 104
    t.length == s.length
    s 和 t 由任意有效的 ASCII 字符组成

哈希表

  1. 哈希表:是一种以键值对(key-value)形式存储数据的数据结构,它通过哈希函数将键映射到特定的位置(索引),从而实现高效的查找、插入和删除操作。

  2. 在 C++ 中,常用的哈希表容器是std::unordered_map

  3. 哈希表的特点

    • 高效性:哈希表的查找、插入和删除操作的平均时间复杂度是 O(1)。这是通过哈希函数直接定位到元素所在的位置实现的。
    • 非有序性:哈希表中的元素存储顺序通常和插入顺序不同,具体取决于哈希函数。如果需要有序的键值对,可以使用 std::map。
    • 冲突处理:当两个键经过哈希函数映射到相同的位置时,称为哈希冲突。哈希表通过链地址法(链表)或开放地址法(探测)解决冲突。
  4. c++ 示例:

#include <unordered_map>
#include <iostream>
using namespace std;int main() {// 定义一个哈希表unordered_map<string, int> myMap;// 插入键值对myMap["apple"] = 5;myMap["banana"] = 3;myMap["cherry"] = 8;// 访问值cout << "apple: " << myMap["apple"] << endl; //输出 5// 查找键是否存在if (myMap.count("banana")) {cout << "banana exists, value: " << myMap["banana"] << endl; //存在,输出值为 3}// 删除键值对myMap.erase("cherry");// 遍历哈希表for (const auto& pair : myMap) {cout << pair.first << ": " << pair.second << endl; //输出 apple 和 banana 的键值对}return 0;
}

题解

  1. 核心要点:使用哈希表(HashMap)来存储字符之间的映射关系。遍历字符串s和t的每个字符,建立字符的映射关系。如果s中的字符已经存在于映射中,并且对应的映射不是当前字符t中的字符,则返回false。如果t中的字符已经存在于映射中,并且对应的映射不是当前字符s中的字符,则返回false。否则,建立字符之间的映射关系。
  2. 复杂度:时间复杂度为O(n),其中 n 为字符串的长度。我们只需同时遍历一遍字符串 s 和 t 即可;空间复杂度为O(字符串的字符集)
  3. c++ 实现算法
bool isIsomorphic(string s, string t) {//两个字符串长度不一样,直接返回 falseif (s.length() != t.length()) return false;//使用两个哈希表来检查双向映射,确保一一对应的关系unordered_map<char, char> mapST; // 映射 s -> tunordered_map<char, char> mapTS; // 映射 t -> sfor (int i = 0; i < s.length(); i++) {char sChar = s[i];char tChar = t[i];// 检查 s -> t 的映射是否一致//检查字符 sChar 是否已经在 mapST 中有记录if (mapST.count(sChar)) {//如果 mapST 中记录的 sChar 的映射值不是当前的 tChar,//说明映射冲突,两个字符串无法是同构的,直接返回 falseif (mapST[sChar] != tChar) return false;} else {//如果 sChar 尚未在 mapST 中建立映射,就将当前的 sChar -> tChar 关系存入映射表中。mapST[sChar] = tChar;}// 检查 t -> s 的映射是否一致if (mapTS.count(tChar)) {if (mapTS[tChar] != sChar) return false;} else {mapTS[tChar] = sChar;}}return true;
}
  1. 算法演示:
  • 示例
    输入:s = “egg”, t = “add”

    • 第一轮 (sChar = ‘e’, tChar = ‘a’)
      mapST 为空,sChar = ‘e’ 不在 mapST 中。
      建立映射:mapST[‘e’] = ‘a’。
    • 第二轮 (sChar =‘g’, tChar = ‘d’)
      sChar = ‘g’ 不在 mapST 中。
      建立映射:mapST[‘g’] = ‘d’。
    • 第三轮 (sChar = ‘g’, tChar = ‘d’)
      sChar = ‘g’ 在 mapST 中,且 mapST[‘g’] == ‘d’,符合映射,继续。 返回 true,两个字符串是同构的。
  • 反例 s = “foo”, t = “bar”

    • 第一轮 (sChar = ‘f’, tChar = ‘b’)
      建立映射:mapST[‘f’] = ‘b’。
    • 第二轮 (sChar = ‘o’, tChar = ‘a’)
      建立映射:mapST[‘o’] = ‘a’。
    • 第三轮 (sChar = ‘o’, tChar = ‘r’)
      sChar = ‘o’ 在 mapST 中,但 mapST[‘o’] != ‘r’。 返回 false。
  1. c++ 完整demo:
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;bool isIsomorphic(string s, string t) {//两个字符串长度不一样,直接返回 falseif (s.length() != t.length()) return false;//使用两个哈希表来检查双向映射,确保一一对应的关系unordered_map<char, char> mapST; // 映射 s -> tunordered_map<char, char> mapTS; // 映射 t -> sfor (int i = 0; i < s.length(); i++) {char sChar = s[i];char tChar = t[i];// 检查 s -> t 的映射是否一致//检查字符 sChar 是否已经在 mapST 中有记录if (mapST.count(sChar)) {//如果 mapST 中记录的 sChar 的映射值不是当前的 tChar,//说明映射冲突,两个字符串无法是同构的,直接返回 falseif (mapST[sChar] != tChar) return false;} else {//如果 sChar 尚未在 mapST 中建立映射,就将当前的 sChar -> tChar 关系存入映射表中。mapST[sChar] = tChar;}// 检查 t -> s 的映射是否一致if (mapTS.count(tChar)) {if (mapTS[tChar] != sChar) return false;} else {mapTS[tChar] = sChar;}}return true;
}int main() {string s = "egg";string t = "add";cout << (isIsomorphic(s, t) ? "true" : "false") << endl;s = "foo";t = "bar";cout << (isIsomorphic(s, t) ? "true" : "false") << endl;s = "paper";t = "title";cout << (isIsomorphic(s, t) ? "true" : "false") << endl;return 0;
}

http://www.ppmy.cn/news/1561050.html

相关文章

软件需求规格是什么

软件需求规格&#xff08;Software Requirements Specification&#xff0c;简称SRS&#xff09;是软件开发过程中一个非常重要的文档&#xff0c;它详细描述了软件产品的功能和性能要求&#xff0c;以及为了满足这些要求而必须遵守的约束条件。软件需求规格为开发团队提供了一…

enzymejest TDD与BDD开发实战

一、前端自动化测试需要测什么 1. 函数的执行逻辑&#xff0c;对于给定的输入&#xff0c;输出是否符合预期。 2. 用户行为的响应逻辑。 - 对于单元测试而言&#xff0c;测试粒度较细&#xff0c;需要测试内部状态的变更与相应函数是否成功被调用。 - 对于集成测试而言&a…

Elasticsearch向量检索需要的数据集以及768维向量生成

Elasticsearch8.17.0在mac上的安装 Kibana8.17.0在mac上的安装 Elasticsearch检索方案之一&#xff1a;使用fromsize实现分页 快速掌握Elasticsearch检索之二&#xff1a;滚动查询(scrool)获取全量数据(golang) Elasticsearch检索之三&#xff1a;官方推荐方案search_after…

开源Material Design WPF UI 控件库简单上手

背景&#xff1a;学过怎么弄&#xff0c;但是又忘记了&#xff0c;现在复习一下这个控件库的使用 1.先到NuGet中将下载到项目中&#xff1a; 2.到github MaterialDesignInXamlToolkit中点击Getting started&#xff0c;将App.xaml改成样例那样

Go Ebiten游戏库入门教程

Ebiten介绍 Ebiten是一款基于Go言语的轻量级开源游戏库&#xff0c;适合快速开发和原型构建2D游戏。它支持多平台&#xff0c;包括Windows、macOS、Linux、iOS和Android。这使它成为小型游戏开发者和试验性项目的优秀选择。 游戏循环精简明了&#xff0c;包括Update (逻辑更新…

Python学习路线

以下是一个Python详细学习路线&#xff1a; 一、入门阶段&#xff08;第1 - 2个月&#xff09; 环境搭建与基础语法 安装与配置&#xff1a; 从Python官方网站&#xff08;Download Python | Python.org&#xff09;下载适合自己操作系统的Python版本并进行安装。 配置环境变…

计算机毕业设计Python动漫推荐系统 漫画推荐系统 动漫视频推荐系统 机器学习 bilibili动漫爬虫 数据可视化 数据分析 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

WebApi使用 (.Net Framework版)

1 创建 使用.Net做web后端&#xff0c;推荐使用.Net Core&#xff0c;微软在此基础上做了很多适配&#xff0c;包括内置Swagger&#xff0c;可以直接启动等等。而.Net Framework版&#xff0c;需要手动配置很多内容。 如果需要调用的项目是基于.Net Framework&#xff0c;那么…