首页 > 试题广场 >

在数组中找到一个局部最小的位置

[编程题]在数组中找到一个局部最小的位置
  • 热度指数:2123 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
定义局部最小的概念。arr长度为1时,arr[0]是局部最小。arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]是局部最小;如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小;如果0<i<N-1,既有arr[i]<arr[i-1],又有arr[i]<arr[i+1],那么arr[i]是局部最小。
给定无序数组arr,已知arr中任意两个相邻的数不相等。写一个函数,只需返回arr中任意一个局部最小出现的位置即可
[要求]
时间复杂度为,空间复杂度为


输入描述:
第一行有一个整数N。标书数组长度
接下来一行,每行N个整数表示数组中的数


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

输入

3
2 1 3

输出

1

说明

因为arr[0] > arr[1] 且 arr[1] < arr[2],因此1是一个合法答案
示例2

输入

1
1

输出

0

备注:

#include<iostream>
(720)#include<algorithm>

using namespace std;

int main(){
    int n;
    cin>>n;
    if(n == 1 ){
        cout<<0<<endl;
        return 0;
    }
    int inp[n];
    for(int i = 0; i < n; i++){
        scanf("%d",&inp[i]);
    }
    if(inp[0] < inp[1]){
        cout<<0<<endl;
        return 0;
    }
    else if(inp[n - 1] < inp[n - 2]){
        cout<<n - 1<<endl;
        return 0;
    }
    int left = 1, right = n - 2;
    while(left < right){
        int mid = (left + right) / 2;
        if(inp[mid] > inp[mid - 1]){
            right  = mid - 1;
        }
        else if(inp[mid] > inp[mid + 1]){
            left = mid + 1;
        }
        else{
            cout<<mid<<endl;
            return 0;
        }
    }
    cout<<left<<endl;
    return 0;
}

发表于 2020-05-02 10:45:00 回复(0)
二分查找
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 = 1, right = n - 2;
        while(left < right){
            int mid = left + (right - left) / 2;
            if(arr[mid] > arr[mid - 1]){
                right  = mid - 1;
            }else if(arr[mid] > arr[mid + 1]){
                left = mid + 1;
            }else{
                System.out.println(mid);
                return;
            }
        }
        System.out.println(left);
    }
}

发表于 2021-06-22 19:38:05 回复(0)
#include<bits/stdc++.h>
using namespace std;
//求波谷
int findMixNum(vector<int>& arr) {
    if (arr.size()< 2) return 0;
    int l = 0, r = arr.size() - 1;
    while (l < r) {
        int mid = (r - l) / 2 + l;
        if (arr[mid] < arr[mid + 1]) {
            r = mid;
        }
        else {
            l = mid + 1;
        }
    }
    return l;
}
int main() {
    int n;
    cin >> n;
    vector<int> arr(n, 0);
    for (int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    cout << findMixNum(arr);
    return 0;
}





#include<bits/stdc++.h>
using namespace std;
//求波谷
int findMixNum(vector<int>& arr) {
    if (arr.size()< 2) return 0;
    int l = 0, r = arr.size() - 1;
    while (l < r) {
        int mid = (r + l + 1) / 2;
        if (arr[mid] < arr[mid - 1]) {
            l = mid;
        }
        else {
            r = mid - 1;
        }
    }
    return l;
}
int main() {
    int n;
    cin >> n;
    vector<int> arr(n, 0);
    for (int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    cout << findMixNum(arr);
    return 0;
}



编辑于 2020-08-28 11:04:59 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin>>n;
    int a[n], l=0, r=n-1;
    for(int i=0;i<n;i++)
        cin>>a[i];
    if(n==1)
        cout<<0<<endl;
    else{
        if(a[n-1]<a[n-2])
            cout<<n-1<<endl;
        else if(a[0]<a[1])
            cout<<0<<endl;
        else{
            while(l<=r){
                int m = (l+r)>>1;
                if(a[m]<a[m-1] && a[m]<a[m+1]){
                    cout<<m<<endl;
                    break;
                }else if(a[m]>a[m-1])
                    r = m-1;
                else
                    l = m+1;
            }
        }
    }
    return 0;
}

发表于 2020-02-19 00:38:14 回复(0)
int main(){

    // freopen("input.txt","r",stdin); 
    int n;
    scanf("%d", &n);
    int arr[n];
    for(int i = 0; i < n; i++){
        scanf("%d", &arr[i]);
    }
    if(n == 1){
        cout << 0 << endl;
        return 0;
    } else {
        if(arr[n-1] < arr[n-2]){
            cout << n-1 <<endl;
            return 0;
        } 
        if(arr[0] < arr[1]){
            cout << 0 << endl;
        }
    }

    int l = 0, r = n-1;
    while(l <= r){
        int mid = int((l + r) / 2);
        if(arr[mid-1] > arr[mid] && arr[mid+1] > arr[mid]){
            cout << mid << endl;
            return 0;
        } else if(arr[mid-1] < arr[mid]){
            r = mid-1;
        } else {
            l = mid+1;
        }
    }

    return EXIT_SUCCESS;
}
往负梯度的方向进行二分查找
发表于 2019-11-15 17:08:38 回复(0)
利用元素与相邻元素的关系可以进行二分查找
# include <bits/stdc++.h>

using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<int> nums(n);
    for(int i = 0; i < n; ++i) cin >> nums[i];
    
    int left = 0, right = n - 1;
    while(left <= right){
        int mid = left + right >> 1;
        // 当左相邻元素小于中间元素时,左侧区域必定存在局部最小值,可以排除右侧区域
        if(nums[mid - 1] < nums[mid]){
            right = mid - 1;
        }
        // 当右相邻元素小于于中间元素时,右侧区域必定存在局部最小值,可以排除左侧区域
        else if(nums[mid + 1] < nums[mid])  {
            left = mid + 1;
        }
        else {
            cout << mid;    // 注意是返回下标,不是返回元素
            return 0;
        }
    }
    return 0;
}


