LeetCode 第34题:二分查找+扩展搜索

LeetCode 第34题:在排序数组中查找元素的第一个和最后一个位置

LeetCode 第34题要求在一个排序的数组中找到给定目标值的第一个和最后一个位置。如果目标值不存在,则返回 [-1, -1]。在本篇文章中,我将为大家提供详细的 C 语言解法,并逐行解释代码。

题目分析

给定一个升序排列的整数数组 nums 和一个目标值 target,我们需要找到目标值 target 在数组中首次和最后一次出现的位置。如果数组中没有目标值,则返回 [-1, -1]

解法思路

我们可以使用二分查找来加速搜索过程,利用排序数组的性质找到目标值的第一个和最后一个位置。

具体的思路如下:

  1. 使用二分查找找到目标值的位置。
  2. 找到目标值后,通过向左扩展和向右扩展的方式来确定目标值的最左和最右位置。
  3. 如果找不到目标值,返回 [-1, -1]

代码实现

代码解读

#include <stdio.h>
#include <stdlib.h>

/**
 * searchRange 函数用于在已排序的数组中找到目标值的起始和结束位置。
 * 如果目标值不存在,则返回 [-1, -1]。
 * 
 * @param nums: 排序后的整数数组。
 * @param numsSize: 数组的大小。
 * @param target: 要查找的目标值。
 * @param returnSize: 返回数组的大小,固定为2,表示包含目标值的范围。
 * @return: 一个包含目标值范围的数组,范围为 [left, right],如果目标值不存在返回 [-1, -1]。
 */
int* searchRange(int* nums, int numsSize, int target, int* returnSize) {
    // 设置返回数组的大小为2,表示结果为目标值的起始和结束位置
    *returnSize = 2;

    // 动态分配结果数组,用于存储目标值的起始和结束位置
    int* result = (int*)malloc(sizeof(int) * 2);
    
    // 检查内存分配是否成功
    if (result == NULL) {
        *returnSize = 0;  // 如果内存分配失败,返回0大小的数组
        return NULL;
    }

    // 初始化结果数组,默认值为 [-1, -1]
    result[0] = -1;
    result[1] = -1;

    // 如果数组为空或目标值不在数组的范围内,直接返回 [-1, -1]
    if (numsSize == 0 || nums[0] > target || nums[numsSize - 1] < target) {
        return result;
    }

    int left = 0;            // 左指针
    int right = numsSize - 1;  // 右指针
    int middle = 0;          // 中间指针

    // 二分查找目标值的位置
    while (left <= right) {
        middle = left + (right - left) / 2;  // 计算中间位置,避免溢出
        if (nums[middle] == target) {  // 找到目标值
            // 找到目标值后,向左和向右扩展,找到最左和最右的目标值
            int m_left = middle;
            int m_right = middle;

            // 向右扩展,直到不再等于目标值
            while ((m_right + 1) < numsSize && nums[m_right + 1] == target) {
                m_right += 1;
            }

            // 向左扩展,直到不再等于目标值
            while ((m_left - 1) >= 0 && nums[m_left - 1] == target) {
                m_left -= 1;
            }

            // 设置结果数组,返回最左和最右位置
            result[0] = m_left;
            result[1] = m_right;
            return result;
        }

        // 根据中间值与目标值的大小关系调整左右指针
        if (nums[middle] > target) {
            right = middle - 1;  // 如果目标值小于中间值,右指针左移
        } else {
            left = middle + 1;  // 如果目标值大于中间值,左指针右移
        }
    }

    // 如果没有找到目标值,返回 [-1, -1]
    return result;
}

int main() {
    // 示例数组和目标值
    int nums[] = {5, 7, 7, 8, 8, 10};
    int target = 8;
    int returnSize;
    


    // 调用 searchRange 函数
    int* result = searchRange(nums, sizeof(nums) / sizeof(nums[0]), target, &returnSize);

    // 输出结果
    if (result != NULL) {
        printf("Range: [%d, %d]\n", result[0], result[1]);
        free(result);  // 记得释放动态分配的内存
    } else {
        printf("Target not found.\n");
    }

    return 0;
}

