【牛客-算法】 NC48 在旋转过的有序数组中寻找目标值

news/2024/5/17 0:57:36/文章来源:https://blog.csdn.net/m0_63238256/article/details/127144245

文章目录

  • 🚩 前言
  • 1.题目描述
  • 2.算法设计思路
  • 3.算法实现
    • bug记录
    • 🧭 遇到问题(可跳过)
    • 🌻 写在前面
    • 我最初的通过代码(C语言)
  • 4.运行结果
  • 5.小结

🔥 该专栏作为算法题笔记,记录算法的思路、遇到的问题,以及能跑的代码,持续更新中!

推荐一款面试、刷题神器牛客网:👉开始刷题学习👈


🚩 前言

本文记录的是一个过程,若想快速获得解题思路,可直接从目录跳到这一部分:🌻 写在前面

1.题目描述

描述
有一个长度为 n 的按严格升序排列的整数数组 nums ,在实行 search 函数之前,在某个下标 k 上进行旋转,使数组变为
[nums[k],nums[k+1],.....,nums[nums.length−1],nums[0],nums[1],.......,nums[k−1]][nums[k],nums[k+1],.....,nums[nums.length-1],nums[0],nums[1],.......,nums[k-1]][nums[k],nums[k+1],.....,nums[nums.length1],nums[0],nums[1],.......,nums[k1]]
给定旋转后的数组 nums 和一个整型 target ,请你查找 target 是否存在于 nums 数组中并返回其下标(从0开始计数),如果不存在请返回-1。

数据范围0≤n≤10000,0≤target≤1000000 \le n \le 10000,0 \le target \le 1000000n10000,0target100000
要求:空间复杂度 O(1)O(1)O(1) ,时间复杂度 O(n)O(n)O(n)
例子,数组 [0,2,4,6,8,10][0,2,4,6,8,10][0,2,4,6,8,10] 在下标3处旋转之后变为 [6,8,10,0,2,4][6,8,10,0,2,4][6,8,10,0,2,4] , 当给定target为10时,10的下标是2,target为3时,nums数组中不存在3,所以返回-1

2.算法设计思路

前面铺垫那么多干嘛呢?我要做的不就是在数组中遍历搜索一个整数吗?

C代码:一次遍历,

int search(int* nums, int numsLen, int target ) {// write code herefor(int i = 0; i < numsLen; i++){if(nums[i] == target){return i;}}return -1;
}

后面仔细看了题目和别人的讨论才发现,有一个重要的条件是数组在旋转之前是严格升序的。所有题目的意思是,为了将时间复杂度从 O(n)O(n)O(n) 减小为 O(log(n))O(log(n))O(log(n)) O(log(n))\Omicron(log(n))O(log(n)),可以采用二分的办法。那么问题来了,在旋转之后,数组就不是严格有序了,要怎么二分呢?

旋转前的数组(左)和旋转后的数组(右) :

旋转前的数组(左)和旋转后的数组(右)

我们仍然取数组的中点 mid,将数组划分为 (left, mid-1) 和 (mid+1, right) 两部分,而其中一定有一个区间是完全有序的(可通过比较端点值来判断)。所以,我们可以将区间分为左、右两个部分分别进行搜索

(注:下面的 搜索 字眼,若无特别说明,则是指对 不完全有序区间 的搜索)

算法过程:

  • 如果搜索的区间有序
    • 判断 target 是否在该区间中(通过比较端点值)
    • 若在,则对该区间进行完全有序情况下的二分搜索即可(不再赘述)
    • 若不在,则放弃该区间,搜索另一半无序的区间
  • 若搜索的区间不完全有序
    • 再次将该区间划分分为左、右两个部分进行搜索

3.算法实现

bug记录

报错solution.c:94:13: warning: implicit declaration of function 'serchSorted' is invalid in C99 [-Wimplicit-function-declaration]
翻译过来就是:解决方案.c:94:13: 警告:函数“serch排序”的隐式声明在 C99 中无效 [-微缩-函数-声明]

一看到C99,我还以为是版本的问题,结果实际是代码中拼写错误导致的。我把searchSorted写成了serchSorted,掉了个字母 a。

🧭 遇到问题(可跳过)

对一个有序的区间二分的时候,我们要严格的判断目标值 target 在不在区间里,就要用 target 与区间的两个端点都进行比较。而进行过比较的端点,就可以排除出我们接下来要搜索的区间(如果值相等,那就直接找到目标了)。

或者,我们也可以只与区间的中间点这一个端点比较,判断 target 是在区间的哪一边。

哪种方式更好呢?

🌻 写在前面

下面的代码显得很长,因为我将搜索有序区间搜索非有序区间作为两个函数分开来写了。

其实我更推荐你看这篇题解中的 C++ 代码二十来行解决问题:NC48 在旋转过的有序数组中寻找目标值。

