面试题8:旋转数组的最小数字
来源:互联网 发布:webpack mac 安装 编辑:程序博客网 时间:2024/04/28 08:06
- 题目描述:Online Judge
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
- 输入:
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数。
输入的第二行包括n个整数,其中每个整数a的范围是(1<=a<=10000000)。
- 输出:
对应每个测试案例,
输出旋转数组中最小的元素。
- 样例输入:
53 4 5 1 2
- 样例输出:
1
问题分析:
1)常规的思路是从头到尾扫描一遍数组,然后得到最小值,这种思想的时间复杂度显然是O(n),但是这种思路达不到面试官的要求。
2)数组前和尾分别设置一个指针,然后采用类似快速排序的方法得到解。其中要注意的有数组中可能存在最小值重复的情况。
java代码:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.StreamTokenizer;public class Problem_08 {public static void main(String[] args) throws IOException {BufferedReader bu= new BufferedReader( new InputStreamReader(System.in));StreamTokenizer str = new StreamTokenizer(bu);while(str.nextToken() != StreamTokenizer.TT_EOF){int n = (int)str.nval;int [] array = new int[n];for(int i = 0; i < n; i++){str.nextToken();array[i] = (int) str.nval;}// end for System.out.println(findMin(array));}//end while}//end mainpublic static int findMin(int[] array){if(array.length == 0){return 0;}//end if int start = 0;int end = array.length - 1;int mid = start;while(array[start] >= array[end]){if(end - start == 1){mid = end;break;}mid = (start + end )/2;if( array[start] == array[end] && array[start] == array[mid] ){return minOrder(array,start,end);}//end ifif(array[start] <= array[mid]){start = mid;}else if (array[end] >= array[mid]){end = mid;}//end if}//end whilereturn array[mid];}//end findMinpublic static int minOrder(int[] array, int start, int end){int result = array[start];for(int i = start + 1; i <= end; i++){if(result > array[i]){result = array[i];}}//end forreturn result;}//end minOrder}
C++代码:#include "iostream"#include "cstdio"using namespace std; int MinInOrder(int *a, int low, int high){ int re = a[low]; for(int i = low + 1; i <= high; ++i) if(re > a[i]) re = a[i]; return re;} int MinSearch(int A[], int low, int high){ int mid; mid = (low + high) / 2; if(A[low] <= A[mid] && A[mid] <= A[high]) mid = low; while(A[low] >= A[high]) { if(high - low == 1) { mid = high; break; } mid = (low + high) / 2; if(A[low] == A[mid] && A[mid] == A[high]) { return MinInOrder(A, low, high); } if(A[mid] >= A[low]) low = mid; else if(A[mid] <= A[high]) high = mid; } return A[mid];} int main(){ int n; while(scanf("%d",&n)!=EOF) { int *a = new int[n]; for(int i = 0; i < n; ++i) scanf("%d",&a[i]); int r = MinSearch(a, 0, n - 1); printf("%d\n",r); delete []a; a = NULL; } return 0;}
C代码:
#include <stdio.h>#include <stdlib.h> int main(){ int left, right, mid, i, n, min, arr[1000001]; while (scanf("%d", &n) != EOF) { for (i = 0; i < n; i ++) scanf("%d", &arr[i]); left = 0; right = n - 1; mid = left; while (arr[left] >= arr[right]) { if (left + 1 == right) { mid = right; break; } mid = (left + right) / 2; // 特例情况 if (arr[left] == arr[mid] && arr[mid] == arr[right]) { // 顺序查找 for (i = left + 1, min = arr[left]; i <= right; i ++) { if (arr[i] < min) { min = arr[i]; mid = i; } } break; } if (arr[mid] >= arr[left]) { left = mid; } else if (arr[mid] <= arr[right]) { right = mid; } } printf("%d\n", arr[mid]); } return 0;}
测试用例:1)输入升序排序的一个旋转数组,数组中有重复数字或者没有重复数字。2)边界值测试(输入数组是一个升序排序的数组,只包含一个数字的数组)。3)特殊数组测试(空指针输入)体会:本题类似于快速排序的一次排序。
- 面试题:旋转数组的最小数字
- 面试题8:旋转数组的最小数字 ***
- 面试题8:旋转数组的最小数字
- 【剑指offer】面试题8:旋转数组的最小数字
- 剑指offer面试题8:旋转数组的最小数字
- 剑指Offer:面试题8 :旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- 《剑指offer》面试题8旋转数组的最小数字
- 面试题8-旋转数组的最小数字
- 面试题8 旋转数组的最小数字
- 面试题8 旋转数组的最小数字
- 《剑指Offer》面试题8:旋转数组的最小数字
- 面试题8 旋转数组的最小数字
- 【剑指offer】 面试题8: 旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- 剑指offer-面试题8:旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- cocos2d/cocos/platform/CCGLViewProtocol.cpp
- IIS提升网站并发数
- 如何从SVN导入Maven管理的eclipse项目
- Five things that make Go fast
- 动态设置drawableTop,drawableLeft,drawableRight,drawableBottom
- 面试题8:旋转数组的最小数字
- Oracle中不同语言环境导致to_date出错的问题
- TextView无焦点滚动(一)
- malloc/free和new/delete的区别
- JSP----application
- leetcode - Sum Root to Leaf Numbers
- Android下的Activity的四种启动模式
- Android判断应用程序是否安装和版本号
- Python 代码到这个水平就行了!!