相关文章推荐
帅气的弓箭  ·  PowerApps ...·  1 周前    · 
重情义的单杠  ·  .NET Framework ...·  1 年前    · 

1. 两数之和 找数组内,两个元素值的和=target的数的下标 Map 来存遍历过的 key: 元素值``value: 下标 ,遍历数组,计算它和 target 的差,找 Map 中有没有:

  • 有:返回下标
  • 没有:加入 Map 中继续找
  • 失散的母子们:一群人中有几对母子,警察一个一个问他们要找的谁,用一张表存每个人的信息和要找的人,首先看表里有没有要找的那个人,如果没有就把他要找的人和信息记下来,看后面会不会有人找

    map 映射

    * @param { number[] } nums * @param { number } target * @return { number[] } var twoSum = function ( nums, target ) { // 使用map集合key:值,value:下标 let map = new Map () for ( let i = 0 ; i < nums. length ; i++) { // 遍历数组 let sub = target - nums[i] // 计算满足条件的差值 if (map. has (sub)) return [map. get (sub), i] // 如果之前遍历过的有,返回下标 else { map. set (nums[i], i) // 没有就加入set(k, v)存入map return []

    454. 四数相加 II

    454. 四数相加 II 四个 独立 的数组,求有几个A[i] + B[j] + C[k] + D[l] = 0,即 a + b + c + d = 0

  • 定义一个 map key: a+b,value: a+b出现过几次
  • 遍历A和B,统计两数组元素之和,出现次数,存入 map
  • 定义 count ,用来统计 a+b+c+d = 0 出现的次数
  • 遍历C和D, map 中找有 0-(c+d) 吗?有: **count** 加上出现次数
  • Set

    * @param { number[] } nums1 * @param { number[] } nums2 * @param { number[] } nums3 * @param { number[] } nums4 * @return { number } var fourSumCount = function ( nums1, nums2, nums3, nums4 ) { // 类似与两数相加,用map存 let map = new Map () //key为a+b,value为出现次数 for ( let a of nums1) { for ( let b of nums2) { let sum = a + b //先求a+b放入map map. set (sum, (map. get (sum) || 0 ) + 1 ) //如果之前没有0+1变为1,有就取值+1 let count = 0 // 存最终结果 for ( let c of nums3) { for ( let d of nums4) { let sub = 0 - (c+d) //求让和为0的 if (map. has (sub)) //在map中 count = count + map. get (sub) //个数+出现次数 return count

    383. 赎金信

    383. 赎金信 后一个字符串中能找到前一个字符串中的所有元素

    用数组映射

    * @param { string } ransomNote * @param { string } magazine * @return { boolean } var canConstruct = function ( ransomNote, magazine ) { let hash = new Array ( 26 ). fill ( 0 ) //哈希映射26个字母 let base = "a" . charCodeAt () for ( let i = 0 ; i < ransomNote. length ; i++) { //r数组有的++ hash[ransomNote[i]. charCodeAt () - base]++ for ( let j = 0 ; j < magazine. length ; j++) { //m数组有的-- hash[magazine[j]. charCodeAt () - base]-- for ( let h of hash) { //最后如果还有>0的数,说明存在r数组中有,m数组中没有的 if (h > 0 ) return false return true

    15. 三数之和

    15. 三数之和 在一个数组内,找三个数的和为0,形成的不能重复的数组 用双指针解题:a + b + c = 0

  • 首先对数组进行排序(小->大)
  • i 去遍历数组(a), l i 下一个(b), r 从最后一个(c),向中间移动找到合适的
  • 可以用 -1 -1 0 0 1 1 3 判断去重
  • 判断 去重 要找 与前一个是否相等 ,相等说明这个数的已经处理过了,再处理也是一样的 重复
  • 注意:不能先去重再找,会少一些情况:比如 [0, 0, 0] 就直接被删除了
  • 三指针剪枝

    * @param { number[] } nums * @return { number[][] } var threeSum = function ( nums ) { nums. sort ( ( a, b ) => a-b) // 按照升序对数组排序 let result = [], conut = 0 //存最后得到的数组 for ( let i = 0 ; i < nums. length ; i++) { // i去遍历数组 // 如果排序后第一个元素都>0,再与后面元素相加怎么也不可能为0 if (nums[i] > 0 ) break // a去重,如果前面已经有了说明重复了 if (i > 0 && nums[i] === nums[i- 1 ]) continue let l = i + 1 //l从i下一个 let r = nums. length - 1 //r从最后一个 while (l < r) { //循环找让a+b+c = 0 if (nums[i] + nums[l] + nums[r] > 0 ) r-- //>0 r前移让和变小 else if (nums[i] + nums[l] + nums[r] < 0 ) l++ //<0 l后移让和变大 else { //找到等于0 result[conut++] = [nums[i], nums[l], nums[r]] //加入结果数组 // 对l,r去重,移一位 while (nums[l + 1 ] === nums[l]) l++ // 如果下一个相同就跳过,找下一个不相同的 while (nums[r - 1 ] === nums[r]) r-- // 找到答案时,双指针同时收缩 l++ // 跳到不相同的下一个 return result

    18. 四数之和

    18. 四数之和 三数之和的升级版

  • 四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,一样是 l``r 移动找和满足 target ,五数之和、六数之和等等都采用这种解法
  • 剪枝的时候要用 break 直接结束循环(后面都不看了),不能直接 return nums[i] > target && nums[i] >=0 比如:数组是[-4, -3, -2, -1],target是-10,不能因为-4 > -10而跳过,看 nums[i] 是否 >=0 ,如果 >=0 ,说明后面比它大的都是正数,加上正数只会越来越大
  • 去重:与前一个相等,直接结束这次,继续下次循环 continue (这个数不用看了)
  • 排序:从小到大
  • 遍历前面的值
  • 剪枝,排除不满足的情况:已经大于 target >=0 后面值越来越大、和前面相同:必须加上 > 起始值限制 i > k + 1、k > 0
  • l, r 分别从剩下的往中间遍历
  • 四指针剪枝

    * @param { number[] } nums * @param { number } target * @return { number[][] } var fourSum = function ( nums, target ) { let result = [], count = 0 // 存 nums. sort ( ( a, b ) => a - b) // 排序 for ( let k = 0 ; k < nums. length ; k++) { //k遍历数组 // 剪枝:排除不满足的情况 //一级剪枝 if (nums[k] > target && nums[k] >= 0 ) break // 不可能==target if (k > 0 && nums[k] === nums[k - 1 ]) continue // k去重 for ( let i = k + 1 ; i < nums. length ; i++) { //i从k+1 let l = i + 1 let r = nums. length - 1 let sum = nums[k] + nums[i] // 已确定的k,i和 //二级剪枝 if (sum > target && sum >= 0 ) break // 第一次i = K + 1时不能和前面比较剪枝i > K + 1 if (i > k + 1 && nums[i] === nums[i - 1 ]) continue while (l < r) { if (sum + nums[l] + nums[r] > target) r-- else if (sum +nums[l] + nums[r] < target) l++ else { result[count++] = [nums[k], nums[i], nums[l], nums[r]] while (l < r && nums[l + 1 ] === nums[l]) l++ while (l < r && nums[r - 1 ] === nums[r]) r-- return result
  • 复盘:前端岗位的寒冬,用这3点进行自救
  • 🔥我说MySQL每张表最好不超过2000万数据,面试官让我回去等通知?
  • Web3.0对前端很友好?
  • 三面面试官:运行 npm run xxx 的时候发生了什么?
  • 私信