总结一下他的思路:(采用迭代写法,主要是将有序和无序的情况统一起来了)

  1. 将区间划分为左、右两部分小区间
  2. 找到有序的区间
  3. 若该有序区间包含 target:将该区间设为新的目标区间
    若不包含 target:将另一半区间设为新的搜索区间
  4. 直到找到 target,或区间为空,停止搜索

我最初的通过代码(C语言)

int searchNo(int* nums, int left, int right, int target);
int searchSorted(int *nums, int left, int right, int target);//调用者函数
int search(int* nums, int numsLen, int target ) {// write code hereint mid = numsLen / 2;int x = -1;//注意不是初始化为 0x = searchNo(nums, 0, numsLen-1, target);return x;
}//搜索不完全有序的区间
int searchNo(int* nums, int left, int right, int target){int mid = (left + right) / 2;int x1 = -1, x2 = -1;if(left > right){return -1;}if(nums[mid] == target){return mid;}if(nums[mid] > nums[0])//说明左区间有序,否则右区间有序{//将target与区间两个端点,而不仅仅是mid进行比较,这有利于判断是否放弃一个区间if(nums[0] <= target && target <= nums[mid]) //nums[mid-1]是否可能非法内存访问?{x1 = searchSorted(nums, 0, mid-1, target);}else{x2 = searchNo(nums, mid+1, right, target);}}else//右区间有序{if(nums[mid] <= target && target <= nums[right]){x2 = searchSorted(nums, mid+1, right, target);}else{x1 = searchNo(nums, 0, mid-1, target);}}if(x1 != -1){return x1;}return x2;
}//搜索有序区间
int searchSorted(int *nums, int left, int right, int target){int mid = (left + right) / 2;int x = -1;if(left > right){return -1;}if(nums[mid] == target){return mid;}if(target < nums[mid]){x = searchSorted(nums, left, mid-1, target);}else if(nums[mid] < target){x = searchSorted(nums, mid+1, right, target);}return x;//x是不是-1都可以return
}

4.运行结果

成功通过!

在这里插入图片描述

5.小结

感觉在编码之前,仅仅规划大致的算法步骤还不够。也许我还需要一个中间的层次,像伪代码那样,即可以仔细考虑算法过程中的细节,又不必理会太多具体有关编程语言的细节

今天的分享就到这里啦,快来一起刷题叭!
👉开始刷题学习👈


CSDN话题挑战赛第2期
参赛话题:学习笔记

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

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

相关文章

Bert在fine-tune训练时的技巧:①冻结部分层参数、②weight-decay (L2正则化)、③warmup_proportion、④

作为一个NLPer&#xff0c;bert应该是会经常用到的一个模型了。但bert可调参数很多&#xff0c;一些技巧也很多&#xff0c;比如加上weight-decay, layer初始化、冻结参数、只优化部分层参数等等&#xff0c;方法太多了&#xff0c;每次都会纠结该怎么样去finetune&#xff0c;…

打印数组的所有子集

打印数组的所有子集 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;打印数组的所有子集 CSDN&#xff1a;打印数组的所有子集 无重复值情况 题目描述见: LeetCode 78. Subsets 主要思路 定义递归函数 void p(int[] arr, int i, LinkedList<Integer…

【数据结构与算法】深度理解队列(上)

✨hello&#xff0c;进来的小伙伴们&#xff0c;你们好耶&#xff01;✨ &#x1f68e;&#x1f68e;系列专栏&#xff1a;【数据结构与算法】 &#x1f680;&#x1f680;本篇内容:队列从0到1的学习&#xff01; ⛵⛵作者简介&#xff1a;一名双非本科大三在读的科班Java编程小…

11-二叉树-删除

delete(ElementType e)&#xff1a;删除某个值为 e 的结点。实现方法有多种。 按添加结点的规则&#xff0c;小于根结点的放在左边&#xff0c;大于等于根结点的放在右边。b 小于 c 中任意一个子结点&#xff0c;只能放在 c 中最小的一个结点 e 的左子结点下。 除 e 外&#x…

Git基础操作

拉取代码直接clone,复制远程仓库文件夹 git clone git@gitee.com:chen-LinQiang/my-notes.git 在已有仓库文件夹中拉代码 # 初始化 git init # 关联远程仓库 git remote add origin git@gitee.com:chen-LinQiang/my-notes.git # 切换到本地主分支 git checkout master # 若报错…

SpringBoot员工管理的项目——SpringBoot首页定制的操作和国际编码操作(课时十五)

SpringBoot员工管理的项目——SpringBoot后台数据库的搭建(课时十四)_星辰镜的博客-CSDN博客 上篇文章的的文章路径 读者可以回看 有些内容在这里不在说明 本博文完成的两个功能: 利用 Thymeleaf模板引擎完成员工管理系统的的首页定制 国际化编码格式操作 <!--Thymeleaf 说…

计算机网络——媒体接入控制

