剑指Offer-旋转数组的最小数字
2018-03-26 16:27
429 查看
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。如果直接遍历数组,时间复杂度为O(n),可以利用旋转数组的特性来解决此题;思路:(1)如果发生旋转,前面的数至少去了一个放在数组的后面; 1)旋转后,数组分为两个排序数组,而且前一个数组中的数均大于等于后一个数组中的数,因为要查找数组中的最小数,也就是第二个数组中的第一个数,可以采用二分查找的思想;2)设置两个指针p1,p2,p1指向数组的开始位置,也就是第一个数组的开始位置,p2指向数组的终止位置,也就是第二个数组的结束位置。Mid=p1+p2/2; 如果中间位置mid的数大于p1指向的数,则mid在第一个数组中,让p1指向mid所指向的数,p1指向的依然是数组1的数; 如果中间位置mid的数小于p2所指向的位置,则mid在第二个数组中,p2指向mid指向的数,p2指向的依然是数组2的数;Mid不是指向数组1的数,就是指向数组2的数,指向数组1的数,就让p1移动到mid的位置,指向数组2就让p2数组移动到mid的位置;直到p2移动到数组1的结束的位置,p1移动到数组2的开始的位置,此时p2与p1挨着,而且p1所指向的数组2的起始位置中存放的就是最小数;(2)如果中间位置的数既等于p1位置数,又等于p2位置的数,这时候,不能确定移哪个指针,就必须采用顺序查找的方法来寻找最小数; 总结:此题就是利用两个指针,一个往后移,一个往前移,具体怎么移,通过mid的大小控制;直到两个指针的位置挨着,就可以找到最小数了!还需要考虑:如果数组取0个放在了数组的后面,也就是排序数组没有变,这时p1指向的数小于p2指向的数;直接是数组的首元素是最小的数;[java] view plain copyimport java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array)
{
if(array == null || array.length == 0)
{
return 0;
}
int p1 = 0;//从前往后走
int p2 = array.length-1;//从后往前走
int min = array[p1];//如果没发生旋转,直接将array[0]的值返回,
int mid = 0;
//当数组发生旋转了,
while(array[p1] >= array[p2])
{
//当两个指针走到挨着的位置时,p2就是最小数了
if(p2 - p1 == 1)
{
min = array[p2];
break;
}
mid = (p1 + p2)/2;
//如果中间位置的数既等于p1位置的数又等于P2位置的数
if(array[p1] == array[mid]&&array[p2]==array[mid])
{
min = minInorder(array,p1,p2);
}
if(array[p1] <= array[mid])//若中间位置的数位于数组1,让p1走到mid的位置
{
p1 = mid;
}
else if(array[p2] >= array[mid])//若中间位置的数位于数组2,让p2走到mid的位置
{
p2 = mid;
}
}
return min;
}
private int minInorder(int[]array,int p1,int p2)
{
int min = array[p1];
for (int i = p1 + 1; i <= p2; i++)
{
if(min > array[i])
{
min = array[i];
}
}
return min;
}
}
输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。如果直接遍历数组,时间复杂度为O(n),可以利用旋转数组的特性来解决此题;思路:(1)如果发生旋转,前面的数至少去了一个放在数组的后面; 1)旋转后,数组分为两个排序数组,而且前一个数组中的数均大于等于后一个数组中的数,因为要查找数组中的最小数,也就是第二个数组中的第一个数,可以采用二分查找的思想;2)设置两个指针p1,p2,p1指向数组的开始位置,也就是第一个数组的开始位置,p2指向数组的终止位置,也就是第二个数组的结束位置。Mid=p1+p2/2; 如果中间位置mid的数大于p1指向的数,则mid在第一个数组中,让p1指向mid所指向的数,p1指向的依然是数组1的数; 如果中间位置mid的数小于p2所指向的位置,则mid在第二个数组中,p2指向mid指向的数,p2指向的依然是数组2的数;Mid不是指向数组1的数,就是指向数组2的数,指向数组1的数,就让p1移动到mid的位置,指向数组2就让p2数组移动到mid的位置;直到p2移动到数组1的结束的位置,p1移动到数组2的开始的位置,此时p2与p1挨着,而且p1所指向的数组2的起始位置中存放的就是最小数;(2)如果中间位置的数既等于p1位置数,又等于p2位置的数,这时候,不能确定移哪个指针,就必须采用顺序查找的方法来寻找最小数; 总结:此题就是利用两个指针,一个往后移,一个往前移,具体怎么移,通过mid的大小控制;直到两个指针的位置挨着,就可以找到最小数了!还需要考虑:如果数组取0个放在了数组的后面,也就是排序数组没有变,这时p1指向的数小于p2指向的数;直接是数组的首元素是最小的数;[java] view plain copyimport java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array)
{
if(array == null || array.length == 0)
{
return 0;
}
int p1 = 0;//从前往后走
int p2 = array.length-1;//从后往前走
int min = array[p1];//如果没发生旋转,直接将array[0]的值返回,
int mid = 0;
//当数组发生旋转了,
while(array[p1] >= array[p2])
{
//当两个指针走到挨着的位置时,p2就是最小数了
if(p2 - p1 == 1)
{
min = array[p2];
break;
}
mid = (p1 + p2)/2;
//如果中间位置的数既等于p1位置的数又等于P2位置的数
if(array[p1] == array[mid]&&array[p2]==array[mid])
{
min = minInorder(array,p1,p2);
}
if(array[p1] <= array[mid])//若中间位置的数位于数组1,让p1走到mid的位置
{
p1 = mid;
}
else if(array[p2] >= array[mid])//若中间位置的数位于数组2,让p2走到mid的位置
{
p2 = mid;
}
}
return min;
}
private int minInorder(int[]array,int p1,int p2)
{
int min = array[p1];
for (int i = p1 + 1; i <= p2; i++)
{
if(min > array[i])
{
min = array[i];
}
}
return min;
}
}
相关文章推荐
- 剑指offer---旋转数组的最小数字
- 剑指offer之旋转数组的最小数字
- 剑指offer-旋转数组的最小数字-二分查找法
- 剑指offer 旋转数组的最小数字
- 【剑指offer】面试题8:旋转数组的最小数字
- 剑指Offer之 - 旋转数组的最小数字
- [牛客网,剑指offer,python] 旋转数组的最小数字
- (C++)剑指offer-6:旋转数组的最小数字
- 剑指offer-8 旋转数组的最小数字
- 剑指offer第8题:旋转数组的最小数字
- 剑指offer 旋转数组的最小数字
- [剑指offer]旋转数组的最小数字
- 剑指Offer的旋转数组的最小数字问题是要二分法解决
- 剑指Offer--008-旋转数组的最小数字
- 剑指offer-旋转数组的最小数字
- 剑指offer面试题8:旋转数组的最小数字
- 剑指offer面试题[8]-旋转数组的最小数字
- 剑指offer 6 旋转数组的最小数字
- 剑指offer-----旋转数组的最小数字
- 【剑指Offer面试编程题】题目1386:旋转数组的最小数字--九度OJ