发表于 2022-04-10 10:08:31 回复(0)
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = in.nextInt();
        }
        int res = getLessIndex(arr);
        System.out.println(res);
    }
    public static int getLessIndex(int[] arr) {
        if (arr[0] < arr[1]) 
            return 0;
        if (arr[arr.length - 1] < arr[arr.length - 2])
            return arr.length - 1;
        int l = 1;
        int r = arr.length - 2;
        int mid = 0;
        while (l < r) {
            mid = (l + r) >> 1;
            if (arr[mid] > arr[mid - 1]) {
                r = mid + 1;
            } else if (arr[mid] > arr[mid + 1]) {
                l = mid + 1;
            } else {
                return mid;
            }  
        }
        return l;
    }
}

发表于 2021-08-14 02:34:08 回复(0)
import java.util.*;
public class Main {
    public static void main(String[]args){
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int[] arr = new int[N];
        for(int i =0; i < N;i++) {
            arr[i] = scan.nextInt();
        }
        System.out.println(partialMinPos(arr));
    }
    public static int partialMinPos(int[] arr) {
        if (arr == null || arr.length == 0) return -1;
        if (arr.length == 1 || arr[0] < arr[1]) return 0;
        if (arr[arr.length - 1] < arr[arr.length - 2]) return arr.length - 1;

        int l = 0;
        int r = arr.length - 1;

        while (l + 1 < r) {
            int mid = (l + r) / 2;
            if (arr[mid] > arr[mid - 1]) {
                r = mid;
            } else if (arr[mid] > arr[mid + 1]) {
                l = mid;
            } else {
                return mid;
            }
        }
        return -1;
    }
}

发表于 2021-06-11 10:52:17 回复(0)
#include<iostream>
#include<vector>
using namespace std;
int areamin(const vector<int> &v,int n);
int main()
{
    int n;
    while(cin>>n)
    {
        vector<int> v(n);
        for(int i=0;i<n;i++){
            cin>>v[i];
        }
        cout<<areamin(v,n)<<endl;
    }
    return 0;
}
int areamin(const vector<int> &v,int n)
{
    int i;
    if(v[0]<v[1])
        return 0;
    else if(v[n-1]<v[n-2])
        return n-1;
    else{
        for(i=1;i<n-1;i++){
            if(v[i]<v[i+1]&&v[i]<v[i-1])
            {
                return i;
            }
        }
    }
}
发表于 2020-07-21 17:59:13 回复(0)
public static int getLessIndex(int[] arr) {
    if (arr == null || arr.length == 0) {
        return -1; // no exist
    }
    if (arr.length == 1 || arr[0] < arr[1]) {
        return 0;
    }
    if (arr[arr.length - 1] < arr[arr.length - 2]) {
        return arr.length - 1;
    }
    int left = 1;
    int right = arr.length - 2;
    int mid = 0;
    while (left < right) {
        mid = (left + right) / 2;
        if (arr[mid] > arr[mid - 1]) {
            right = mid - 1;
        } else if (arr[mid] > arr[mid + 1]) {
            left = mid + 1;
        } else {
            return mid;
        }
    }
    return left;
}
发表于 2020-07-20 15:56:33 回复(1)
import java.io.*;
public class Main{
    public static void main(String[]args) throws IOException{
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        int n= Integer.valueOf(bf.readLine());
        String[] str = bf.readLine().split(" ");
        int[] arr = new int[n];
        for(int i=0; i<n; i++){
            arr[i] = Integer.valueOf(str[i]);
        }
        bf.close();
        
        int s = 0, e = n-1, m;
        while(s<e){
            m = (s+e)>>1;
            if(arr[m+1] < arr[m]){
                s = m+1;
            }else{
                e = m;
            }
        }
        System.out.println(s);
    }
}

发表于 2020-06-05 00:12:54 回复(0)
#include "stdio.h"
#include "stdlib.h"
#include "string.h"


int main()
{
    int arr[100861] = {0};
    int n, i, tmp = 0;

    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
        if ((i > 1) && (tmp == 0)) //如果0<i<n-1且还没找到局部最小
        {
            if ((arr[i - 1] < arr[i - 1 - 1]) && (arr[i - 1] < arr[i - 1 + 1]))
            {
                tmp = i - 1; //找到了局部最小
            }
        }
    }
    if ((n == 1) || (arr[0] < arr[1])) //arr的长度为1或arr[0]<arr[1]时局部最小是0
        printf("0\n");
    else if (arr[n - 1] < arr[n - 2]) //看看n-1是不是局部最小
        printf("%d\n", n - 1);
    else //如果0<i<n就输出上面找到的局部最小
        printf("%d\n", tmp);
    return 0;
}

发表于 2020-02-10 17:22:51 回复(0)
优化了大神的代码啊!不是我自己想到的。
发表于 2019-10-30 15:56:46 回复(0)
注意是返回局部最小的位置
N = eval(input())
ls = list(map(int, input().split()))
def local_Minimum(ls):
    if len(ls) == 1:
        return 0
    elif ls[0] < ls[1]:
        return 0
    elif ls[-1] < ls[-2]:
        return len(ls)-1
    else:
        for i in range(1, len(ls)-1): #因为i-1和i+1的存在,下标要从1开始,并且不能遍历到最后
            if ls[i] < ls[i-1] and ls[i] < ls[i+1]:
                return i
print(local_Minimum(ls))


发表于 2019-08-13 16:57:34 回复(1)

问题信息

上传者:小小
难度:
14条回答 4110浏览

热门推荐

通过挑战的用户

查看代码