首页 > 试题广场 >

在有序旋转数组中找到最小值

[编程题]在有序旋转数组中找到最小值
  • 热度指数:1466 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
有序数组arr可能经过一次旋转处理,也可能没有,且arr可能存在重复的数。例如,有序数组[1, 2, 3, 4, 5, 6, 7],可以旋转处理成[4, 5, 6,  7, 1, 2, 3]等。给定一个可能旋转过的有序数组arr,返回arr中的最小值。
[要求]
期望复杂度为

输入描述:
第一行一个整数N表示数组大小。
接下来N个数表示数组内的数。


输出描述:
输出一个整数表示答案
示例1

输入

7
1 2 3 4 5 6 7

输出

1
示例2

输入

7
4 5 6 7 1 2 3

输出

1

备注:

import java.util.Scanner;

public class Main {
    public static int find(int p, int r, int n, int arr[]) {
        while (p <= r) {
            int mid = p + (r - p) / 2;
            if (arr[p] <= arr[mid] && arr[mid] <= arr[r]) {
                return (arr[p] <= arr[mid + 1] ? arr[p] : arr[mid + 1]);
            } else if (arr[p] <= arr[mid]) {
                p = mid + 1;
            } else if (arr[mid] <= arr[r]) {
                r = mid - 1;
            }
        }
        return 0;
    }

    public static void main(String[] args) {
        int n = 0;
        int arr[] = new int[10000000];
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
        System.out.println(find(0, n - 1, n, arr));
    }
}

发表于 2020-04-05 22:23:52 回复(1)
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n, x, Min=INT_MAX;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>x;
        Min = min(Min, x);
    }
    cout<<Min<<endl;
    return 0;
}

发表于 2020-03-27 23:52:14 回复(0)
二分法
(1) 如果左端点比右端点的元素小,待考察的arr[left:right]子数组是有序的,直接返回arr[left];
(2) 如果中点元素比右端点大,说明进行过旋转,左半部分是有序的,最小值应该在右半部分,left=mid+1
(3) 如果中点元素小于等于右端点元素,旋没旋转过都有可能,但不管是否旋转过,右边都是有序的,最小值应该在包括中点的左半部分right=mid
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        String[] strArr = br.readLine().trim().split(" ");
        int[] arr = new int[n];
        for(int i = 0; i < n; i++) arr[i] = Integer.parseInt(strArr[i]);
        int left = 0, right = n - 1;
        while(left < right) {
            if(arr[left] < arr[right]) break;
            int mid = left + (right - left) / 2;
            if(arr[mid] > arr[right]){
                left = mid + 1;
            }else
                right = mid;
        }
        System.out.println(arr[left]);
    }
}

发表于 2021-06-16 10:25:49 回复(0)
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    while(cin>>n)
    {
        vector<int> vc(n+1,0);
        for(int i=0;i<n;i++)
        {
            cin>>vc[i];
        }
        int low=0,high=n-1,mid=0;
        while(low<high)
        {
            if(vc[low]<vc[high])
            {//这里是严格升序,所以直接可以返回,每次是在low-high这个范围里找最小值
                break;
            }
            mid=(low+high)/2;
            if(vc[low]<=vc[mid])// 2 2 2 2 1 2
            {//说明vc[low -mid]这一段是非降序的,表明min不在这里
                low=mid+1;
            }
            else
            {//vc[low] > vc[mid],最小值肯定在  low - mid范围内
                high=mid;
            }
        }
        cout<<vc[low]<<endl;
    }
    return 0;
}

发表于 2021-03-31 16:30:38 回复(0)
import java.util.Scanner;
import java.util.Arrays;

public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int[] arr=new int[n];
        for(int i=0;i<n;i++){
            arr[i]=sc.nextInt();
        }
        Arrays.sort(arr);
        System.out.print(arr[0]);
    }
}

发表于 2021-03-25 11:02:53 回复(0)
int findMinimumInRotatedSortedArray(const vector& arr) {
    if (arr.size() == 1) return arr[0];
    int L = 0, R = arr.size()-1;
    while (L <= R) {
        if (arr[R] >= arr[L]) return arr[L];
        int mid = (L + R) / 2;
        if (mid + 1 <= R && arr[mid+1] < arr[mid])
            return arr[mid+1];
        if (mid - 1 >= L && arr[mid-1] > arr[mid])
            return arr[mid];
        if (arr[mid] > arr[L])
            L = mid+1;
        else
            R = mid-1;
    }
    return arr[L];
}

测资好像不是很足够,上面的代码可以通过,试试[3, 1, 3]發现答案不是正确的

编辑于 2021-03-15 01:52:40 回复(0)
public class Main {
 public static void main(String[] args) {
  Scanner in = new Scanner(System.in);
  String num_and_len = in.nextLine();
  int num = Integer.valueOf(num_and_len);
  int[] score = new int[num];
  String aString = in.nextLine();
  aString=aString.replace("  ", " ");
  String[] a = aString.split(" ");
  for (int i = 0; i < a.length; i++) {
   score[i] = Integer.parseInt(a[i]);
  }
  System.out.println(find_min(score, 1, a.length));
 }
 public static int find_min(int[] a,int start,int end) {
  if(a[start-1]<a[end-1])
  {return a[start-1];}
  if(start==end) {
   return a[start-1];
  }
  else {
   int mid=(start+end)/2;
   return Math.min(find_min(a, start, mid), find_min(a, mid+1,end ));
  }
  
  
 }
}
发表于 2020-02-17 21:51:27 回复(0)

二分思路,每次去除一半的数据

n = int(input())
l = list(map(int, input().split()))
left, right = 0, n-1
while left < right:
    if l[left] < l[right]:
        break
    mid = (left + right) >> 1
    if l[mid] > l[right]:
        left = mid+1
    else:
        right = mid
print(l[left])
发表于 2019-08-16 10:19:30 回复(0)

问题信息

上传者:小小
难度:
8条回答 2901浏览

热门推荐

通过挑战的用户

查看代码