代码分析

  1. 初始化和内存分配:我们首先动态分配了一个 result 数组,用于存储目标值的最左和最右位置。若内存分配失败,我们将 returnSize 设置为 0 并返回 NULL

  2. 边界检查:在开始二分查找之前,我们进行了边界检查。如果目标值不可能出现在数组中(如目标值小于数组中的最小值或大于数组中的最大值),我们直接返回 [-1, -1]

  3. 二分查找:我们通过 while 循环进行二分查找,在找到目标值后,进一步扩展搜索范围,找到目标值的最左和最右位置。

  4. 结果输出:最后,我们通过 printf 输出目标值的范围。如果目标值不存在,我们输出 “Target not found”。

时间复杂度分析

  • 二分查找 的时间复杂度是 O(log n),在最坏情况下,我们只需要进行一次二分查找。
  • 扩展查找最左和最右位置的过程是线性的 O(n),但这仅在找到目标值后进行,所以整体时间复杂度仍然是 O(n)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/950691.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek-V3 通俗详解:从诞生到优势,以及与 GPT-4o 的对比

1. DeepSeek 的前世今生 1.1 什么是 DeepSeek&#xff1f; DeepSeek 是一家专注于人工智能技术研发的公司&#xff0c;致力于打造高性能、低成本的 AI 模型。它的目标是让 AI 技术更加普惠&#xff0c;让更多人能够用上强大的 AI 工具。 1.2 DeepSeek-V3 的诞生 DeepSeek-V…

linux之自动挂载

如果想要实现自动挂载&#xff0c;应该挂在客户端&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 客户端&#xff1a; [rootlocalhost ~]# yum install nfs-utils -y &#xff08;下载软件&#xff09; [rootlocalhost ~]# systemctl start nfs-utils.servic…

RHCSA知识点汇总

第0章&#xff1a;Linux基础入门 0.1 什么是计算机 计算机的组成&#xff1a; 控制器&#xff1a;是整个计算机的中枢神经&#xff0c;根据程序要求进行控制&#xff0c;协调计算机各部分工作及内存与外设的访问等。 输入设备&#xff1a;将文字、数据、程序和控制命令等信…

交响曲-24-3-单细胞CNV分析及聚类

CNV概述 小于1kb是常见的插入、移位、缺失等的变异 人体内包含<10% 的正常CNV&#xff0c;我们的染色体数是两倍体&#xff0c;正常情况下&#xff0c;只有一条染色体表达&#xff0c;另一条沉默&#xff0c;当表达的那条染色体发生CNV之后&#xff0c;表达数量就会成倍增加…

【Linux-多线程】POSIX信号量-基于环形队列生产消费模型

POSIX信号量 POSIX信号量和System V信号量作用相同&#xff0c;都是用于同步操作&#xff0c;达到无冲突的访问共享资源的目的。但POSIX可以用于线程间同步 1.快速认识信号量接口 POSIX信号量分为两种类型&#xff1a; 命名信号量&#xff08;Named Semaphores&#xff09;&…

Linux下文件操作相关接口

文章目录 一 文件是什么普通数据文件 二 文件是谁打开的进程用户 三 进程打开文件的相关的接口c语言标准库相关文件接口1. fopen 函数2. fread 函数3. fwrite 函数4. fclose 函数5. fseek 函数 linux系统调用接口1. open 系统调用2. creat 系统调用3. read 系统调用4. write 系…

UE蓝图节点备忘录

获取索引为0的玩家 获取视图缩放 反投影屏幕到世界 获取屏幕上的鼠标位置 对指定的物体类型进行射线检测 判断物体是否有实现某个接口 上面节点的完整应用 通过PlayerControlle获取相机相关数据 从相机处发射射线撞击物体从而获取物体信息 抽屉推拉功能 节点说明 ##门的旋转开关…

玩机搞机基本常识-------列举安卓机型一些不常用的adb联机命令

前面分享过很多 常用的adb命令&#xff0c;今天分享一些不经常使用的adb指令。以作备用 1---查看当前手机所有app包名 adb shell pm list package 2--查看当前机型所有apk包安装位置 adb shell pm list package -f 3--- 清除指定应用程序数据【例如清除浏览器应用的数据】 …

LeetCode【剑指offer】系列(字符串篇)

剑指offer05.替换空格 题目链接 题目&#xff1a;假定一段路径记作字符串path&#xff0c;其中以 “.” 作为分隔符。现需将路径加密&#xff0c;加密方法为将path中的分隔符替换为空格" "&#xff0c;请返回加密后的字符串。 思路&#xff1a;遍历即可。 通过代…

