leetcode热题hot100【JS】 更新时间 2024.5.12 第一次更新
2024.5.17 第二次更新
刷算法题可能用到的函数和表示方式 常用的表达方式
数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 let arr = [];arr.push (1 ); arr.indexOf (1 ); function arraysAreEqual (array1, array2 ) { if (array1.length !== array2.length ) return false ; for (let i = 0 ; i < array1.length ; i++) { if (array1[i] !== array2[i]) return false ; } return true ; } let strs = ["hello" , "world" , "JavaScript" ];for (let i = 0 ; i < strs.length ; i++){ console .log (i,strs[i]); } for (let [i, str] of strs.entries ()) { console .log (i, str); } nums = [100 ,4 ,200 ,1 ,3 ,2 ]; nums.sort ((a, b ) => a - b); let n = 5 ; let arr = Array (n).fill (0 );console .log (arr);
字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 let c = 'a' ;let ASCIINum = c.charCodeAt (0 );let c1 = 'ab' ;let ASCIINum = c.charCodeAt (2 );let str = "hello" ;str.split ("" ).forEach (char => console .log (char)); function sortString (str ) { let arr = str.split ('' ); arr.sort (); return arr.join ('' ); } let originalString = "hello" ;let sortedString = sortString (originalString);console .log (sortedString);
Map 在JavaScript中,Map
是一种新的数据结构,它允许你存储键值对(key-value pairs)。与对象不同,Map
的键可以是任何类型的值,包括函数、对象或任何原始类型。下面是一些基本的 Map
对象用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 let map = new Map ();map.set ('key' , 'value' ); map.set (123 , 456 ); map.set ({}, 'Object' ); map.set (function ( ) {}, 'Function' ); console .log (map.get ('key' )); console .log (map.get (123 )); console .log (map.has ('key' )); console .log (map.has ('notExist' )); map.delete ('key' ); console .log (map.size );map.forEach ((value, key ) => { console .log (key, value); }); for (let [key, value] of map.entries ()) { console .log (key, value); } for (let [key, value] of map) { console .log (key, value); } map.clear ();
Set 在JavaScript中,Set
是一种新的数据结构,它类似于数组,但是它的一个主要特点是其内部的值都是唯一的,没有重复的值。Set
对象允许你存储任何类型的唯一值,无论是原始值或是对象引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 let mySet = new Set ();let mySet = new Set ([1 , 2 , 3 , 4 , 4 , 4 ]);console .log (mySet); mySet.add (5 ); mySet.add ("hello" ); mySet.add ({a : 1 , b : 2 }); console .log (mySet.has (1 )); console .log (mySet.has (6 )); mySet.delete (1 ); mySet.forEach (value => { console .log (value); }); for (let item of mySet) { console .log (item); } console .log (mySet.size );mySet.clear ();
Set是JavaScript ES6中引入的一种集合类型,它提供了一种存储唯一值的高效方式。
100题实战 哈希 两数之和【数组、哈希】 1. 两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
1 2 3 输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
1 2 输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3:
1 2 输入:nums = [3,3], target = 6 输出:[0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
code :
第一次写没有考虑到两个数的下标不能一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var twoSum = function (nums, target ) { for (let i = 0 ; i < nums.length ; i++){ let res = []; let index; if (( index = nums.indexOf (target - nums[i])) != -1 && index != i){ res.push (i); res.push (index); return res; } } };
字母异位词分组【数组、哈希、字符串】 49. 字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例 1:
1 2 输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"] 输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
1 2 输入: strs = [""] 输出: [[""]]
示例 3:
1 2 输入: strs = ["a"] 输出: [["a"]]
提示:
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i]
仅包含小写字母
code
一开始的想法是对每一个字符串的ASCII码求和,和一样的字符串就是字母异位词,但是仔细想一下就知道这样不对,即使字符不一样,也可能会出现SASCII码一样的情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 var groupAnagrams = function (strs ) { let hash = new Map (); for (let i = 0 ; i < strs.length ; i++){ let sumASCII = 0 ; strs[i].split ('' ).forEach (c => sumASCII += c.charCodeAt (0 )); if (hash.has (sumASCII)){ let arr = hash.get (sumASCII); arr.push (strs[i]); hash.set (sumASCII, arr); }else { let arr = []; arr.push (strs[i]); hash.set (sumASCII,arr); } } let res = []; hash.forEach ( (value, key ) => { res.push (value); }); return res; };
看了官方解法,有两种解法,排序和计数,很好的解法
排序
思路和上面的ASCII码的思路是一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 var groupAnagrams = function (strs ) { let mp = new Map (); for (let [i, str] of strs.entries ()){ let arr = str.split ('' ).sort (); let newStr = arr.join ('' ); if (mp.has (newStr)){ let subArr = mp.get (newStr); subArr.push (str); mp.set (newStr, subArr); }else { let subArr = []; subArr.push (str); mp.set (newStr, subArr); } } let res = []; mp.forEach ((value, key ) => res.push (value)); return res; };
【要二刷】最长连续序列【并查集、数组、哈希表】 128. 最长连续序列
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
1 2 3 输入:nums = [100,4,200,1,3,2] 输出:4 解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:
1 2 输入:nums = [0,3,7,2,5,8,4,6,0,1] 输出:9
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
思路是哈希表,但是刚开始没有想到有负数,通过用例 67/75
主要是超过时间限制了,10的9次方的数,遍历一遍就超时了
单出用hashtable[num]++;来计数判断不行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 var longestConsecutive = function (nums ) { if (nums.length ===0 ) return 0 ; let maxNum = 0 ; let minNum = 0 ; nums.map ( (v ) => { maxNum = Math .max (maxNum, v); minNum = Math .min (minNum, v); }); let hashTable1 = Array (maxNum + 1 ).fill (0 ); let hashTable2 if (minNum < 0 ){ hashTable2 = Array ( -1 * minNum + 1 ).fill (0 ); } for (let i = 0 ; i < nums.length ; i++){ if (nums[i] >= 0 ){ hashTable1[nums[i]]++; }else { hashTable2[ -1 * nums[i]]++; } } let res = 0 ; let maxLen1 = -1 ; let maxLen2 = -1 ; let l1 = 0 ; let l2 = 0 ; let f1 = false ; for (let i = 0 ; i <= maxNum ; i++){ if (hashTable1[i] != 0 ){ res++; }else { f1 = true ; maxLen1 = Math .max (maxLen1, res); res = 0 ; } if (!f1) l1++; } maxLen1 = Math .max (maxLen1, res); res = 0 let f2 = false ; for (let i = 1 ; i <= ( -1 * minNum) ; i++){ if (hashTable2[i] != 0 ){ res++; }else { f2 = true ; maxLen2 = Math .max (maxLen2, res); res = 0 ; } if (!f2) l1++; } maxLen2 = Math .max (maxLen2, res); return Math .max (maxLen1, maxLen2, l1+l2); };
稍微看了一下题解思路,说是主要判断这个数的上一个数是否在哈希表中,感觉有点思路了,尝试写一下,没写出来,看完题解思路了才写的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var longestConsecutive = function (nums ) { let mySet = new Set (); nums.map ( v => {mySet.add (v);}); let res = 0 , cn = 1 ; for (let i = 0 ; i < nums.length ; i++){ cn = 1 ; if (!mySet.has (nums[i] - 1 )){ let st = nums[i] + 1 ; while (mySet.has (st)){ cn++; st++; } res = Math .max (res, cn); } } return res; };
双指针 移动零【数组、双指针】 283. 移动零
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
1 2 输入: nums = [0,1,0,3,12] 输出: [1,3,12,0,0]
示例 2:
提示 :
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶: 你能尽量减少完成的操作次数吗?
code
快慢指针的思路
慢指针指向待更新的数
快指针指向非0需要转移的数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var moveZeroes = function (nums ) { let len = nums.length ; let f = 0 , s = 0 ; for (s = 0 ; s < len; s++){ while ( f < len && nums[f] == 0 ) f++; if (f >= len) break ; nums[s] = nums[f++]; } while (s<len){ nums[s++] = 0 ; } return nums; };
盛最多水的容器【双指针、贪心】 11. 盛最多水的容器
给定一个长度为 n
的整数数组 height
。有 n
条垂线,第 i
条线的两个端点是 (i, 0)
和 (i, height[i])
。
找出其中的两条线,使得它们与 x
轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明: 你不能倾斜容器。
示例 1:
1 2 3 输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
提示:
n == height.length
2 <= n <= 105
0 <= height[i] <= 104
code :
前几天刚做过,复习了一下
双指针,两边夹
贪心的想法,由于装水的面积是右桶的长短决定的,所以较短的那条边先向中间走(这是保证从长到短的宽度下的最优解)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var maxArea = function (height ) { let maxNum = -1 ; let st = 0 , end = height.length - 1 ; while (st < end){ maxNum = Math .max (maxNum, (end - st) * Math .min (height[st], height[end])); if (height[st] <= height[end]){ st++; }else end--; } return maxNum; };
【优先二刷】三数之和 【数组,双指针】 15. 三数之和
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意: 答案中不可以包含重复的三元组。
示例 1:
1 2 3 4 5 6 7 8 输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 解释: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 注意,输出的顺序和三元组的顺序并不重要。
示例 2:
1 2 3 输入:nums = [0,1,1] 输出:[] 解释:唯一可能的三元组和不为 0 。
示例 3:
1 2 3 输入:nums = [0,0,0] 输出:[[0,0,0]] 解释:唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105
code:
排序去重是一个很重要的点,有很多题目,都是组成元素一样,但是顺序不一样,此时,应该考虑排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 var threeSum = function (nums ) { let res = []; let set = new Set (); for (let i = 0 ; i < nums.length ; i++){ for (let j = i; j < nums.length ; j++){ if ( i != j){ let sum = nums[i] + nums[j]; let index = nums.indexOf (-sum); if (index != -1 && index != i && index != j){ let arr = []; arr.push (nums[i]); arr.push (nums[index]); arr.push (nums[j]); arr.sort (); if (!set.has (arr)){ res.push (arr); set.add (arr); } } } } } return res; };
但是这样写的话在JS中是不能用set去重的,因为set中的元素是对象,对象引用的是指针,就算排序后的数组中的每一个元素都是一样的,set也会认为这是不同的数组。然后尝试将数组使用join函数转换为字符串在传入set去重
但是还是有问题,测试用例过227/313,不知道哪里错了,看不出来.
还有效率问题:您的代码使用了三层循环(实际上是两层循环加一个线性搜索 indexOf),这导致时间复杂度高达 O(n^3),在 nums 数组较大时会非常低效。
思考:其实经常想不到sort排序的解法,应该想到的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 var threeSum = function (nums ) { let res = []; let set = new Set (); for (let i = 0 ; i < nums.length ; i++){ for (let j = i; j < nums.length ; j++){ if ( i != j){ let sum = nums[i] + nums[j]; let index = nums.indexOf (-sum); if (index != -1 && index != i && index != j){ let arr = []; arr.push (nums[i]); arr.push (nums[index]); arr.push (nums[j]); arr.sort (); let str = arr.join ('' ); if (!set.has (str)){ res.push (arr); set.add (str); } } } } } return res; };
转换思路,咨询了一下AI模型,跑了后还是对的
排序:首先对数组进行排序,这样可以更容易地避免重复的三元组,并且可以使用双指针技术来减少不必要的搜索。
双指针:使用一个外层循环遍历每个元素,然后在剩余部分使用两个指针(一个从左边开始,另一个从右边开始)来寻找两个数,使得这三个数的和为0。
跳过重复元素:在外层循环和双指针移动时,如果遇到相同的元素,应该跳过,以避免重复的三元组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 var threeSum = function (nums ) { nums.sort ((a,b ) => a - b); let res = []; for (let i = 0 ; i < nums.length - 2 ; i++){ if ( i > 0 && nums[i] == nums[i - 1 ]) continue ; let left = i + 1 , right = nums.length - 1 ; while (left < right){ let sum = nums[i] + nums[left] + nums[right]; if (sum === 0 ){ res.push ([nums[i], nums[right], nums[left]]); while (left < right && nums[left] == nums[left + 1 ]) left++; while (left < right && nums[right] == nums[right - 1 ]) right--; left++; right--; }else if (sum < 0 ){ left++; }else right--; } } return res; };
【!!dp,还没写】接雨水 42. 接雨水
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
1 2 3 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
1 2 输入:height = [4,2,0,3,2,5] 输出:9
提示:
n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105
滑动窗口 无重复字符的最长子串 3. 无重复字符的最长子串
给定一个字符串 s
,请你找出其中不含有重复字符的最长子串 的长度。
示例 1:
1 2 3 输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
1 2 3 输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
1 2 3 4 输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
code:
不用map,用set和单纯数组都行,数组的话就用include方法来查看字母是否已经存在于数组中,但是最好还是不要数组了,数组里面删除一个元素会很麻烦,主要还是哈希+滑动窗口的思想。
用set的话会简单一点点
带注释版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 var lengthOfLongestSubstring = function (s ) { if (s.length ==0 ) return 0 ; let maxLen = -1 ; let hash = new Map (); let st = 0 ; for (let end = 0 ; end < s.length ; end++){ let c = s[end]; if (hash.has (c)){ while ( st < end && s[st] != c){ hash.delete (s[st]); st++; } st++; }else { hash.set (c, 1 ); } maxLen = Math .max (maxLen, end - st + 1 ); } return maxLen; };
不带注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var lengthOfLongestSubstring = function (s ) { if (s.length ==0 ) return 0 ; let maxLen = -1 ; let hash = new Map (); let st = 0 ; for (let end = 0 ; end < s.length ; end++){ let c = s[end]; if (hash.has (c)){ while ( st < end && s[st] != c){ hash.delete (s[st]); st++; } st++; }else { hash.set (c, 1 ); } maxLen = Math .max (maxLen, end - st + 1 ); } return maxLen; };
找到字符串中所有字母异位词 438. 找到字符串中所有字母异位词
给定两个字符串 s
和 p
,找到 s
中所有 p
的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
示例 1:
1 2 3 4 5 输入: s = "cbaebabacd", p = "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
示例 2:
1 2 3 4 5 6 输入: s = "abab", p = "ab" 输出: [0,1,2] 解释: 起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。 起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。 起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
Code:
窗口不合理的情况比较复杂
带注释版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 var findAnagrams = function (s, p ) { let hash = new Map (); let hash2 = new Map (); let res = []; for (let i = 0 ; i < p.length ; i++){ if (hash.has (p[i])){ hash.set (p[i], hash.get (p[i]) + 1 ); }else hash.set (p[i], 1 ); } let st = 0 ; for (let end = 0 ; end < s.length ; end++){ let c = s[end]; if (hash2.has (c)){ hash2.set (c, hash2.get (c) + 1 ); }else hash2.set (c, 1 ); if (!hash.has (c)){ while (st != end + 1 ){ hash2.set (s[st], hash2.get (s[st]) - 1 ); st++; } }else if (hash2.get (c) > hash.get (c)){ while (hash2.get (c) != hash.get (c)){ hash2.set (s[st], hash2.get (s[st]) - 1 ); st++; } } while (end - st + 1 > p.length ){ hash2.set (s[st], hash2.get (s[st]) - 1 ); st++; } if (end - st + 1 === p.length ){ res.push (st); } } return res; };
不带注释版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 var findAnagrams = function (s, p ) { let hash = new Map (); let hash2 = new Map (); let res = []; for (let i = 0 ; i < p.length ; i++){ if (hash.has (p[i])){ hash.set (p[i], hash.get (p[i]) + 1 ); }else hash.set (p[i], 1 ); } let st = 0 ; for (let end = 0 ; end < s.length ; end++){ let c = s[end]; if (hash2.has (c)){ hash2.set (c, hash2.get (c) + 1 ); }else hash2.set (c, 1 ); if (!hash.has (c)){ while (st != end + 1 ){ hash2.set (s[st], hash2.get (s[st]) - 1 ); st++; } }else if (hash2.get (c) > hash.get (c)){ while (hash2.get (c) != hash.get (c)){ hash2.set (s[st], hash2.get (s[st]) - 1 ); st++; } } while (end - st + 1 > p.length ){ hash2.set (s[st], hash2.get (s[st]) - 1 ); st++; } if (end - st + 1 === p.length ){ res.push (st); } } return res; };
子串 【优先二刷】和为 K 的子数组 560. 和为 K 的子数组
给你一个整数数组 nums
和一个整数 k
,请你统计并返回 该数组中和为 k
的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例 1:
1 2 输入:nums = [1,1,1], k = 2 输出:2
示例 2:
1 2 输入:nums = [1,2,3], k = 3 输出:2
code:
一刷本来想用滑动窗口做,但是发现有负数,没法用滑动窗口做。
这个问题可以通过使用“前缀和”加上“哈希表”来高效解决。基本思路是,我们遍历数组,计算每个位置的前缀和,即从数组开始到当前元素的累计和。然后,对于每个前缀和,我们检查是否存在一个之前的前缀和,其值等于“当前前缀和 - k”。如果存在,这意味着这两个前缀和之间的元素的和正好为k。我们使用哈希表来存储每个前缀和出现的次数,这样就可以在O(1)时间内查找到之前的前缀和。
在这道题学会了前缀和
的用法,这确实是我比较少用的一个点
学习了:
前缀和的思想
用对象来构建哈希表
let of的用法,
forEach()
方法在遍历数组时访问的是原数组。这意味着在forEach()
循环中,您可以直接访问并操作原数组的元素。
forEach()
里面的回调函数确实可以修改原数组的元素。但是,需要注意的是,虽然您可以修改数组的元素,比如通过索引更改元素的值,您却不能通过forEach()
直接修改数组的结构,例如增加或删除元素,对数组结构的修改不会影响到遍历过程。这是因为forEach()
遍历的范围在第一次调用回调函数之前就已经确定了。
下面是一个示例,展示了如何通过forEach()
修改原数组的元素:
1 2 3 4 5 6 7 8 9 let nums = [1 , 2 , 3 , 4 ];nums.forEach ((value, index, array ) => { array[index] = value * 2 ; }); console .log (nums);
在这个例子中,我们通过forEach()
遍历数组,并将每个元素的值加倍。虽然我们在forEach()
的回调函数中直接修改了数组元素的值,但是请注意,如果尝试在遍历过程中添加或删除元素,可能不会影响当前的遍历过程,因为遍历的范围是在遍历开始前就已经确定了。
由此可见,这是一个数学题TAT,思路如下:
a1 a2 a3 a4 a5 a6 cn1 = a1 + a2 cn2 = a1 + a2 + a3 + a4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 var subarraySum = function (nums, k ) { let pre_sum_hash = {0 : 1 }; let sum = 0 ; let res = 0 ; for (let num of nums){ sum += num; let otherPreSum = sum - k; if (pre_sum_hash[otherPreSum] !== undefined ){ res += pre_sum_hash[otherPreSum]; } if (pre_sum_hash[sum] !== undefined ){ pre_sum_hash[sum]++; }else { pre_sum_hash[sum] = 1 ; } } return res; };