28.找出字符串中第一个匹配项的下标
题目
给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
示例 1:
输入:haystack = "sadbutsad", needle = "sad" 输出:0 解释:"sad" 在下标 0 和 6 处匹配。 第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:
输入:haystack = "leetcode", needle = "leeto" 输出:-1 解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
提示:
1 <= haystack.length, needle.length <= 104
haystack
和needle
仅由小写英文字符组成
方法一、使用JS中的封装函数indexOf
indexOf
方法是 JavaScript 中字符串和数组对象的一个内置方法,用于查找一个值在给定数组或字符串中首次出现的位置。如果没有找到该值,则返回 -1。以下是 indexOf
方法的详细信息:
数组中的 indexOf
语法
array.indexOf(searchElement[, fromIndex])
参数
-
searchElement
:需要查找的元素。 -
fromIndex
(可选):开始查找的位置。如果该索引值大于或等于数组长度,则返回 -1。如果为负值,则从数组的末尾开始向前查找,即 -1 表示从最后一个元素开始查找,-2 表示从倒数第二个元素开始查找,以此类推。
返回值
返回在数组中找到 searchElement
的第一个索引,如果不存在,则返回 -1。
示例
const array = [2, 5, 9];
console.log(array.indexOf(2)); // 输出:0
console.log(array.indexOf(7)); // 输出:-1
console.log(array.indexOf(9, 2)); // 输出:2
console.log(array.indexOf(2, -1)); // 输出:-1,因为从倒数第一个元素开始查找,找不到2
console.log(array.indexOf(5, -3)); // 输出:1,因为从倒数第三个元素开始查找,即从第一个元素开始查找
字符串中的 indexOf
语法
string.indexOf(searchValue[, fromIndex])
参数
searchValue
:需要查找的字符串。fromIndex
(可选):开始查找的位置。如果该索引值大于或等于字符串长度,则返回 -1。如果为负值,则从字符串的末尾开始向前查找。
返回值
返回 searchValue
在字符串中首次出现的位置的索引,如果不存在,则返回 -1。
示例
const str = "Hello world!";
console.log(str.indexOf("Hello")); // 输出:0
console.log(str.indexOf("world")); // 输出:6
console.log(str.indexOf("o")); // 输出:4,因为返回第一次出现的位置
console.log(str.indexOf("o", 5)); // 输出:7,从索引5开始查找
console.log(str.indexOf("bye")); // 输出:-1,因为字符串中不存在 "bye"
indexOf
方法在处理字符串和数组时非常有用,尤其是在需要确定某个值是否存在或者需要找到特定值的位置时。需要注意的是,indexOf
方法在比较值时使用的是严格相等(===),这意味着不会进行类型转换。
代码
var strStr = function(haystack, needle) {// 如果 needle 是空字符串,根据题目要求,返回 0if (needle === "") {return 0;}// 使用 indexOf 方法查找 needle 在 haystack 中的位置return haystack.indexOf(needle);};
方法二、通过字符串比较
通过字符串比较来找到子字符串 needle
在字符串 haystack
中的第一个匹配项的下标,而不使用 indexOf
方法,可以手动实现一个类似的逻辑。
1.比较在haystack中和needle长度相同的字符串
2.从当前索引到长度相同的位置 一一比较即可,也就是haystack中找当前索引0到haytack-neddle长度的位置为起始比较点。
3.对于needle,从haystack中的i+j位置开始挨个比较。只要出现不同的就停止 证明这一段肯定不相同。
function strStr(haystack, needle) {// 如果 needle 是空字符串,根据题目要求,返回 0if (needle === "") {return 0;}// 获取 haystack 和 needle 的长度const haystackLength = haystack.length;const needleLength = needle.length;// 只需要遍历到 haystack 剩余长度等于 needle 长度的位置for (let i = 0; i <= haystackLength - needleLength; i++) {// 检查从当前索引开始的子字符串是否与 needle 相同let match = true;for (let j = 0; j < needleLength; j++) {if (haystack[i + j] !== needle[j]) {match = false;break;}}// 如果找到匹配的子字符串,返回当前索引if (match) {return i;}}// 如果没有找到匹配项,返回 -1return -1;
}// 示例 1
console.log(strStr("sadbutsad", "sad")); // 输出:0// 示例 2
console.log(strStr("leetcode", "leeto")); // 输出:-1
方法三、通过数组比较
- 将
haystack
和needle
都转换为字符数组。 - 遍历
haystack
数组,对于每个字符,检查它是否是needle
数组的第一个字符。 - 如果找到匹配的字符,检查
haystack
中从当前位置开始的子数组是否与needle
数组相同。 - 如果找到完全匹配的子数组,返回当前索引。
- 如果遍历完
haystack
都没有找到匹配的子数组,返回 -1。
function strStr(haystack, needle) {// 如果 needle 是空字符串,返回 0if (needle === "") return 0;// 将 haystack 和 needle 转换为字符数组const haystackArr = haystack.split('');const needleArr = needle.split('');// 遍历 haystack 数组for (let i = 0; i <= haystackArr.length - needleArr.length; i++) {// 检查从当前位置开始的子数组是否与 needleArr 相同if (haystackArr.slice(i, i + needleArr.length).join('') === needleArr.join('')) {return i; // 找到匹配,返回当前索引}}// 没有找到匹配,返回 -1return -1;
}// 示例 1
console.log(strStr("sadbutsad", "sad")); // 输出:0// 示例 2
console.log(strStr("leetcode", "leeto")); // 输出:-1
243.有效的字母异位词
题目
给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的
示例 1:
输入: s = "anagram", t = "nagaram" 输出: true
示例 2:
输入: s = "rat", t = "car" 输出: false
提示:
1 <= s.length, t.length <= 5 * 104
s
和t
仅包含小写字母
进阶: 如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?
方法一、排序
如果s和t中的元素是相同的 只要对他们进行排序 然后判断相等与否 如果相同 就是字母异位词 如果不同就不是
- 首先将字符串
s
和t
分别转换为字符数组。 - 然后,您对这两个数组进行排序。
- 排序后,您将数组转换回字符串。
- 最后,您比较这两个排序后的字符串是否相等。
var isAnagram = function(s, t) {// //一、排序StrS=s.split('').sort().join('');StrT=t.split('').sort().join('');if(StrS===StrT) return true;else return false;
};
可以将字符串转换为字符数组,然后比较这两个数组是否相等。
- 创建字符数组,但并没有将它们转换回字符串。
- 使用
every
方法和数组的索引来比较排序后的数组的每个元素。
这种方法同样具有 O(n log n) 的时间复杂度,但是由于没有将数组转换回字符串,它可能稍微节省了一些时间和内存。
function areCharCountsEqual(s, t) {const sArray = Array.from(s).sort();const tArray = Array.from(t).sort();return sArray.length === tArray.length && sArray.every((value, index) => value === tArray[index]);
}
方法二、统计字母出现次数
统计s中每个元素出现的个数,在对t进行遍历,若存在这个元素则将这个元素减一,当t中有这个元素,但是count数组中却没有(包括count[char]为0和undefined),这种情况下返回false。
var isAnagram = function(s, t) {//二、统计字母出现次数// 如果两个字符串长度不同,它们不可能是字母异位词if (s.length !== t.length) {return false;}// 创建一个对象来统计字符出现的次数let count = {};//计算s和t中每个字符出现的次数for(let char of s){count[char]=(count[char]||0)+1;}for(let char of t){// if(count[char]===undefined||count[char]===0) return false;if(!count[char]) return false;count[char]--;// if(count[char]===-1) return false;}return true;
};