算法刷题-哈希表-有效的字母异位词

news/2024/10/18 5:50:16/

有效的字母异位词

    • 242.有效的字母异位词
    • 思路
    • 其他语言版本
    • 相关题目

数组就是简单的哈希表,但是数组的大小可不是无限开辟的

242.有效的字母异位词

力扣题目链接

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true

示例 2:
输入: s = “rat”, t = “car”
输出: false

说明:
你可以假设字符串只包含小写字母。

思路

先看暴力的解法,两层for循环,同时还要记录字符是否重复出现,很明显时间复杂度是 O(n^2)。

暴力的方法这里就不做介绍了,直接看一下有没有更优的方式。

数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。

需要定义一个多大的数组呢,定一个数组叫做record,大小为26 就可以了,初始化为0,因为字符a到字符z的ASCII也是26个连续的数值。

为了方便举例,判断一下字符串s= “aee”, t = “eae”。

操作动画如下:

在这里插入图片描述

定义一个数组叫做record用来上记录字符串s里字符出现的次数。

需要把字符映射到数组也就是哈希表的索引下标上,因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。

再遍历 字符串s的时候,只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。 这样就将字符串s中字符出现的次数,统计出来了。

那看一下如何检查字符串t中是否出现了这些字符,同样在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。

那么最后检查一下,record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false。

最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。

时间复杂度为O(n),空间上因为定义是的一个常量大小的辅助数组,所以空间复杂度为O(1)。

C++ 代码如下:

