乐趣区

关于leetcode:力扣之找出数组中的幸运数

问题形容

在整数数组中,如果一个整数的呈现频次和它的数值大小相等,咱们就称这个整数为「侥幸数」。

给你一个整数数组 arr,请你从中找出并返回一个侥幸数。

如果数组中存在多个侥幸数,只需返回 最大 的那个。如果数组中不含侥幸数,则返回 -1。

示例 1:

输出:arr = [2,2,3,4]
输入:2
解释:数组中惟一的侥幸数是 2,因为数值 2 的呈现频次也是 2。

示例 2:

输出:arr = [1,2,2,3,3,3]
输入:3
解释:1、2 以及 3 都是侥幸数,只须要返回其中最大的 3。

示例 3:

输出:arr = [2,2,2,3,3]
输入:-1
解释:数组中不存在侥幸数。

示例 4:

输出:arr = [5]
输入:-1

示例 5:

输出:arr = [7,7,7,7,7,7,7]
输入:7

力扣原题目地址:https://leetcode.cn/problems/…

思路剖析

题目简略,就是统计数组中每一项呈现的次数(统计谁呈现了几次),看看谁正好等于呈现的次数;当然可能正好有多个 谁 等于 其对应呈现的次数,这个时候,就看谁更大即可

  1. 一想到要统计数组中每一项呈现的次数,咱们就会想到应用 Map 汇合进行统计

    1. 比方 for 循环数组,而后往 map 里追加,map 中存储的键值对中的 key 为数组中的项,value 为数组中这一项呈现的次数。代码:

      let map = new Map()
      for (let i = 0; i < arr.length; i++) {if (map.has(arr[i])) {let count = map.get(arr[i])
              count = count + 1
              map.set(arr[i], count)
          } else {map.set(arr[i], 1)
          }
      }
      1. 而后再应用 forof 遍历 map 汇合,做次数判断即可
  2. 或者想到应用对象 Object 统计

    1. 比方 for 循环数组,而后往对象中去增加。对象中的 key 为数组中的项,value 为数组中这一项呈现的次数。代码

      let obj = {}
      for (let i = 0; i < arr.length; i++) {let item = arr[i]
          if (item in obj) {let count = obj[item]
              count = count + 1
              obj[item] = count
          } else {obj[item] = 1
          }
      }
      console.log(obj);
    2. 或者应用 reduce 循环去统计操作次数

      let res = arr.reduce((tempObj, item) => {if (item in tempObj) {let count = tempObj[item]
              count = count + 1
              tempObj[item] = count
          } else {tempObj[item] = 1
          }
          return tempObj
      }, {})
      console.log(res);
    3. 而后再应用 forin 遍历对象,做次数判断即可

代码

应用 Map

var findLucky = function (arr) {
    // 1. 统计次数
    let map = new Map()
    for (let i = 0; i < arr.length; i++) {if (map.has(arr[i])) {let count = map.get(arr[i])
            count = count + 1
            map.set(arr[i], count)
        } else {map.set(arr[i], 1)
        }
    }
    // 2. 定义初始 luckyNum,比方没有(没有返回 -1)let luckyNum = -1 
    // 3. 遍历 map 汇合
    for (const [key, value] of map) {if (key === value) { // 若某一项也等于其对应呈现次数
            key > luckyNum ? luckyNum = key : '' // 就做一个大小的判断(因为要取最大的那个)}
    }
    return luckyNum // 最初返回之即可
};

应用 Object

var findLucky = function (arr) {
    // 1. 应用对象的形式 reduce 函数
    let res = arr.reduce((tempObj, item) => {if (item in tempObj) {let count = tempObj[item]
            count = count + 1
            tempObj[item] = count
        } else {tempObj[item] = 1
        }
        return tempObj
    }, {})
    let luckyNum = -1
    for (const key in res) {/* 留神这里不能直接判断 key === res[key],因为对象中的 key 间接循环默认为字符串
          然而 value(res[key])是数字类型的。所以要把数字类型也转换为字符串类型的 */ 
        /* 或者应用双等于号,不应用三等于号。毕竟 js 会做类型转换。字符串 '1' 是弱等于数字 1 的
         if (key == res[key]) {......} */ 
        if (key === res[key] + '') {res[key] > luckyNum ? luckyNum = res[key] : ''
        }
    }
    return luckyNum
};

总结

如果 leetcode 题目刷多了,会发现,一些题目是另外一些简略题目的变形。

比方这一题考查的还是数组中统计项呈现的次数(应用 Map 汇合统计、应用 Object 统计)

以及 Map 的循环 forof 的应用,或者 reduce 函数的应用、forin 的应用 …

集体愚见:前端同学刷力扣算法题,倡议只刷简略和中等类型就行了。至于艰难题目,应该不必去钻研,毕竟咱们也不是应聘算法工程师这一个岗位。

而刷算法的目标,一方面是去晋升开发中数据加工组装的能力(如:后端返回的数据结构很奇葩,且不违心批改;只能前端本人加工成能用的构造啦)

另一方面就是可能在某个中央,应用某种算法操作,可能晋升性能放慢效率

再一个就是为了应酬面试啦

退出移动版