剑指offer数组3
面试题11:旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
考察对二分查找的理解
1. 定义两个指针。第一个 index1 指向第一个元素,第二个 index2 指向最后一个元素。
2. 数组的中间元素 indexMid。如果该中间元素位于前面的递增子数组,那么它大于等于第一个指针指向的元素(最小的元素应该在后面)。index1 = indexMid
如果中间元素位于后面的递增子数组,那么它小于等于第二个指针指向的元素(最小的元素应该在前面)index2 = indexMid
3. 最终两个指针会相邻,第二个指针指向的刚好是最小的元素
特殊情况:
数组{1,0,1,1,1}和数组{1, 1, 1, 0, 1}都看以看成递增排序数组{0, 1, 1, 1, 1}的旋转

当两个指针指向的数字及它们中间的数字三者相同,我们无法判断中间元素位于前面的子数组还是后面的子数组。不得不采用顺序查找的方法。
#include <exception>
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int size = rotateArray.size();
if(size == ){
return ;
}
int left = ,right = size - ;
int mid = ;
while(rotateArray[left] >= rotateArray[right]){
if(right - left == ){
mid = right;
break;
}
mid = left + (right - left) / ;
// rotateArray[left] rotateArray[right] rotateArray[mid]三者相等
// 无法确定中间元素是属于前面还是后面的递增子数组
// 只能顺序查找
if(rotateArray[left] == rotateArray[right] && rotateArray[left] == rotateArray[mid]){
return MinOrder(rotateArray,left,right);
}
// 中间元素位于前面的递增子数组
// 此时最小元素位于中间元素的后面
if(rotateArray[mid] >= rotateArray[left]){
left = mid;
}
// 中间元素位于后面的递增子数组
// 此时最小元素位于中间元素的前面
else{
right = mid;
}
}
return rotateArray[mid];
}
private:
// 顺序寻找最小值
int MinOrder(vector<int> &num,int left,int right){
int result = num[left];
for(int i = left + ;i < right;++i){
if(num[i] < result){
result = num[i];
}//if
}//for
return result;
}
};
面试题56:数组中只出现一次的数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度为O(1)
假设输入数组{2, 4, 3, 6, 3, 2, 5, 5}。当我们依次对数组中的每个数字进行异或运算之后,得到的结果是0010。异或得到结果中的倒数第二位是1,于是我们根据数字的倒数第二位是不是1,将该数组分为两个子数组。第一个子数组{2, 3, 6, 3, 2}中所有数字的倒数第二位都是1,而第二个子数组{4, 5, 5}中所有数字的倒数第二位是0。接下来对每个子数组求异或,第一个子数组的结果是6,第二个子数组的结果是4
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int length = data.size();
if(length < )
return;
int resultExclusiveOR = ;
for(int i = ; i < length; ++i)
{
// 所有元素相异或,得到结果。本例为0010
resultExclusiveOR ^= data[i];
}
// indexOf1 为倒数第二位
unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
*num1 = *num2 = ;
for(int j = ; j < length; ++j)
{
if(IsBit1(data[j], indexOf1))
*num1 ^= data[j];
else
*num2 ^= data[j];
}
}
// 找到最右边是1的位
unsigned int FindFirstBitIs1(int num)
{
int indexBit = ;
while(((num & ) == ) && (indexBit < * sizeof(int)))
{
num = num >> ;
++indexBit;
}
return indexBit;
}
// IsBit1 是判断在num的二进制表示中从右边数起的indexBit位是不是1
bool IsBit1(int num, unsigned int indexBit)
{
num = num >> indexBit;
return (num & );
}
};
面试题57:和为s的数字
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
// 返回的结果是个数组
vector<int> result;
int length = array.size();
if(length <= )
return result;
int head = ;
int behind = length - ;
while(head < behind)
{
int curSum = array[head] + array[behind];
if(curSum > sum)
{
--behind;
}
else if(curSum < sum)
{
++head;
}
else
{
result.push_back(array[head]);
result.push_back(array[behind]);
break;
}
}
return result;
}
};
面试题57(二):和为s的连续正数序列
输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如:输入15,由于1+2+3+4+5=7+8=15,所以打印出3个连续序列1~5、4~6和7~8
class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
vector<vector<int> > result;
if(sum < )
return result;
int small = ;
int big = ;
int middle = ( + sum) / ;
while(small < middle)
{
int curSum = (small + big) * (big - small + ) / ;
if(curSum < sum)
++big;
if(curSum == sum)
{
vector<int> res;
for(int i = small; i <= big; ++i)
{
res.push_back(i);
}
result.push_back(res);
++small;
}
if(curSum > sum)
{
++small;
}
}
return result;
}
};
剑指offer数组3的更多相关文章
- 剑指 Offer —— 数组中重复的数字
数组中的重复数字 题目描述 牛课网链接 长度为 n 的数组里,所有数字都在 0 到 n-1 的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一 ...
- 剑指offer 数组中重复的数
在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{ ...
- 剑指Offer 数组中只出现一次的数字
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 因为有2个数字只出现了一次,而其他的数字都是2次,可以通过异或运算,得到最后这2个只 ...
- [剑指OFFER] 数组中的逆序对
题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 分析:利用归并排序的思想,分成2部分,每一部分按照从大到 ...
- 剑指offer数组2
面试题39:数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次, ...
- 剑指offer数组1
面试题3:数组中重复的数字 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例 ...
- 剑指offer数组列表
一.数组 面试题3 : 找出数组中重复的数字 面试题3(二):不修改数组找出重复的数字 面试题4:二维数组的查找 面试题21:调整数组顺序使奇数位于偶数前面 面试题39:数组中出现次数超过一半的数字 ...
- 剑指Offer——数组中重复的数字
题目描述: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度 ...
- 剑指Offer——数组中只出现一次的数字
题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 分析: 数组中一共有偶数个数.两个数字只出现过一次. 相同数异或在一起等于0,那么将所有数异或 ...
随机推荐
- error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\cl.exe' failed with exit status 2
安装mysql是出现这个错误. python3.和python2.两个的版本不一样,所以安装的东西也不一样:MySQLdb 安装mysql的连接包.工具安装 Python3.x版本:Pip insta ...
- 洛谷 P1411 树
最近在做些树形DP练练手 原题链接 大意就是给你一棵树,你可以断开任意数量的边,使得剩下的联通块大小乘积最大. 样例 8 1 2 1 3 2 4 2 5 3 6 3 7 6 8 输出 18 我首先想的 ...
- Springboot 1.简介 及第一个demo
按照官网上的新建一个maven项目,然后将类引入pom.xml文件中 <?xml version="1.0" encoding="UTF-8"?> ...
- python中logger模块的应用
logger模块是python内置的一个模块,主要用于输出运行日志,可以输出日志的等级,日志的保存路径等 具体详见博客https://www.cnblogs.com/qianyuliang/p/723 ...
- jmeter+maven+jenkins自动化接口测试(上)
代码已上传git(包括调试的jmx,jmeter相关文件等):https://gitlab.com/yinzhenzhi/jmeterandmaven 目的:现在很多人都在做自动化接口的平台,我也正在 ...
- <三>企业级开源仓库nexus3实战应用–使用nexus3配置maven私有仓库
一两个星期之前,你如果在我跟前说起私服的事情,我大概会绕着你走,因为我对这个东西真的一窍不通.事实上也正如此,开发同学曾不止一次的跟我说公司的私服版本太旧了,许多新的依赖编译之后不会从远程仓库自动缓存 ...
- [Android] Android RxJava2+Retrofit2+OkHttp3 的使用
[Android] Android RxJava2+Retrofit2+OkHttp3 简单介绍Retrofit.OKHttp和RxJava之间的关系: Retrofit:Retrofit是Squar ...
- 基于STM32F1的语音合成芯片SYN6288驱动
目录 说明 SYN6288.h SYN6288.c 说明 基于USART2制作,封装了各种通信协议 SYN6288.h #ifndef _SYN6288_H_ #define _SYN6288_H_ ...
- vue之生命周期函数例子
执行代码看生命周期函数的执行顺序 <!-- 根组件 --> <!-- vue的模板内,所有内容要被一个根节点包含起来 App.vue --> <template> ...
- scheduling while atomic 出现的错误
产生这种情况的原因: 1.当中断发生时,出现了调度做法, 2.另一个是spin_lock 里调用sleep, 让出调度, 另外线程又进行spin_lock, 导致死锁. 相关问题的链接 1.为 ...