[特殊字符] 高效统计排序数组中目标元素的出现次数

给定一个已排序的数组和一个目标值,如何快速统计该目标值在数组中出现的次数?这是面试中非常经典的一道题,今天就来聊聊两种解法:线性搜索和二分搜索。

问题描述

假设有一个已排序的数组 arr[] 和一个整数 target,需要找出 target 在数组中出现的次数。

示例:

  • 输入:arr[] = [1, 1, 2, 2, 2, 2, 3], target = 2

  • 输出:4(2 出现了 4 次)

  • 输入:arr[] = [1, 1, 2, 2, 2, 2, 3], target = 4

  • 输出:0(4 不在数组中)

方法一:线性搜索(暴力法)

思路: 遍历整个数组,遇到与目标值相等的元素就计数加 1。

代码实现(Python):

python 复制代码
def countFreq(arr, target):
    res = 0
    for i in range(len(arr)):
        if arr[i] == target:
            res += 1
    return res

arr = [1, 1, 2, 2, 2, 2, 3]
target = 2
print(countFreq(arr, target))  # 输出 4

复杂度分析:

  • 时间复杂度:O(n),因为需要遍历整个数组。
  • 空间复杂度:O(1),只用了常数空间。

这种方法简单直观,但当数组很大时效率较低。

刷算法题时,遇到"排序数组中查找目标元素出现次数"这类问题,你是不是也卡在边界条件和二分查找的细节上?其实,理解这类问题的核心,关键在于把抽象的逻辑"看"清楚。强烈安利一个神器------图码,它提供60多种数据结构和算法的交互式动画可视化,能帮你把二分查找的每一步都"动"起来。更绝的是,你可以直接上传自己的C/C++/Java/Python代码,或者输入自定义数据,让网站自动生成动画,直观看到代码执行过程。无论你是备战408考研,还是准备数据结构期末考试,它都能把晦涩的算法拆解得明明白白。现在就去看看吧,说不定能让你少走很多弯路!

图码-数据结构与算法交互式可视化平台

访问网站:https://totuma.cn

方法二:二分搜索(最优解)

既然数组是已排序的,我们可以利用二分搜索来加速。核心思想是:

  1. 找到目标值的 第一次出现位置(下界)
  2. 找到 第一个大于目标值的位置(上界)
  3. 两者之差就是目标值的出现次数

代码实现(Python,使用内置函数):

python 复制代码
from bisect import bisect_left, bisect_right

def countFreq(arr, target):
    l = bisect_left(arr, target)
    r = bisect_right(arr, target)
    return r - l

arr = [1, 2, 2, 2, 2, 3, 4, 7, 8, 8]
target = 2
print(countFreq(arr, target))  # 输出 4

手动实现二分搜索(C++ 风格):

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int countFreq(vector<int> &arr, int target) {
    int l = lower_bound(arr.begin(), arr.end(), target) - arr.begin();
    int r = upper_bound(arr.begin(), arr.end(), target) - arr.begin();
    return r - l;
}

int main() {
    vector<int> arr = {1, 2, 2, 2, 2, 3, 4, 7, 8, 8};
    int target = 2;
    cout << countFreq(arr, target);  // 输出 4
    return 0;
}

复杂度分析:

  • 时间复杂度:O(log n),两次二分搜索,每次 O(log n)。
  • 空间复杂度:O(1)。

为什么二分搜索更快?

线性搜索需要遍历整个数组,当数组有 10 万个元素时,最坏情况要比较 10 万次。而二分搜索每次将搜索范围减半,只需比较约 log₂(100000) ≈ 17 次。

总结

方法 时间复杂度 空间复杂度 适用场景
线性搜索 O(n) O(1) 小数组或未排序数组
二分搜索 O(log n) O(1) 已排序的大数组

如果数组是已排序的,强烈推荐使用二分搜索,效率高且实现简单。如果数组未排序,可以先排序再二分,但排序本身需要 O(n log n) 时间,此时线性搜索可能更合适。

希望这篇文章对你有帮助!如果你有其他解法或问题,欢迎在评论区讨论~

相关推荐
炘爚12 小时前
数据结构:单链表
数据结构
都在酒里12 小时前
算法总结(二)深入浅出 PID 控制算法:原理、优化与 STM32 标准库实现
stm32·算法·pid算法·位置pid·增式pid
Sinsa_SI12 小时前
2026算法应用主题赛初赛-小学4-6组(c++)试卷(含答案+详细解析)
java·c++·算法
_深海凉_12 小时前
LeetCode热题100-排序链表
算法·leetcode·链表
代码中介商12 小时前
哈夫曼树:高效压缩数据的秘密武器
数据结构·算法
sheeta199812 小时前
LeetCode 每日一题笔记 日期:2026.05.22 题目:33. 搜索旋转排序数组
笔记·算法·leetcode
练习时长一年12 小时前
LeetCode热题100之缺失的第一个正数
数据结构·算法·leetcode
Severus_black12 小时前
【初阶数据结构与算法】八大排序之插入排序(直接插入、希尔),一次性讲清!
数据结构·算法·排序算法
加成BUFF12 小时前
MATLAB 基础命令合集:从入门到精通(环境、变量、矩阵、绘图全解析)
数据结构·matlab·矩阵