当前位置: 首页 > news >正文

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

力扣第34题:在排序数组中查找元素的第一个和最后一个位置(C语言解法)

题目描述

在一个升序排列的整数数组 nums 中,找到指定元素 target第一个和最后一个位置。如果数组中不存在目标值 target,则返回 [-1, -1]

示例 1

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

要求:时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

解题思路

由于数组是升序排列的,因此可以使用二分查找来快速找到 target。具体思路如下:

  1. 查找第一个位置:通过二分查找找到 target第一个出现位置,即最左边的 target
  2. 查找最后一个位置:同样使用二分查找找到 target最后一个出现位置,即最右边的 target

这样两次二分查找就可以得到 target 的起始和结束位置。因为二分查找的时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn),所以整体复杂度也是 O ( log ⁡ n ) O(\log n) O(logn)

代码实现

下面是具体的 C 语言实现。

#include <stdio.h>
#include <stdlib.h>// 查找target的第一个位置
int findFirst(int* nums, int numsSize, int target) {int left = 0, right = numsSize - 1;int first = -1;  // 初始化为-1,表示未找到while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] == target) {first = mid;       // 找到target,记录位置right = mid - 1;   // 向左缩小范围} else if (nums[mid] < target) {left = mid + 1;    // target在右侧} else {right = mid - 1;   // target在左侧}}return first;
}// 查找target的最后一个位置
int findLast(int* nums, int numsSize, int target) {int left = 0, right = numsSize - 1;int last = -1;  // 初始化为-1,表示未找到while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] == target) {last = mid;        // 找到target,记录位置left = mid + 1;    // 向右缩小范围} else if (nums[mid] < target) {left = mid + 1;    // target在右侧} else {right = mid - 1;   // target在左侧}}return last;
}// 主函数,返回target的起始和结束位置
int* searchRange(int* nums, int numsSize, int target, int* returnSize) {int* result = (int*)malloc(2 * sizeof(int));  // 分配返回结果的内存result[0] = findFirst(nums, numsSize, target);result[1] = findLast(nums, numsSize, target);*returnSize = 2;return result;
}int main() {int nums[] = {5, 7, 7, 8, 8, 10};int target = 8;int returnSize;int* result = searchRange(nums, 6, target, &returnSize);printf("[%d, %d]\n", result[0], result[1]);  // 输出结果free(result);  // 释放内存return 0;
}

代码解析

函数 findFirst

findFirst 函数的作用是查找 target 的第一个位置,使用二分查找实现。

  1. 初始化 leftright 为数组的左右边界。
  2. 进入 while 循环,直到 left > right
  3. 计算 mid,这是当前的中间位置。
  4. 如果 nums[mid] == target
    • 记录 first = mid,表示找到了 target
    • right 设置为 mid - 1,继续向左查找,确保找到最左边的 target
  5. 如果 nums[mid] < target,说明 target 在右侧,将 left 更新为 mid + 1
  6. 如果 nums[mid] > target,说明 target 在左侧,将 right 更新为 mid - 1
  7. 最后返回 first,如果未找到 target 则返回 -1
函数 findLast

findLast 函数的作用是查找 target 的最后一个位置,基本逻辑与 findFirst 类似:

  1. 如果 nums[mid] == target,记录 last = mid,并将 left 设置为 mid + 1,继续向右查找。
  2. 其他步骤与 findFirst 类似,最后返回 last
主函数 searchRange

searchRange 使用 findFirstfindLast 得到 target 的起始和结束位置:

  1. 动态分配 result 数组来存储结果,并调用 findFirstfindLast
  2. returnSize 设置为 2,表示结果包含两个值。
  3. 返回 result 数组。

时间复杂度

两个二分查找的时间复杂度都是 O ( log ⁡ n ) O(\log n) O(logn),因此整体时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn),符合题目要求。


http://www.mrgr.cn/news/64456.html

相关文章:

  • Python酷库之旅-第三方库Pandas(192)
  • word mathml 创建粗体字母快捷键
  • 深度学习与时间序列预测的关系
  • 速盾:sdk盾有什么用?
  • 目录的简介和rest api规范
  • ProLightsfx新的出发–从CSDN到WordPress
  • Python酷库之旅-第三方库Pandas(190)
  • 纯前端生成PDF(jsPDF)并下载保存或上传到OSS
  • CSS中的 BFC,是啥呀?
  • 无源元器件-磁珠选型参数总结
  • 32单片机HAL库的引脚初始化
  • C语言第11节:指针(1)
  • 05 Django 框架模型介绍(一)
  • 虚拟机安装Ubuntu系统
  • 网络请求优化:理论与实践
  • 【Python项目管理】“无法创建虚拟环境”报错原因及解决方法
  • JZ2440开发板——LCD
  • 什么是软件测试?软件测试的流程?软件测试未来3-5年的职业规划?
  • 【AD】1-2 AD24软件的中英文版本切换
  • Python数据分析案例62——基于MAGU-LSTM的时间序列预测(记忆增强门控单元)
  • 不同网线类型
  • 数据库->联合查询
  • Ubuntu使用Qt虚拟键盘,支持中英文切换
  • 网鼎杯-re2-好久不见5
  • C语言 ——— 学习和使用 strstr 函数,并模拟实现
  • [Redis] Redis事务