Problem Description

In an integer array, an integer is called a "lucky number" if its occurrence frequency is equal to its numerical value.

Given an array of integers arr, please find and return a lucky number from it.

If there are multiple lucky numbers in the array, just return the largest one. Returns -1 if the array contains no lucky numbers.

Example 1:

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

Example 2:

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

Example 3:

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

Example 4:

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

Example 5:

 输入:arr = [7,7,7,7,7,7,7]
输出:7
The address of the original title of Leetcode: https://leetcode.cn/problems/find-lucky-integer-in-an-array

Thought analysis

The question is simple, it is to count the number of occurrences of each item in the array (count who has appeared several times), and see who is exactly equal to the number of occurrences; of course, there may be exactly multiple who are equal to the number of corresponding occurrences. At this time, it depends on whoever is bigger

  1. When we think of counting the number of occurrences of each item in the array, we will think of using the Map collection for statistics.

    1. For example, the for loop array, and then append to the map, the key in the key-value pair stored in the map is the item in the array, and the value is the number of times this item appears in the array. Code:

       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. Then use forof to traverse the map collection and do the number judgment
  2. Or think of using object statistics

    1. For example, the for loop array, and then add to the object. The key in the object is the item in the array, and the value is the number of times this item appears in the array. code

       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. Or use a reduce loop to count the number of operations

       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. Then use forin to traverse the object and do the number of judgments

code

Use 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 // 最后返回之即可
};

useObject

 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
};

Summarize

If there are too many leetcode questions, you will find that some questions are deformations of other simple questions.

For example, this question examines the number of occurrences of statistical items in the array (using Map collection statistics, using Object statistics)

And the use of the loop forof of Map, or the use of the reduce function, the use of forin...

Personal humble opinion: The front-end students brush the force deduction algorithm questions, and it is recommended to only brush the simple and medium types. As for difficult topics, there should be no need to study them. After all, we are not applying for the position of algorithm engineer.

The purpose of brushing the algorithm, on the one hand, is to improve the ability of data processing and assembly in development (for example: the data structure returned by the back-end is very strange and unwilling to modify it; only the front-end can be processed into a usable structure by itself)

On the other hand, it may be possible to use a certain algorithm somewhere to improve performance and speed up efficiency.

The other one is to prepare for the interview.


水冗水孚
1.1k 声望585 粉丝

每一个不曾起舞的日子,都是对生命的辜负