问题形容
在整数数组中,如果一个整数的呈现频次和它的数值大小相等,咱们就称这个整数为「侥幸数」。
给你一个整数数组 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/...
思路剖析
题目简略,就是统计数组中每一项呈现的次数(统计谁呈现了几次),看看谁正好等于呈现的次数;当然可能正好有多个 谁 等于 其对应呈现的次数,这个时候,就看谁更大即可
一想到要统计数组中每一项呈现的次数,咱们就会想到应用Map汇合进行统计
比方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) }}
- 而后再应用
forof
遍历map汇合,做次数判断即可
- 而后再应用
或者想到应用对象Object统计
比方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);
或者应用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);
- 而后再应用
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的应用...
集体愚见:前端同学刷力扣算法题,倡议只刷简略和中等类型就行了。至于艰难题目,应该不必去钻研,毕竟咱们也不是应聘算法工程师这一个岗位。
而刷算法的目标,一方面是去晋升开发中数据加工组装的能力(如:后端返回的数据结构很奇葩,且不违心批改;只能前端本人加工成能用的构造啦)
另一方面就是可能在某个中央,应用某种算法操作,可能晋升性能放慢效率
再一个就是为了应酬面试啦