leetcode刷题第5天(一)

文章讲述了如何利用哈希表数据结构(C++中为数组,JavaScript中可使用Array或Map)判断两个字符串是否为字母异位词,通过统计字符出现次数来验证两字符串是否由相同的字母组成,但顺序可以不同。
摘要由CSDN通过智能技术生成

242.有效的字母异位词

题意:

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

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

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

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

思路:这道题可以用哈希表来解决,只需要判断s 和 t 是否有不相同的字母,不用考虑字母出现的顺序,符合哈希表能够快速找出一个元素的特点。首先掌握哈希表的构造,在c++中可以通过定义数组来实现(哈希表的键对应数组的索引),js中可以结合Array或者map来构造。

解法

  • 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;
    }
};
  • javascript
// 1. Array方法
var isAnagram = function(s, t) {  
    if(s.length !== t.length) return false; // 如果数组长度不相同,一定为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;
};

// 2. map方法
var isAnagram = function(s, t) {
  if(s.length !== t.length) return false;
  let char_count = new Map();
  for(let item of s) {
    char_count.set(item, (char_count.get(item) || 0) + 1) ;
  }
  for(let item of t) {
    if(!char_count.get(item)) return false; // 如果map中对应的字符的值为0,说明s中没有出现,直接返回false
    char_count.set(item, char_count.get(item)-1);
  }
  return true;
};

笔记:(补充一些js的基础知识)

  • Array.fill() 方法:会改变原数组
// 创建一个长度为5的数组,并填充为0
let arr = new Array(5).fill(0);
console.log(arr); // [0, 0, 0, 0, 0]

// 创建一个长度为3的数组,并填充为'hello'
let newArr = new Array(3).fill('hello');
console.log(newArr); // ['hello', 'hello', 'hello']

// 从索引1开始填充到索引3(不包括)
let arr2 = [1, 2, 3, 4, 5];
arr2.fill('a', 1, 3); 
console.log(arr2); // [1, 'a', 'a', 4, 5]
  • for… in和for…of的区别:

for...offor...in 是 JavaScript 中用于循环的两种不同语法,它们各自有不同的用途和行为。

  1. for…of 循环:
  • 用于遍历可迭代对象(iterable),比如数组、字符串、Map、Set 等。
  • 在每次迭代中,会将可迭代对象中的值赋给循环变量,而不是索引
  • 不支持普通对象的遍历,因为普通对象不是可迭代对象。

示例用法:

let arr = [1, 2, 3];

for (let value of arr) {
  console.log(value); // 1, 2, 3
}

let str = "hello";

for (let char of str) {
  console.log(char); // 'h', 'e', 'l', 'l', 'o'
}
  1. for…in 循环:
  • 用于遍历对象的可枚举属性包括自身和继承的可枚举属性
  • 在每次迭代中,会将对象的属性名赋给循环变量,而不是属性值
  • 一般不推荐用于遍历数组,因为它会遍历数组的所有可枚举属性,包括数组的原型链上的属性。

示例用法:

let obj = { a: 1, b: 2, c: 3 };

for (let key in obj) {
  console.log(key); // 'a', 'b', 'c'
  console.log(obj[key]); // 1, 2, 3
}

let arr = [1, 2, 3];

for (let index in arr) {
  console.log(index); // '0', '1', '2'
  console.log(arr[index]); // 1, 2, 3
}

总之,for...of 适用于遍历可迭代对象的值,而 for...in 适用于遍历对象的属性名。

  • js的 map 和 set 的区别:

在 JavaScript 中,MapSet 都是用来存储数据集合的数据结构,它们有一些区别:

  1. Map:
  • Map 是一种键值对的集合,其中每个键都唯一,并且可以存储任意类型的值
  • 键可以是任意数据类型,包括基本类型和对象引用。
  • 可以通过 set(key, value) 方法设置键值对,通过 get(key) 方法获取值,通过 delete(key) 方法删除键值对,以及通过 has(key) 方法检查键是否存在。
  • 可以迭代其中的键值对,支持 for...of 循环和 forEach 方法。
  • Map 中的键值对是有序的,插入顺序决定了迭代顺序。

示例用法:

let map = new Map();
map.set('key1', 'value1');
map.set('key2', 'value2');

console.log(map.get('key1')); // 'value1'
console.log(map.has('key2')); // true
map.forEach((value, key) => {
  console.log(`${key}: ${value}`);
});
  1. Set:
  • Set 是一种值的集合,其中每个值都是唯一的,不允许重复
  • 可以存储任意类型的值,但不允许重复的值存在。
  • 可以通过 add(value) 方法添加值,通过 delete(value) 方法删除值,以及通过 has(value) 方法检查值是否存在。
  • 可以迭代其中的值,支持 for...of 循环和 forEach 方法。
  • Set 中的值是有序的,但插入顺序不会影响迭代顺序。

示例用法:

let set = new Set();
set.add('value1');
set.add('value2');

console.log(set.has('value1')); // true
set.forEach(value => {
  console.log(value);
});

总的来说,Map 适用于需要键值对存储的情况,而 Set 适用于需要存储唯一值的情况。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值