&#x1f49f;&#x1f49f;前言 ​ 友友们大家好&#xff0c;我是你们的小王同学&#x1f617;&#x1f617; 今天给大家打来的是 计算机网络——媒体接入控制 希望能给大家带来有用的知识 觉得小王写的不错的话麻烦动动小手 点赞&#x1f44d; 收藏⭐ 评论&#x1f4c4; 小王…

20、DQL(编写顺序和执行顺序)

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 DQL&#xff08;编写顺序和执行顺序&#xff09; 执行顺序&#xff1a; 1、from&#xff08;from 查什么表是第一&#xff09; 2、where 3、group by 和 having 4、select 5、order by&#xff08;你很与众不同哈&…

Promise 及其基于 Typescript 的实现

Promise 的概念、用法与实现作者&#xff1a; jcLee95 邮箱 &#xff1a;291148484163.com CSDN 主页&#xff1a;https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/121506948 相关文章&…

APP攻防

信息收集 APP-外在抓包-Fd&茶杯&BurpAPP-外在封包-封包监听工具APP-内在提取-AppInfoScannerAPP-内在搜索-反编译载入IDEAAPP-资源提取-安装包&资源文件APP-框架使用-Xposed&JustTrustMe fiddler 1、安装证书 然后设置-WLAN-高级设置-安装证书-安装FidderRo…

【C语言】字符+字符串函数精讲

前言 ● 从我们第一个C程序——Hello world 的诞生&#xff0c;到字符串的拷贝、比较等各种操作的实现。从中不难发现&#xff1a;我们在处理C语言时对字符和字符串的处理很是频繁&#xff0c;因此学习字符及字符串的各种操作函数尤显其必要性。 ● C语言本身是没有字符串类型的…

SpringBoot项目中计量单位与进制转换问题解决措施及数据校验怎么操作

写在前面&#xff1a; 继续记录自己的SpringBoot学习之旅&#xff0c;这次是SpringBoot应用相关知识学习记录。若看不懂则建议先看前几篇博客&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 3.2 配置高级 3.2.1 ConfigurationProperties注解 …

【小程序从0到1】小程序条件渲染|列表渲染

欢迎来到我的博客 &#x1f4d4;博主是一名大学在读本科生&#xff0c;主要学习方向是前端。 &#x1f36d;目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏 &#x1f6e0;目前正在学习的是&#x1f525;React/小程序React/小程序React/小程序&am…

【mysql】performance_schema初识

1、linux下一些mysql常用的命令 打开mysqld服务 systemctl start mysqld关闭mysqld服务 systemctl stop mysqld查看 mysqld状态 service mysqld status修改MySQL的配置文件 vim /etc/my.cnf2、什么是performance_schema performance_schema是运行在较低级别的用于监控mys…

最小 XOR leetcode第 313 场周赛 第三题

给你两个正整数 num1 和 num2 &#xff0c;找出满足下述条件的整数 x &#xff1a; x 的置位数和 num2 相同&#xff0c;且 x XOR num1 的值 最小 注意 XOR 是按位异或运算。 返回整数 x 。题目保证&#xff0c;对于生成的测试用例&#xff0c; x 是 唯一确定 的。 整数…

用同一个GroovyClassLoader加载的Class真的无法回收吗

源码地址&#xff1a;https://gitee.com/mr_wenpan/basis-enhance/tree/master/enhance-boot-groovy-engine 一、问题描述 最近需要使用到groovy&#xff0c;于是进行了一番调研&#xff0c;看到网上有个很常见的说法&#xff0c;如下&#xff1a; 如果一个项目里使用同一个G…

matlab与python编程对照

格式 n. 功能 Matlab编程 Matlab输出 Python编程 Python输出 ——————————————————————————————————— 1. for 循环 Matlab编程 for i 1:3i end Matlab输出 Python编程 for i in range (1,4):print(i) Python输出 —————…

LSS-lift splat shoot论文与代码解读

目录序言论文代码总结序言 最近开始学习多摄融合领域了&#xff0c;定义是输入为多个摄像机图像&#xff0c;获得多个视角的相机图像特征&#xff0c;通过相机内外参数进行特征映射到BEV视角&#xff0c;得到360的视觉感知结果&#xff0c;今天分享的是经典论文LSS。 论文 论…

python算法面试题(一)

1、给定一个包含红色、白色和蓝色、共n 个元素的数组nums&#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、1 和 2 分别表示红色、白色和蓝色&#xff1b;必须在不使用库的sort函数的情况下解决…

二十五、C预处理器

文章目录一、定义1.1 C预处理器1.2 预定义宏1.3 预处理器运算符1.3.1 宏延续运算符 \1.3.2 字符串常量化运算符 (#)1.3.3 标记粘贴运算符 (##)1.4 参数化的宏一、定义 1.1 C预处理器 预处理器必须以#开头&#xff0c;其本质上是一个文本替换工具&#xff0c;有如下指令&#…