idea java.lang.OutOfMemoryError: GC overhead limit exceeded

Idea build项目直接报错 java: GC overhead limit exceeded java.lang.OutOfMemoryError: GC overhead limit exceeded 设置 编译器 原先heap size 设置的是 700M , 改成 2048M即可

aws(学习笔记第二十二课) 复杂的lambda应用程序(python zip打包)

aws(学习笔记第二十二课) 开发复杂的lambda应用程序(python的zip包) 学习内容&#xff1a; 练习使用CloudShell开发复杂lambda应用程序(python) 1. 练习使用CloudShell CloudShell使用背景 复杂的python的lambda程序会有许多依赖的包&#xff0c;如果不提前准备好这些python的…

conda 批量安装requirements.txt文件

conda 批量安装requirements.txt文件中包含的组件依赖 conda install --yes --file requirements.txt #这种执行方式&#xff0c;一遇到安装不上就整体停止不会继续下面的包安装。 下面这条命令能解决上面出现的不执行后续包的问题&#xff0c;需要在CMD窗口执行&#xff1a; 点…

如何操作github,gitee,gitcode三个git平台建立镜像仓库机制,这样便于维护项目只需要维护一个平台仓库地址的即可-优雅草央千澈

如何操作github&#xff0c;gitee&#xff0c;gitcode三个git平台建立镜像仓库机制&#xff0c;这样便于维护项目只需要维护一个平台仓库地址的即可-优雅草央千澈 问题背景 由于我司最早期19年使用的是gitee&#xff0c;因此大部分仓库都在gitee有几百个库的代码&#xff0c;…

SpringBootWeb 登录认证(day12)

登录功能 基本信息 请求参数 参数格式&#xff1a;application/json 请求数据样例&#xff1a; 响应数据 参数格式&#xff1a;application/json 响应数据样例&#xff1a; Slf4j RestController public class LoginController {Autowiredpriva…

nginx http反向代理

系统&#xff1a;Ubuntu_24.0.4 1、安装nginx sudo apt-get update sudo apt-get install nginx sudo systemctl start nginx 2、配置nginx.conf文件 /etc/nginx/nginx.conf&#xff0c;但可以在 /etc/nginx/sites-available/ 目录下创建一个新的配置文件&#xff0c;并在…

【25考研】川大计算机复试情况,重点是啥?怎么准备?

24年进入复试的同学中&#xff0c;有10位同学的复试成绩为0分。具体是个人原因还是校方原因&#xff0c;还尚不明确。但是C哥提醒&#xff0c;一定要认真复习&#xff01;复试完后不要跟任何人讨论有关复试的题目及细节&#xff01; 一、复试内容 四川大学复试内容较多&#xf…

React Native 项目 Error: EMFILE: too many open files, watch

硬件&#xff1a;MacBook Pro (Retina, 13-inch, Mid 2014) OS版本&#xff1a;MacOS BigSur 11.7.10 (20G1427) 更新: 删除modules的方法会有反弹&#xff0c;最后还是手动安装了预编译版本的watchman。 React Native 项目运行npm run web&#xff0c;出现如下错误&#xff1a…

YOLO11改进算法 | 引入SimAM模块的YOLO11-pose关键点姿态估计

目录 网络结构 测试结果 算法改进 局部和全局特征的兼顾 提升模型精度 提高计算效率 增强模型鲁棒性 模型指标 数据集介绍 Coovally AI模型训练与应用平台 YOLO11是由Ultralytics团队于2024年9月30日发布的&#xff0c;它是YOLO&#xff08;You Only Look Once&#…

运放输入偏置电流详解

1 输入阻抗与输入偏置电路关系 在选择运放和仪表运放时&#xff0c;经常听到这样的说法&#xff1a;“需要非常高的输入阻抗”&#xff0c;事实上真实如此吗&#xff1f; 输入阻抗&#xff08;更确切的说是输入电阻&#xff09;很少会成为一个重要的问题&#xff08;输入电容也…

HTML基础入门——简单网页页面

目录 一&#xff0c;网上转账电子账单 ​编辑 1&#xff0c;所利用到的标签 2&#xff0c;代码编写 3&#xff0c;运行结果 二&#xff0c;李白诗词 1&#xff0c;所用到的标签 2&#xff0c;照片的编辑 3&#xff0c;代码编写 4&#xff0c;运行结果 一&#xff0c;网…