旋转数组的最小值

编程入门 行业动态 更新时间:2024-10-24 04:40:51

旋转<a href=https://www.elefans.com/category/jswz/34/1771288.html style=数组的最小值"/>

旋转数组的最小值

文章目录

  • 1 题目
  • 2 思路
    • 2.1 思路1
    • 2.2 思路2
  • 3 实现
    • 3.1 暴力
    • 3.2 二分查找

1 题目

将一个数组最开始的若干元素搬到数组的末尾,称之为数组的旋转。输入一个已排好序数组的一个旋转,求该旋转数组的最小元素。如,数组{3,4,,5,1,2}为有序数组{1,2,3,4,5}的一个旋转数组,该数组的最小值为1。

2 思路

2.1 思路1

暴力遍历数组,求出数组的最小元素。

时间复杂度:O(n)
空间复杂度:O(1)

2.2 思路2

将旋转后的数组看成两个升序的子序列,即查找一个元素(使用二分查找法),满足的条件为比相邻左边的元素小,也比相邻右边的元素小(如果存在的话)。

算法1详细(方便理解):

  • 用l指针指向第一个序列的第一个元素,用r指针指向第二个序列的最后一个元素;
    • 当l = mid时,r为最小元素(特殊处理当最小元素位于末尾的情况),例如{2,3,4,5,1},此时最小元素为r指向的元素,而不是mid指向的元素;
    • 当元素满足比左边元素小,比右边元素小时,即为最小元素;
    • 如果中间指针mid((l+r)/2)在第一个序列中(即A[mid] < A[l]),则要寻找的元素在后半段中,把l改为mid;
    • 如果中间指针mid第二个序列中(即A[mid]<A[r]),则要寻找的元素在前半中;
  • 当l=r时,返回最小元素A[r];否则,返回最小元素A[mid]。

算法2详细(上一种算法的改进版本):

  • 用l指针指向第一个序列的第一个元素,用r指针指向第二个序列的最后一个元素;
    • 如果中间指针mid((l+r)/2)在第一个序列中(即A[mid] < A[l]),则要寻找的元素在后半段中,把l改为mid;
    • 如果中间指针mid第二个序列中(即A[mid]<A[r]),则要寻找的元素在前半中。
  • 当l和r相邻时(此时mid=l),最小元素在r指向的元素。

时间复杂度:O(logn)
空间复杂度:O(1)

例如:原数组{1,2,3,4,5},
旋转后的数组{2,3,4,5,1},1比左边的5小,无右边的元素;
旋转后的数组{3,4,5,1,2},1比左边的5小,比右边2小;
旋转后的数组{4,5,1,2,3},1比左边的5小,比右边2小。

3 实现

3.1 暴力

#include<cstdio>int solution(int *A, int n){int ans = A[0];for(int i = 1;i < n;i++)if(A[i] < ans) ans = A[i];return ans;
}int main(){int A[] = {2,3,4,5,1};//int A[] = {3,4,5,1,2};//int A[] = {4,5,1,2,3};//int A[] = {5,1,2,3,4};printf("%d", solution(A, sizeof(A)/sizeof(A[0])));return 0;
}

3.2 二分查找

#include<cstdio>int solution(int *A, int n){int l = 0, r = n - 1, mid;while(l <= r){mid = (l + r)/2;printf("值   %d %d %d \n", A[l], A[mid], A[r]);printf("序号 %d %d %d \n", l, mid, r);//特殊处理最小元素位于最后一个的情况,例如2,3,4,5,1的情况,此时mid=l=3,r=4if(l == mid && A[r] < A[mid]) break;//如果比左边相邻的元素小//同时也比右边相邻的元素小(如果右边元素不存在,则和自己比较)if((A[mid] < A[mid-1] && A[mid] <= A[mid+1])) break;if(A[mid] < A[r]) r = mid;else l = mid;}return (l == mid)?A[mid+1]:A[mid];
}int solution2(int *A, int n){int l = 0, r = n - 1, mid;while(A[l] >= A[r]){if(r -l ==1){mid = r;break;}mid = (l + r)/2;printf("值   %d %d %d \n", A[l], A[mid], A[r]);printf("序号 %d %d %d \n", l, mid, r);if(A[mid] < A[r]) r = mid;else l = mid;}return A[mid];
}int main(){int A[] = {2,3,4,5,1};//int A[] = {3,4,5,1,2};//int A[] = {4,5,1,2,3};//int A[] = {5,1,2,3,4};printf("%d", solution(A, sizeof(A)/sizeof(A[0])));return 0;
}

更多推荐

旋转数组的最小值

本文发布于:2023-12-04 01:11:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1659319.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数组   最小值

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!