问题形容
在整数数组中,如果一个整数的呈现频次和它的数值大小相等,咱们就称这个整数为「侥幸数」。
给你一个整数数组 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 的应用 …
集体愚见:前端同学刷力扣算法题,倡议只刷简略和中等类型就行了。至于艰难题目,应该不必去钻研,毕竟咱们也不是应聘算法工程师这一个岗位。
而刷算法的目标,一方面是去晋升开发中数据加工组装的能力(如:后端返回的数据结构很奇葩,且不违心批改;只能前端本人加工成能用的构造啦)
另一方面就是可能在某个中央,应用某种算法操作,可能晋升性能放慢效率
再一个就是为了应酬面试啦