class Solution {
public:bool isAnagram(string s, string t) {int record[26] = {0};for (int i = 0; i < s.size(); i++) {// 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了record[s[i] - 'a']++;}for (int i = 0; i < t.size(); i++) {record[t[i] - 'a']--;}for (int i = 0; i < 26; i++) {if (record[i] != 0) {// record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。return false;}}// record数组所有元素都为零0,说明字符串s和t是字母异位词return true;}
};

其他语言版本

Java:

/*** 242. 有效的字母异位词 字典解法* 时间复杂度O(m+n) 空间复杂度O(1)*/
class Solution {public boolean isAnagram(String s, String t) {int[] record = new int[26];for (int i = 0; i < s.length(); i++) {record[s.charAt(i) - 'a']++;     // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了}for (int i = 0; i < t.length(); i++) {record[t.charAt(i) - 'a']--;}for (int count: record) {if (count != 0) {               // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。return false;}}return true;                        // record数组所有元素都为零0,说明字符串s和t是字母异位词}
}

Python:

class Solution:def isAnagram(self, s: str, t: str) -> bool:record = [0] * 26for i in s:#并不需要记住字符a的ASCII,只要求出一个相对数值就可以了record[ord(i) - ord("a")] += 1for i in t:record[ord(i) - ord("a")] -= 1for i in range(26):if record[i] != 0:#record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。return Falsereturn True

Python写法二(没有使用数组作为哈希表,只是介绍defaultdict这样一种解题思路):

class Solution:def isAnagram(self, s: str, t: str) -> bool:from collections import defaultdicts_dict = defaultdict(int)t_dict = defaultdict(int)for x in s:s_dict[x] += 1for x in t:t_dict[x] += 1return s_dict == t_dict

Python写法三(没有使用数组作为哈希表,只是介绍Counter这种更方便的解题思路):

class Solution(object):def isAnagram(self, s: str, t: str) -> bool:from collections import Countera_count = Counter(s)b_count = Counter(t)return a_count == b_count

Go:

func isAnagram(s string, t string) bool {record := [26]int{}for _, r := range s {record[r-rune('a')]++}for _, r := range t {record[r-rune('a')]--}return record == [26]int{}   // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
}

javaScript:

/*** @param {string} s* @param {string} t* @return {boolean}*/
var isAnagram = function(s, t) {if(s.length !== t.length) return false;const resSet = new Array(26).fill(0);const base = "a".charCodeAt();for(const i of s) {resSet[i.charCodeAt() - base]++;}for(const i of t) {if(!resSet[i.charCodeAt() - base]) return false;resSet[i.charCodeAt() - base]--;}return true;
};

TypeScript:

function isAnagram(s: string, t: string): boolean {if (s.length !== t.length) return false;let helperArr: number[] = new Array(26).fill(0);let pivot: number = 'a'.charCodeAt(0);for (let i = 0, length = s.length; i < length; i++) {helperArr[s.charCodeAt(i) - pivot]++;helperArr[t.charCodeAt(i) - pivot]--;}return helperArr.every(i => i === 0);
};

Swift:

func isAnagram(_ s: String, _ t: String) -> Bool {if s.count != t.count {return false}var record = Array(repeating: 0, count: 26)let aUnicodeScalar = "a".unicodeScalars.first!.valuefor c in s.unicodeScalars {record[Int(c.value - aUnicodeScalar)] += 1}for c in t.unicodeScalars {record[Int(c.value - aUnicodeScalar)] -= 1}for value in record {if value != 0 {return false}}return true
}

PHP:

class Solution {/*** @param String $s* @param String $t* @return Boolean*/function isAnagram($s, $t) {if (strlen($s) != strlen($t)) {return false;}$table = [];for ($i = 0; $i < strlen($s); $i++) {if (!isset($table[$s[$i]])) {$table[$s[$i]] = 1;} else {$table[$s[$i]]++;}if (!isset($table[$t[$i]])) {$table[$t[$i]] = -1;} else {$table[$t[$i]]--;}}foreach ($table as $record) {if ($record != 0) {return false;}}return true;}
}

Rust:

impl Solution {pub fn is_anagram(s: String, t: String) -> bool {      let mut record = vec![0; 26];let baseChar = 'a';for byte in s.bytes() {record[byte as usize - baseChar as usize] += 1;} for byte in t.bytes() {record[byte as usize - baseChar as usize] -= 1;} record.iter().filter(|x| **x != 0).count() == 0}
}

Scala:

object Solution {def isAnagram(s: String, t: String): Boolean = {// 如果两个字符串的长度不等,直接返回falseif (s.length != t.length) return falseval record = new Array[Int](26) // 记录每个单词出现了多少次// 遍历字符串,对于s字符串单词对应的记录+=1,t字符串对应的记录-=1for (i <- 0 until s.length) {record(s(i) - 97) += 1record(t(i) - 97) -= 1}// 如果不等于则直接返回falsefor (i <- 0 until 26) {if (record(i) != 0) {return false}}// 如果前面不返回false,说明匹配成功,返回true,return可以省略true}
}

C#:

 public bool IsAnagram(string s, string t) {int sl=s.Length,tl=t.Length;if(sl!=tl) return false;int[] a = new int[26];for(int i = 0; i < sl; i++){a[s[i] - 'a']++;a[t[i] - 'a']--;}       foreach (int i in a){if (i != 0)return false;}return true;}

相关题目

  • 383.赎金信
  • 49.字母异位词分组
  • 438.找到字符串中所有字母异位词

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

相关文章

GO-slice详解

GO-slice详解 简介 slice&#xff08;切片&#xff09;是go中常见和强大的类型&#xff0c;这篇文章不是slice使用简介&#xff0c;从源码角度来分析slice的实现&#xff0c;slice的一些迷惑的使用方式&#xff0c;同时也讲清楚一些问题。 slice的底层实现是数组&#xff0c…

[安卓广播入门][1]Android Studio接收系统广播

一、新建项目 二、增加权限 <uses-permission android:name"android.permission.ACCESS_NETWORK_STATE" />三、代码 public class MainActivity extends AppCompatActivity {private IntentFilter intentFilter;//过滤隐式意图private NetworkChangeReceiver…

gopro lrv文件和thm文件

gopro最新固件会有的文件&#xff0c;在录像时生成mp4的同时伴随lrv和thm文件的生成&#xff0c;分别是对应录像的小格式版本&#xff0c;改mp4后缀可直接播放&#xff0c;thm文件为改视频的第一帧&#xff0c;可改jpg后缀打开&#xff0c;均用作屏幕或手机预览显示使用。

怎么恢复GoPro运动相机SD卡删除格式化丢失的MP4视频

数据丢失问题 GoPro运动相机里的SD卡&#xff0c;误格式化后想要恢复数据&#xff0c;使用一般恢复软件恢复出来的文件全部是损坏的&#xff0c;无法打开。 恢复技术分析 1. GoPro运动相机录制的MP4视频会同步进行高分辨率、低分辨率2种视频模式进行录制&#xff0c;低分辨率…

完美配件:它可让GoPro相机续航翻倍

相对于 GoPro Hero 5 的强性能&#xff0c;不少用户更亲睐体积更为小巧的 GoPro Session。 Session 最大的优势的就是便携&#xff0c;简单的立方体造型&#xff0c;前侧几乎仅能容纳一枚镜头&#xff0c;已经达到了运动相机的极限尺寸。 不过机身小就带来了一个问题&#xff0…

大疆没有边界:刚拳打GoPro,又脚踢优必选

李根 发自 纽凹非寺 量子位 报道 | 公众号 QbitAI 干一行&#xff0c;干好一行&#xff0c;而且刚一出手就卓尔不凡。 配得上这样标准的公司全球都不多&#xff0c;但DJI大疆创新肯定位列名单。 刚刚推出的教育机器人产品&#xff0c;也在印证上述判断。 挺进教育领域 6月12日&…

go android app下载地址,goPro安卓app下载

goPro安卓app下载地址免费提供给大家&#xff0c;goPro是一款功能强大的运动摄像机软件&#xff0c;不仅支持极限拍照&#xff0c;还有视频直播功能&#xff0c;稳定性更强&#xff0c;更有超多拍摄技巧可以免费学习哦&#xff01; 软件介绍 GoPro是一款功能非常全面的运动摄像…

解决GoPro Quik频繁自动登出的问题

背景&#xff1a;去年入了一台狗&#xff0c;想体验一下它的强大&#xff0c;于是在我的Surface上安装最新版的官方的GoPro Quik应用程序。大概是不支持硬件加速的原因&#xff0c;一打开预览直接卡爆。 于是改在渲染机上安装使用。然而总是自动登出。 通过多次试验&#xff08…