剑指offer面试题8
来源:互联网 发布:淘宝极速退款没有了 编辑:程序博客网 时间:2024/05/16 06:02
面试题8:旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.
预备知识:
排序: 归并排序,快速排序,插入排序,冒泡排序
查找:二分查找,顺序查找,哈希表查找,二叉树排序树查找
指标:额外空间消耗,平均时间复杂度和最差时间复杂度
实现方式:递归和循环两种方式
位运算:与&,或|,异或^,左移<<,右移>>
思路:首先要弄清楚题目的意思以及相关的概念,接着需要自己通过一个简单的例子进行具体分析如何查找,最后寻找特殊的例子,如边界值或特殊输入进行分析即可,这里需要注意临界条件。
算法实现:
#include "stdafx.h"#include<exception> //C++异常处理int MinInOrder(int* numbers, int index1, int index2);int Min(int* numbers, int length){ if(numbers == NULL || length <= 0) throw new std::exception("Invalid parameters"); //异常处理类class exception; //在C/C++数组索引是从0开始的 int index1 = 0; //开头元素索引 int index2 = length - 1; //结束元素索引 int indexMid = index1; //当前面0个元素搬到最后面,即保存不变的时候 while(numbers[index1] >= numbers[index2]) //临界条件 { // 如果index1和index2指向相邻的两个数, // 则index1指向第一个递增子数组的最后一个数字, // index2指向第二个子数组的第一个数字,也就是数组中的最小数字 if(index2 - index1 == 1) //相邻元素 { indexMid = index2; break; } // 如果下标为index1、index2和indexMid指向的三个数字相等, // 则只能顺序查找 indexMid = (index1 + index2) / 2; if(numbers[index1] == numbers[index2] && numbers[indexMid] == numbers[index1]) //特例的情况 return MinInOrder(numbers, index1, index2); //顺序查找 // 缩小查找范围 if(numbers[indexMid] >= numbers[index1]) //中间元素大于等于前面的元素,说明这个元素位于第一递增数组中 index1 = indexMid; else if(numbers[indexMid] <= numbers[index2])//中间元素小于等于后面的元素,说明这个元素位于第二递增数组中 index2 = indexMid; } return numbers[indexMid];}//顺序查找最小值int MinInOrder(int* numbers, int index1, int index2){ int result = numbers[index1]; for(int i = index1 + 1; i <= index2; ++i) //在数组中遍历每一个值 { if(result > numbers[i]) result = numbers[i]; } return result;}// ====================测试代码====================void Test(int* numbers, int length, int expected){ int result = 0; try { result = Min(numbers, length); //二分查找最小 for(int i = 0; i < length; ++i) printf("%d ", numbers[i]); if(result == expected) printf("\tpassed\n"); else printf("\tfailed\n"); } catch (...) { if(numbers == NULL) //特殊输入测试 printf("Test passed.\n"); else printf("Test failed.\n"); }}int _tmain(int argc, _TCHAR* argv[]){ // 典型输入,单调升序的数组的一个旋转 int array1[] = {3, 4, 5, 1, 2}; Test(array1, sizeof(array1) / sizeof(int), 1); // 有重复数字,并且重复的数字刚好的最小的数字 int array2[] = {3, 4, 5, 1, 1, 2}; Test(array2, sizeof(array2) / sizeof(int), 1); // 有重复数字,但重复的数字不是第一个数字和最后一个数字 int array3[] = {3, 4, 5, 1, 2, 2}; Test(array3, sizeof(array3) / sizeof(int), 1); // 有重复的数字,并且重复的数字刚好是第一个数字和最后一个数字 int array4[] = {1, 0, 1, 1, 1}; Test(array4, sizeof(array4) / sizeof(int), 0); // 单调升序数组,旋转0个元素,也就是单调升序数组本身 int array5[] = {1, 2, 3, 4, 5}; Test(array5, sizeof(array5) / sizeof(int), 1); // 数组中只有一个数字 int array6[] = {2}; Test(array6, sizeof(array6) / sizeof(int), 2); // 输入NULL Test(NULL, 0, 0); return 0;}
//***********************7月12日********************************************************//
// 面试题8.cpp : 定义控制台应用程序的入口点。////旋转数组的最小数字#include "stdafx.h"#include <exception>using namespace std;int Min_1(int* numbers, int length){if(numbers == NULL || length < 0)throw new std::exception("Invalid parameters");int index1 = 0; //第一个指针int index2 = length - 1; //第二个指针int indexMid = index1;while(numbers[index1] >= numbers[index2]){if(index2 - index1 == 1 ){indexMid = index2;break;}if (index1 == index2){indexMid = index2;break;}indexMid = (index1 + index2) / 2; //中间元素if (numbers[indexMid] >= numbers[index1])index1 = indexMid;else if (numbers[indexMid] <= numbers[index2])index2 = indexMid;}return numbers[indexMid];}int MinInOrder(int* numbers, int index1, int index2);int Min_2(int* numbers, int length){if(numbers == NULL || length <= 0)throw new std::exception("Invalid parameters");int index1 = 0;int index2 = length -1;int indexMid = index1;while(numbers[index1] >= numbers[index2]){indexMid = (index1 + index2) / 2; //中间的元素//如果这指针指向的3个元素相等,那么只能顺序查找了if(numbers[index1] == numbers[index2] && numbers[indexMid] == numbers[index1]){return MinInOrder(numbers, index1, index2);}if(numbers[indexMid] >= numbers[index1])index1 = indexMid;else if(numbers[indexMid] <= numbers[index2])index2 = indexMid;}}//顺序查找int MinInOrder(int* numbers, int index1, int index2){int result = numbers[index1];for(int i = index1 + 1; i <= index2; ++i){if(result > numbers[i])result = numbers[i];}return result;}/************测试1*************/void Test1(){int numbers[] = {3,4,5,6,7,8,9,-2,-1,1,2};int min = Min_1(numbers, sizeof(numbers)/sizeof(int));printf("min = %d\n", min);}//int numbers[] = {1,2,3,4,5,6}void Test2(){int numbers[] = {1,2,3,4,5,6}; //0次旋转int min = Min_1(numbers, sizeof(numbers)/sizeof(int));printf("min = %d\n", min);}//int numbers[]={111111}void Test3(){int numbers[] = {1,1,1,1,1,1};int min = Min_1(numbers, sizeof(numbers)/sizeof(int));printf("min = %d\n", min);}//int numbers[]={111000}void Test4(){int numbers[] = {1,1,1,0,0,0};int min = Min_1(numbers, sizeof(numbers)/sizeof(int));printf("min = %d\n", min);}//int numbers[]={111-211}void Test5(){int numbers[] = {1,1,1,-2,1,1};int min = Min_1(numbers, sizeof(numbers)/sizeof(int));printf("min = %d\n", min);}//int numbers[]={1-21111}void Test6(){int numbers[] = {1,-2,1,1,1,1};int min = Min_1(numbers, sizeof(numbers)/sizeof(int));printf("min = %d\n", min);}//int numbers[]={1}void Test7(){int numbers[] = {1};int min = Min_1(numbers, sizeof(numbers)/sizeof(int));printf("min = %d\n", min);}//int numbers[]={1}void Test8(){try{int min = Min_1(NULL, 0);printf("min = %d\n", min);} catch(...){printf("无效参数\n");}}/*********测试2*********///int numbers[]={1}void Test1_1(){int numbers[] = {1,-2,1,1,1,1};int min = Min_2(numbers, sizeof(numbers)/sizeof(int));printf("min = %d\n", min);}int _tmain(int argc, _TCHAR* argv[]){//Test1();//Test2();//Test3();//Test4();//Test5();Test6();//Test7();Test8();Test1_1();return 0;}
0 0
- 剑指offer面试题8
- 剑指offer 面试题8
- 剑指offer面试题8
- 【面试题】剑指offer 8
- 剑指offer 面试题
- 剑指offer面试题
- 剑指offer面试题8--数组旋转
- 剑指Offer(面试题8~10)
- 剑指Offer面试题8 & Leetcode153
- 剑指offer面试题总结
- 剑指offer面试题06
- 剑指offer面试题 04
- 剑指offer 面试题07
- 剑指offer面试题08
- 剑指offer面试题42
- 剑指offer面试题1
- 剑指offer面试题3
- 剑指offer面试题4
- More Effective C++读书笔记
- 简易的并查集
- 人生,应有的姿态
- 深入分析 Linux操作系统的内核链表
- [C#]Lambda表达式和Where语法
- 剑指offer面试题8
- 以前的博客,分享的是各种原创自定义控件
- Java中Collection和Collections的区别
- 排序入门(1)
- jar file 在eclipse运行成功 换命令行运行却出错
- Linux内核regulator架构和编写
- Android实现推送方式解决方案 - 长连接+心跳机制(MQTT协议)
- 黑马程序员_java面向对象思想学习总结
- ElasticSearch远程任意代码执行漏洞(CVE-2014-3120)分析