旋转数组的最小数字
CCF考试试题自己学习的代码整理

if(length==1){
return rotateArray[0];
}
int min=rotateArray[0];
//int length=rotateArray.size();
for(int i=1;i<length;i++){
if(rotateArray[i]<min){
min=rotateArray[i];
}
}
return min;
}
第三种方法:
vector<int> dev;
if(head!=nullptr){
if(head->next!=nullptr){
dev=printListFromTailToHead(head->next);
}
6.C语言里面没有string类型,都是使用char数组存储
C++ 里面具有string类
7.scanf("%s %s",str1,str2);不能使用&str1,&str2!!!.因为数组首地址就是取地址
8.将字符转换成数字****应该是sum+=(str[i]-'0')*(str[j]-'0');
if(str[i]!=' '){
str[i+2*count]=str[i];
}
else{
count--;
str[i+2*count]='%';
F1=F2;
F2=F3;
}
return F3;
数组反转方法

数组反转方法在编程中,数组是一种重要的数据结构,它允许我们存储和处理大量相似类型的数据。
数组中的元素按照特定的顺序存储,并且可以通过索引访问。
有时候我们需要对数组中的元素进行反转操作,即将原来的顺序颠倒过来。
本文将介绍一些常见的数组反转方法,帮助您在实际编程中灵活运用。
一、内置方法实现数组反转在许多编程语言中,提供了内置的方法来实现数组的反转操作。
下面是一些常见语言的例子:1. Python语言:在Python中,可以使用[::-1]的方式对数组进行反转。
例如,有一个名为arr的数组,可以通过arr[::-1]来实现数组元素的反转。
2. JavaScript语言:在JavaScript中,可以使用Array对象的reverse()方法对数组进行反转。
例如,有一个名为arr的数组,可以通过arr.reverse()来实现数组元素的反转。
这些内置方法是实现数组反转的最简单、快速的方法之一。
然而,有时候我们可能需要自己编写算法来完成数组反转,下面将介绍其他实现方法。
二、循环交换法实现数组反转另一种常见的数组反转方法是循环交换法。
该方法使用两个指针分别指向数组的首尾元素,然后交换它们的值,并依次向中间移动。
具体步骤如下:1. 初始化两个指针,一个指向数组的首元素,记为left,另一个指向数组的尾元素,记为right。
2. 当left小于right时,交换left和right位置上的元素,并将left指针右移一位,将right 指针左移一位。
3. 重复步骤2,直到left大于或等于right为止。
下面是一个使用循环交换法实现数组反转的示例代码(以Java语言为例):```javavoid reverseArray(int[] arr) {int left = 0;int right = arr.length - 1;while (left < right) {int temp = arr[left];arr[left] = arr[right];arr[right] = temp;left++;right--;三、递归实现数组反转除了循环交换法,我们还可以使用递归的方式实现数组反转。
Python高频算法题100例-2019最新

Python高频算法题100例(2019)1.二维数组中的查找题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数2.替换空格题目:请实现一个函数,将一个字符串中的空格替换成“%20”。
例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
3.从尾到头打印链表题目:输入一个链表,从尾到头打印链表每个节点的值。
4.重建二叉树题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
5.两个栈实现队列题目:用两个栈来实现一个队列,完成队列的Push和Pop操作。
队列中的元素为int类型。
6.旋转数组的最小数字题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回07.斐波那契数列题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n 项。
8.跳台阶题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级。
求该青蛙跳上一个n级的台阶总共有多少种跳法。
9.变态跳台阶题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。
求该青蛙跳上一个n级的台阶总共有多少种跳法。
10.矩形覆盖题目:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?11.二进制中1的个数题目:输入一个整数,输出该数二进制表示中1的个数。
2021江苏省信息与未来小学生夏令营编程活动试题

样例输出 1203样例输⼊ 2900 4096样例输出 2389数据规模对于 40% 的数据,。
对于 100% 的数据,。
p2. 摩尔斯电码 (15 pts)早期的电报机只能表达两种状态:电路导通和电路断开。
电路导通时喇叭可以发声;断开时则不发声。
如何⽤这样的机器来传递⼈类能理解的信号呢?聪明的你⼀定想到了——时间的长短可以表达不同的含义(例如长代表 1、短代表 0),然后再把 “01” 的⼆进制序列对应到字符就可以啦。
摩尔斯电码就是这样⼀种早期的数字通信协议,它通过喇叭发声长短来表⽰不同的英⽂字母:1. 点(半⾓点号.),喇叭响 1 单位时间,读作 “滴” dit;2. 划(半⾓减号-),喇叭响 3 单位时间,读作 “嗒” dah;3. 字符/单词间的停顿,字符停顿 3 单位时间,单词停顿 7 单位时间。
下图列出了摩尔斯电码和英⽂字母之间的对应:例如,⼤家可以试试把 “... --- ...” 对照上⾯的表格翻译成英⽂(空格代表字符的分割)。
没错,这就是著名的 “SOS” 紧急求救信号。
现在,你需要写⼀个程序把收到的摩尔斯电码翻译回英⽂字符。
输⼊格式输⼊数据的第⼀⾏是⼀个整数 ,代表共有 个需要解码的英⽂字母。
输⼊数据的第⼆⾏包含 个摩尔斯电码点/划组成的字符串(字符串之间⽤⼀个空格隔开),每个字符串仅包含若⼲半⾓减号 “-” 和半⾓点号 “.”,且保证能翻译为 26 个英⽂字母中的⼀个。
输出格式输出⼀⾏,为摩尔斯电码解码后得到的字符串。
样例输⼊ 1样例输出 1样例输⼊ 23... --- ...SOS35- .... . --.- ..- .. -.-. -.- -... .-. --- .-- -. ..-. --- -..- .--- ..- -- .--. ... --- ...- . .-. - .... . .-.. .- --.. -.-- -.. --- --.样例输出 2THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG解释:“The quick brown fox jumps over the lazy dog” 是⼀个经典的包含了所有 26 个字母的句⼦。
python必刷100题

python必刷100题以下是Python必刷的100道题目,根据不同的水平和兴趣,可以选择适合自己的题目进行练习。
1. 两数之和2. 两数之和 II - 输入有序数组3. 回文数4. 反转整数5. 字符串中的第一个唯一字符6. 合并两个有序链表7. 合并两个有序数组8. 盛最多水的容器9. 三数之和10. 删除排序数组中的重复项11. 最长回文子串12. 最长公共前缀13. 两个数组的交集14. 有效的括号15. 实现strStr()16. 合并K个排序链表17. Pow(x, n)18. 括号生成19. 合并区间20. 合并两个二叉树21. 买卖股票的最佳时机22. 缺失的第一个正数23. 二叉树的最大深度24. 对称二叉树25. 二叉树的层次遍历26. 外观数列27. 单词搜索28. 电话号码的字母组合29. 子集30. 二叉树的前序遍历31. 删除链表中的节点32. 有效的字母异位词33. 二叉树的锯齿形层次遍历34. 路径总和35. 跳跃游戏36. 最小栈37. 单词接龙38. 无重复字符的最长子串39. 相交链表40. 乘积最大子序列41. 格雷编码42. 旋转图像43. 螺旋矩阵44. 二叉搜索树中的搜索45. 字符串相乘46. 矩阵置零47. 下一个排列48. 最大子序和49. 三个数的最大乘积50. 最长连续递增序列51. 缺失的数字52. 跳跃游戏 II53. 矩阵中的最长递增路径54. 合并两个有序链表55. 删除链表的倒数第N个节点56. 最小路径和57. 旋转链表58. 接雨水59. 螺旋矩阵 II60. 跳跃游戏 III61. 移除元素62. 买卖股票的最佳时机 II63. 买卖股票的最佳时机 III64. 除自身以外数组的乘积65. 输出二叉树的右视图66. 反转链表67. 翻转字符串里的单词68. 颜色分类69. 数组中的第K个最大元素70. 验证二叉搜索树71. 在排序数组中查找元素的第一个和最后一个位置72. 寻找旋转排序数组中的最小值73. 最大矩形74. 将有序数组转换为二叉搜索树75. 路径总和 II76. 不同路径77. 组合78. 排列79. 子集 II80. 字符串转换整数(atoi)81. 删除排序链表中的重复元素82. 删除排序链表中的重复元素 II83. 分数到小数84. 复原IP地址85. 最接近的三数之和86. 验证回文串87. 寻找重复数88. 圆圈中最后剩下的数字89. 矩阵中的最长递增路径90. 找到所有数组中消失的数字91. 最小覆盖子串92. 最佳买卖股票时机含冷冻期93. 找到字符串中所有字母异位词94. 单词拆分95. 验证二叉树的前序序列化96. 从前序与中序遍历序列构造二叉树97. 子数组最大平均数 I98. 单词搜索 II99. 最长连续递增序列100. 打家劫舍。
C语言:通过返回指针的形式找出数组的最大值和最小值

C语⾔:通过返回指针的形式找出数组的最⼤值和最⼩值//// main.c// Pointer_max_min(return)//// Created by ma c on 15/8/2.// Copyright (c) 2015年 bjsxt. All rights reserved.// 要求:使⽤返回指针的函数查找10个整数的最⼤值和最⼩值。
#include <stdio.h>int *Find_max(int *arr,int len);int *Find_min(int *arr,int len);int main(int argc, const char * argv[]){int arr[5]={14,65,42,10,20};printf("the max is :%d\n",*Find_max(arr,5));printf("the min is :%d\n",*Find_min(arr,5));return 0;}int *Find_max(int *arr,int len)//返回最⼤值地址{int *max = arr;//⾸先定义⼀个最⼩值指针max指向数组的⾸地址for(int i=0;i<len;i++){max = (*max>*(arr+i))?max:(arr+i);//通过⽐较值的⼤⼩,来改变max指针的指向位置}return max;//返回的是指向最⼤值的指针,即最⼤值所在位置的地址}int *Find_min(int *arr,int len)//返回最⼩值地址{int *min = arr;//⾸先定义⼀个最⼩值指针min指向数组的⾸地址for(int i=0;i<len;i++){min = (*min<*(arr+i))?min:(arr+i);//通过⽐较值的⼤⼩,来改变min指针的指向位置}return min;//返回的是指向最⼩值的指针,即最⼩值所在位置的地址}。
数据结构算法设计笔试面试题1
【字符串】1、输入一个字符串,打印出该字符串中字符的所有排列。
例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
2、有一个由大小写组成的字符串,现在需要对他进行修改,将其中的所有小写字母排在大写字母的前面(大写或小写字母之间不要求保持原来次序),如有可能尽量选择时间和空间效率高的算法。
c语言函数原型void proc(char *str),也可以采用你自己熟悉的语言。
3、编写反转字符串的程序,要求优化速度、优化空间。
4、用C语言实现函数void * memmove(void *dest, const void *src, size_t n)。
memmove函数的功能是拷贝src所指的内存内容前n个字节到dest所指的地址上。
分析:由于可以把任何类型的指针赋给void类型的指针,这个函数主要是实现各种数据类型的拷贝。
5、编程找出两个字符串中最大公共子字符串,如"abccade", "dgcadde"的最大子串为"cad"。
6、输入一个字符串,输出该字符串中对称的子字符串的最大长度。
比如输入字符串"google",由于该字符串里最长的对称子字符串是"goog",因此输出4。
7、字符串原地压缩。
题目描述:“eeeeeaaaff" 压缩为"e5a3f2",请编程实现。
8、请以回溯与不回溯算法实现字符串匹配。
9、输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
句子中单词以空格符隔开。
为简单起见,标点符号和普通字母一样处理。
例如:输入"I am a student.",则输出"student. a am I"。
10、在一个字符串中找到第一个只出现一次的字符。
如输入abaccdeff,则输出b。
编程题经典100例
编程题经典100例编程是当今世界重要的职业领域之一。
许多年轻人渴望成为优秀的程序员,而要做到这一点,练习编程题是必不可少的。
编程题可以帮助初学者加强对算法和编程语言的理解,更好地掌握编程技能。
以下是编程题经典100例,它们分别来自不同的领域和难度级别,希望对初学者有所帮助。
1. 计算素数输入一个正整数num,输出小于等于num的所有素数。
解析:函数is_prime(num)用来判断num是否为素数,若是,返回True,否则返回False。
对于小于等于num的每个数i,如果is_prime(i)返回True,则输出i。
2. 反转字符串输入一个字符串,输出反转后的字符串。
解析:先将字符串转成列表list,然后使用列表切片操作[::-1]反转列表,最后将列表转回字符串。
3. 删除特定字符输入一个字符串str和一个字符ch,输出删除ch后的字符串。
解析:通过字符串的replace()方法删除ch,返回删除后的新字符串。
4. 合并列表输入两个有序列表a和b,输出合并后的有序列表c。
解析:先将a和b合并成一个列表,再使用sort()方法进行排序。
5. 翻转列表输入一个列表,输出翻转后的列表。
解析:使用列表切片[::-1]反转列表。
6. 平均值输入一个列表,输出列表元素的平均值。
解析:使用sum()函数求和,除以列表长度。
7. 数组移动输入一个列表和一个整数n,将列表中前n个元素移到列表的末尾。
解析:将列表分为前n个元素和剩余元素两部分,然后再将这两个部分合并成一个列表。
8. 查找最大元素输入一个列表,输出列表中的最大元素。
解析:使用max()函数找出列表中的最大值。
9. 打印模型输入一个整数n,输出一个由“*”字符组成的模型,模型是n个星号按一行一个打印,直到n个星号都打印出来。
解析:使用循环输出n个星号。
10. 插入排序输入一个列表,实现插入排序。
解析:对于列表中每个元素i,从0到i-1遍历列表,将i和遍历到的元素进行比较,然后插入到正确的位置。
c语言函数求数组最大最小值
c语言函数求数组最大最小值一、题目要求编写一个C语言函数,用于求解一个数组的最大值和最小值。
二、函数设计1. 函数名:findMaxMin2. 函数参数:数组arr和数组长度len3. 函数返回值:无返回值,但通过指针参数max和min返回最大值和最小值4. 函数实现:利用循环遍历数组,比较每个元素与当前的最大值和最小值,更新max和min的值。
三、代码实现```c#include <stdio.h>void findMaxMin(int arr[], int len, int *max, int *min){*max = arr[0]; // 假设第一个元素是最大的 *min = arr[0]; // 假设第一个元素是最小的for (int i=1; i<len; i++) {if (arr[i] > *max) {*max = arr[i];}if (arr[i] < *min) {*min = arr[i];}}}int main(){int arr[] = {10, 20, 30, 40, 50};int len = sizeof(arr) / sizeof(arr[0]);int max, min;findMaxMin(arr, len, &max, &min);printf("Max: %d\n", max);printf("Min: %d\n", min);return 0;}```四、代码解析1. 第一行引入了标准输入输出库stdio.h。
2. findMaxMin函数中,max和min是指针类型的参数,用于返回最大值和最小值。
3. 在函数中,假设第一个元素是最大的、最小的,然后遍历数组,比较每个元素与当前的最大值和最小值,更新max和min的值。
4. 在main函数中,定义了一个数组arr和数组长度len,并调用findMaxMin函数来获取最大值和最小值。
二分法的应用实例
二分法的应用实例
二分法的应用实例:查找旋转排序数组中的最小值
二分法是一种高效的算法,在查找、排序等领域有着广泛的应用。
其中,在查找旋转排序数组中的最小值问题中,二分法的应用尤为突出。
旋转排序数组是指一个原本递增的有序数组,在经过旋转后,有可能变成了一个部分递增、部分递减的有序数组。
例如,[4,5,6,7,0,1,2]就是一个旋转排序数组,其中最小值为0。
如何通过二分法来查找旋转排序数组中的最小值呢?以下是一种基于二分法的解决方案:
1. 首先,我们需要明确一个性质:旋转排序数组中最小的元素,一定是在“旋转点”处。
2. 我们采用二分法的思想,设定两个指针left和right,分别指向数组的首位元素。
计算出它们的中间位置mid,并将其与right元素进行比较。
3. 如果mid位置的元素小于right位置的元素,说明最小值可能在mid左边,因此我们将right指针移动到mid位置。
反之,如果mid位置的元素大于right位置的元素,说明最小值可能在mid右边,因此我们将left指针移动到mid+1位置。
4. 接着,我们重复步骤2和3,直到left和right指针相遇。
此时,它们指向的元素即为旋转数组中最小的元素。
这种基于二分法的解决方案具有时间复杂度O(logn),比暴力搜索的时间复杂度O(n)要快得多。
而且,这种解决方案还具有一定的通用性,可以用于查找旋转排序数组中的最大值、查找某个元素是否存在等问题。
二分法是一种非常有用的算法,可以在许多领域发挥重要作用。
在实际应用中,我们需要根据具体问题来选择合适的解决方案,以达到最优的效果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
这道题最直观的解法并不难,从头到尾遍历数组一次,我们就能找出最小的元素。
这种思路的时间复杂度显然是O(n)。
但是这个思路没有利用输入的旋转数组的特性,肯定达不到面试官的要求。
我们注意到旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都大于或者等于后面子数组的元素。
我们还注意到最小的元素刚好是这两个子数组的分界线。
在排序的数组中我们可以用二分查找法实现O(logn)的查找。
本题给出的数组在一定程度上是排序的,因此我们可以试着用二分查找法的思路来寻找这个最小的元素。
和二分查找法一样,我们用两个指针分别指向数组的第一个元素和最后一个元素。
按照题目中旋转的规则,第一个元素应该是大于或者等于最后一个元素的(这其实不完全对,还有特例,后面再加以讨论)。
接着我们可以找到数组中间的元素。
如果该中间元素位于前面的递增子数组,那么它应该大于或者等于第一个指针指向的元素。
此时数组中最小的元素应该位于该中间元素的后面。
我们可以把第一个指针指向该中间元素,这样可以缩小寻找的范围。
移动之后的第一个指针仍然位于前面的递增子数组之中。
同样,如果中间元素位于后面的递增子数组,那么它应该小于或者等于第二个指针指向的元素。
此时该数组中最小的元素应该位于该中间元素的前面。
我们可以把第二个指针指向该中间元素,这样也可以缩小寻找的范围。
移动之后的第二个指针仍然位于后面的递增子数组之中。
不管是移动第一个指针还是第二个指针,查找范围都会缩小到原来的一半。
接下来我们再用更新之后的两个指针,重复做新一轮的查找。
按照上述的思路,第一个指针总是指向前面递增数组的元素,而第二个指针总是指向后面递增数组的元素。
最终第一个指针将指向前面子数组的最后一个元素,而第二个指针会指向后面子数组的第一个元素。
也就是它们最终会指向两个相邻的元素,而第二个指针指向的刚好是最小的元素。
这就是循环结束的条件。
以前面的数组{3,4,5,1,2}为例,我们先把第一个指针指向第0个元素,把第二个指针指向第4个元素(如图2.10 (a)所示)。
位于两个指针中间(在数组中的下标是2)的数字是5,它大于第一个指针指向的数字。
因此中间数字5-定位于第一个递增子数组中,并且最小的数字一定位于它的后面。
因此我们可以移动第一个指针让它指向数组的中间(图2.10 (b)所示)。
此时位于这两个指针中间(在数组中的下标是3)的数字是l,它小于第二个指针指向的数字。
因此这个中间数字1-定位于第二个递增字数组中,并且最小的数字一定位于它的前面或者它自己就是最小的数字。
因此我们可以移动第二个指针指向两个指针中间的元素即下标为3的元素(如图2.10 (c)所示)。
图2.10在数组{3,4,5,1,2)中查找最小值的过程注:旋转数组中包含两个递增排序的子数组,有阴影背景的是第二个子数组。
(a)把P1指向数组的第一个数字,P2指向数组的最后一个数字。
由于P1和P2中间的数字5大于Pl指向的数字,中间的数字在第一个子数组中。
下一步把P1指向中间的数字。
(b) P1和P2中间的数字1小于P2 指向的数字,中间的数字在第二个子数组中。
下一步把P2指向中间的数字。
(c) Pl和P2指向两个相邻的数字,则P2指向的是数组中的最小数字。
此时两个指针的距离是1,表明第一个指针已经指向了第一个递增子数组的末尾,而第二个指针指向第二个递增子数组的开头。
第二个子数组的第一个数字就是最小的数字,因此第二个指针指向的数字就是我们查找的结果。
基于这个思路,我们可以写出如下代码:int Min (int* numbers, int length){if (numbers==NULL | | length<=O)throw new std:: exception("Invalid parameters");int indexl=0;int index2=length -1;int.indexMid=index1.while( numbers [indexl] >=numbers [index2]){if (index2 - indexl= =1){indexMid=index2;break;}indexMid= (indexl+index2) /2;if (numbers [indexMid] >=numbers [indexl])indexl=index Mid;else if (numbers [indexMid] <=numbers[index2])index2=index Mid;}return numbers [indexMid];}_____________________________________________________________________前面我们提到在旋转数组中,由于是把递增排序数组前面的若干个数字搬到数组的后面,因此第一个数字总是大于或者等于最后一个数字。
但按照定义还有一个特例:如果把排序数组的前面的0个元素搬到最后面,即排序数组本身,这仍然是数组的一个旋转,我们的代码需要支持这种情况。
此时,数组中的第一个数字就是最小的数字,可以直接返回。
这就是在上面的代码中,把indexMid初始化为indexl的原因。
一旦发现数组中第一个数字小于最后一个数字,表明该数组是排序的,就可以直接返回第一个数字了。
上述代码是否就完美了呢?面试官会告诉我们其实不然。
他将提示我们再仔细分析下标为indexl和index2(indexl和index2分别和图中P1和P2相对应)的两个数相同的情况。
在前面的代码中,当这两个数相同,并且它们中间的数字(即indexMid指向的数字)也相同时,我们把index Mid赋值给了indexl,也就是认为此时最小的数字位于中间数字的后面。
是不是一定这样?我们再来看一个例子。
数组{l,0,1,l,1)和数组{1,1,l,0,1}都可以看成是递增排序数组{0,1,1,1,1)的旋转,图2.11分别画出它们由最小数字分隔开的两个子数组。
图2.11数组(0,1,1,1,1)的两个旋转{1,0,1,1,1)和{1,1,1,0,1)注:在这两个数组中,第一个数字、最后一个数字和中间数字都是1,我们无法确定中间的数字1属于第一个递增子数组还是属于第二个递增子数组。
第二个子数组用灰色背景表示。
在这两种情况中,第一个指针和第二个指针指向的数字都是1,并且两个指针中间的数字也是1,这3个数字相同。
在第一种情况中,中间数字(下标为2)位于后面的子数组;在第二种情况中,中间数字(下标为2)位于前面的子数组中。
因此,当两个指针指向的数字及它们中间的数字三者相同的时候,我们无法判断中间的数字是位于前面的子数组中还是后面的子数组中,也就无法移动两个指针来缩小查找的范围。
此时,我们不得不采用顺序查找的方法。
在把问题分析清楚形成清晰的思路之后,我们就可以把前面的代码修改为:int Min (int* numbersr int length){if(numbers==NULL | | length<=0)throw new std:: exception( "Invalid parameters");int indexl=0;int index2=length -l;int indexMid=index1;while (numbers [indexl] >=numbers [index2]){if (index2 - indexl==1){indexMid=index2;break;}indexMid= (indexl+index2) /2;//如果下标为indexl. index2和indexMid指向的三个数字相等,//则只能顺序查找if (numbers[indexl] ==numbers [index2]&&numbers [indexMid] ==numbers [indexl])return MinlnOrder (numbers, indexl, index2);if(numbers [indexMid] >=numbers [indexl])indexl=index Mid;else if (numbers[indexMid] <=numbers[index2])index2=index Mid;}return numbers[indexMid];}int MinlnOrder (int* numbers, int indexl, int index2){int result=numbers [indexl1;for (int i=indexl+1;i<=index2; ++i){if (result>numbers[i])result=numbers [i];}return result;}________________________________________________________源代码:本题完整的源代码详见08 MinNimberInRotatedArray项目。
测试用例:●功能测试(输入的数组是升序排序数组的一个旋转,数组中有重复数字或者没有重复数字)。
●边界值测试(输入的数组是一个升序排序的数组、只包含一个数字的数组)。
●特殊输入测试(输入NULL指针)。
本题考点:●考查对二分查找的理解。
本题变换了二分查找的条件,输入的数组不是排序的,而是排序数组的一个旋转。
这要求我们对二分查找的过程有深刻的理解。
●考查沟通学习能力。
本题面试官提出了一个新的概念:数组的旋转。
我们要在很短时间内学习理解这个新概念。
在面试过程中如果面试官提出新的概念,我们可以主动和面试官沟通,多问几个问题把概念弄清楚。
●考查思维的全面性。
排序数组本身是数组旋转的一个特例。
另外,我们要考虑到数组中有相同数字的特例。
如果不能很好地处理这些特例,就很难写出让面试官满意的完美代码。