【力扣刷题】1287. 有序数组中出现次数超过25%的元素【双指针】

348 阅读1分钟

「这是我参与11月更文挑战的第 21 天,活动详情查看:2021最后一次更文挑战

原题链接

1287. 有序数组中出现次数超过25%的元素 - 力扣(LeetCode) (leetcode-cn.com)

题目描述

给你一个非递减的 有序 整数数组,已知这个数组中恰好有一个整数,它的出现次数超过数组元素总数的 25%。

请你找到并返回这个整数

测试用例

示例:

输入: arr = [1,2,2,6,6,6,6,7,10]
输出: 6

参数限制

  • 1 <= arr.length <= 10^4
  • 0 <= arr[i] <= 10^5

分析

阅读题目,已知一个有序的数组,数组中会存在重复元素,但这些重复的元素是紧紧排列在一起的

而题目,需要我们求出元素重复数超过数组 1/4 的元素,并且保证数组中仅仅只会有一个这样的元素。请注意这个阀值,是需要 超过1/4

这里提供两种思路:

① 使用 Map 存储元素出现的次数

我们使用一个 Object 对象来替代 Map 的键值对映射

出现的数字,就在对应的 key 上 +1,每次操作完成后,比较这个 key 对应统计的次数,是否满足要求,是则返回这个数;否,则继续遍历

② 使用双指针标记

我们使用两个指针 p1, p2,p1指向数组的开头,p2 往后遍历

当 p2 对应的值和 p1 相等时,计数 +1,然后比较这个计数是否超过阀值,超了就返回 p1 对应的值,没超就继续遍历

当 p2 对应的值和 p1 的值不等时,将 p1 的移动到 p2 处,p2 继续往后移动,并且清空计数

代码

代码是双指针的演示版

var findSpecialInteger = function(arr) {
    let need = Math.ceil((arr.length + 1) / 4);
    let count = 0,
        p1 = 0;
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] == arr[p1]) {
            count++;
            if (count >= need) return arr[p1];
        } else {
            count = 1;
            p1 = i;
        }
    }
    return -1;
};

image.png


今天的力扣刷题就分享到这里,感谢大家的阅读~