首页 > 试题广场 >

找出函数的最宽尖峰

[问答题]

找出函数的最宽尖峰

题目描述按数组的形式给出函数f(x)的取值,即数组AA[0]元素为f(0)的取值,数组的取值都为整数,函数在每个点都是严格单调递增或者严格递减(即A[i-1] != A[i] != A[i+1]),要求找出最宽的先上升后下降的区间(这个区间内函数的值必须先上升到一个点然后下降,区间的上升段和下降段长度必须都大于0)。

1. 如果找到符合条件的最大区间输出数组对应的左右下标(保证只有一个最大区间)

2. 找不到那么输出-1 -1

输入格式

n

n长度的整数数组

输出格式

区间的范围

输入样例

10

1 3 1 2 5 4 3 1 9 10

输出样例

2 7

数据规模

对于 100% 的数据,1 <=n <=10, 000, 000

推荐
#include <bits/stdc++.h>
using namespace std;//预处理左右各做一遍最长上升子串, 然后维护一个最大和即可
int main() {
    int n;
    cin >> n;
    vector<int> x(n, 0);
    vector<int> l(n, 0);
    vector<int> r(n, 0);
    for(int i = 0; i < n; i++) scanf("%d", &x[i]);
    for(int i = 1; i < n; i++) {
        if(x[i] > x[i - 1]) {
            l[i] = l[i - 1] + 1;
        }
    }
    for(int i = n - 2; i >= 0; i--) {
        if(x[i] > x[i + 1]) {
            r[i] = r[i + 1] + 1;
        }
    }
    int mx = 0, ll = -1, rr = -1;
    for(int i = 0; i < n; i++) {
        if(l[i] > 0 && r[i] > 0 && l[i] + r[i] > mx) {
            mx = l[i] + r[i];
            ll = i - l[i];
            rr = i + r[i];
        }
    }
    cout << ll << " " << rr << endl;
    return 0;
}

编辑于 2017-07-28 16:53:00 回复(1)
 public static void main(String[] args) {
        //预处理左右各做一遍最长上升子串, 然后维护一个最大和即可
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] x = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = sc.nextInt();
        }
        int[] l = new int[n];
        for (int i = 1; i < n; i++) {
            if (x[i] - x[i - 1] > 0) {
                l[i] = l[i - 1] + 1;
            }
        }
        int[] r = new int[n];
        for (int i = n - 2; i >= 0; i--) {
            if (x[i] > x[i + 1]) {
                r[i] = r[i + 1] + 1;
            }
        }
        int mx = 0, ll = -1, rr = -1;
        for (int i = 0; i < n; i++) {
            if (l[i] > 0 && r[i] > 0 && l[i] + r[i] > mx) {
                mx = l[i] + r[i];
                ll = i - l[i];
                rr = i + r[i];
            }
        }
        System.out.print(ll + " " + rr);
    } 
发表于 2017-08-22 15:16:09 回复(0)
整的复杂了点:
public static void main(String[] args) {
        int[] arr = {1, 3, 1, 2, 1, 4, 3, 1, 9, 10};
        System.out.println(result(arr));
    }

    private static String result(int[] arr) {
        int start = -1;
        int end = -1;
        int s = -1;
        int s1 = -1;
        int s2 = -1;
        for (int i = 0; i < arr.length; i++) {
            start = i;
            if ((i + 1) < arr.length && arr[i] < arr[i + 1]) {
                for (int j = i + 1; j < arr.length; j++) {
                    if ((j + 1) < arr.length && arr[j] == arr[j + 1]) {
                        break;
                    } else if ((j + 1) < arr.length && arr[j] > arr[j + 1]) {
                        for (int k = j + 1; k < arr.length; k++) {
                            if ((k + 1) < arr.length && arr[k] == arr[k + 1]) {
                                break;
                            } else if ((k + 1) < arr.length && arr[k] < arr[k + 1]) {
                                end = k;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            if (start != -1 && end != -1) {
                if ((end - start) > s) {
                    s = end - start;
                    s1 = start;
                    s2 = end;
                }
            }
            end = -1;
        }
        return (s1 + "\t" + s2);
    }
测试结果:4    7
发表于 2019-09-09 01:09:34 回复(0)
#include<iostream>
#include<vector>

using namespace std;

int main()
{
    int n, i, num;
    vector<int> nums;

    cin >> n;
    for (i = 0; i < n; i++) {
        cin >> num;
        nums.push_back(num);
    }

    i = 0;
    int l = -1, r = -1; // 临时左右边界
    int left = -1, right = -1, max_len = -1; // 最终需要输出的最大左右边界和最大长度

    // 认为i是峰顶的下标,往左右两个方向找左右边界
    while (i < n) {
        if (l == -1) { // l == -1 表示左边界需要重新找
            l = i;
            while (l > 0 && nums[l - 1] < nums[l]) // 找左边界
                l--;
        }

        r = i;
        while (r < n - 1 && nums[r + 1] < nums[r]) // 找右边界
            r++;

        if (r > i && l < i && r - l + 1 > max_len) { // 更新最大值
            max_len = r - l + 1;
            left = l;
            right = r;
        }

        // r == i 表示没有右边界,还在上升阶段,下一个峰顶的左边界还是l,就不需要再找左边界了
        if (r != i)
            l = -1;
        i = r + 1; // 把i更新为下一个可能的峰顶
    }
    cout << left << " " << right << endl;

    return 0;
}

发表于 2020-06-03 00:30:37 回复(0)
muf头像 muf
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int n;
    cin>>n;
    vector<int> a(n);
    for(int i=0;i<n;++i)
    {
        cin>>a[i];
    }
    int max = 0;
    int left = 0;
    int right = 0;
    for(int i=0;i<n;++i)
    {
        if(i>0&&a[i]>a[i-1])
            continue;
        if(i<n-1&&a[i]>a[i+1])
            continue;
        int m = 0;
        int j=i;
        while(j<n-1&&a[j]<a[j+1])
        {
                ++j;
        }
        int k = j;
        while(k<n-1&&a[k]>a[k+1])
        {
            ++k;
        }
        if(k>j&&j>i)
        {
            m=k-i;
            if(m>max)
            {
                left = i;
                right =k;
            }
            i=k-1;
        }
        else
        {
            continue;
        }
    }
    cout<<left<<" "<<right<<endl;
    return 0;
}

发表于 2019-04-08 19:58:32 回复(0)
#include <iostream>
#include <vector>
#include <map>
#include <stack>
using namespace std;

struct Pos
{
    int iBegin;
    int iEnd;

    Pos(int i, int j)
    {
        iBegin = i;
        iEnd = j;
    }
};
typedef map<int, Pos> mapKey;

void GetWalve(vector<int> &vecIn, mapKey &mapOut)
{
    int i = 0;
    while (i < vecIn.size())
    {
        if (i + 1 < vecIn.size() && vecIn[i+1] <= vecIn[i])
        {
            i++;
            continue;
        }

        int iUpBegin = i;
        while (i + 1 < vecIn.size() && vecIn[i+1] > vecIn[i])
        {
            i++;
        }
        int iUpEnd = i;

        int iDownBegin = i;
        while (i + 1 < vecIn.size() && vecIn[i+1] < vecIn[i])
        {
            i++;
        }
        int iDownEnd = i;

        if (iDownEnd > iUpBegin && 
            iUpBegin != iUpEnd && 
            iDownBegin != iDownEnd)
        {
            Pos Ptemp = Pos(iUpBegin, iDownEnd) ;
            mapOut.insert(make_pair(iDownEnd - iUpBegin + 1, Ptemp));
            continue;
        }
        i++;
    }
    return;
}


int main()
{
    //int a[10] = {1,2,3,6,7,8,9,11,13,80};
    /*int a[10] = {10,9,8,7,6,5,4,3,2,1};*/
    //int a[10] = {10,3,8,7,6,5,4,3,2,1};
    //int a[10] = {3,8,7,11,5,4,3,2,1,0};
    //vector<int> vecIn;
    //vecIn.insert(vecIn.end(), a, a+10);

    vector<int> vecIn;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> vecIn[i];
    }

    mapKey mapCyy;
    GetWalve(vecIn, mapCyy);
    mapKey::iterator it = mapCyy.end();
    it--;
    cout << it->second.iBegin << " " << it->second.iEnd;
    return 0;
}
发表于 2018-03-22 16:59:18 回复(0)
#include<iostream>
#include <vector>
#include <map>

using namespace std;

typedef struct __tagNode
{
    int length;
    int index;
}Node;

int main()
{
    // 初始化输入
    int num;
    if(num<3)
    {
         cout << -1 << " " << -1 << endl;
         return 0;
     }
    vector<int>vecin;
    vecin.resize(num);
    for(int i=0; i<num; ++i)
    {
        cin >> vecin[i];  
    }
    map<int, int>m;
    int left = -1, right = -1;
    // 从左到右数区间上升
    int index= 0, length = 1;
    for(int i=1; i<num; ++i)
    {
        if(vecin[i]<=vecin[i-1])
        {
            if(length>1)
                     {
                            m[index] = length;
                     }                      left = i;
                    length = 1;  }
        else
        {
            ++index;
            ++length;
        }
    }
    // 从右向左数区间下降
    int max = -1;
    for(int i=num-2; i>=0; ++i)
    {
        if(vecin[i]<=vecin[i+1])
        {
            if(length>1)
                     {
                            if(!m[index] )
                            {
                                    index = i;
                                    length = 1;
                                    continue;
                            }
                            else
                            {
                                    if(length+m[index] > max)
                                    {
                                            left = index - m[index] + 1;
                                            right = index - length - 1;  }  }  } 
                     left = i;
                    length = 1;  }
        else
        {
            --index;
            ++length;
        }
}

cout << left << " " << right << endl;
return 0;
}

发表于 2017-09-05 09:00:02 回复(0)
#include <iostream> #include <vector> using namespace std; int main() { int n; cin >> n; vector<int> x(n,0); vector<int> l(n,0); vector<int> r(n,0); int res=0; int ll=-1, rr=-1; for(int i=0;i<n>>x[i]; } for(int i=1;i<n>x[i-1]) l[i]=l[i-1]+1; } for(int i=n-2;i>=0;i--) { if(x[i]>x[i-1]) r[i]=r[i+1]; } for(int i=0;i<n>0&&r[i]>0&&l[i]+r[i]>mx) { mx=l[i]+r[i]+1; ll=i-l[i]; rr=i+r[i]; } } cout<<ll><<" "<</ll></n></n></n></int></int></int></vector></iostream>
发表于 2017-09-01 14:39:30 回复(0)
#include<bits/stdc++.h>
using namespace std;
int main(){
  int n;
  cin>>n; 
  vector<int> Data;
  int temp;
  int num = n;
  while(num-->0){
    cin>>temp;
    Data.push_back(temp); 
  }
  int max = 1;//初始化序列的最大长度;
  int first, last;
  for(int i = 0; i < n; i++){
    bool up = false;
    bool down = false;
    int index = i + 1;
    while(index < n){
      if(Data[index] > Data[index-1] && (!down)){
        index++;
        if(!up)
          up = true;
      }
      else if(Data[index] < Data[index-1] && up){
        index++;
        if(!down)
          down = true;
      }
      else
        break;
    }
    if((index - i + 1) > max){
      max = index - i + 1;
      first = i;
      last = index;
  }
  if(max < 3)
    cout<<-1<<" "<<-1<<endl;
  else
    cout<< first<<" "<<last<<endl;
}
发表于 2017-08-22 17:34:42 回复(0)
#include <iostream>
#include <vector>
using namespace std;
int n;
int main(){
	while(cin >> n){
		vector<int> nums(n);
		for(int i = 0; i < n; i++) cin >> nums[i];
		int left = -1, right = -1, tmp_left = -1, tmp_right = -1, res = 0;
		for(int i = 1; i < n; ){
			tmp_left = i;
			while( i < n && nums[i] > nums[i-1]) i++;
			if(i == n) break;
			if(i == tmp_left){i++; continue;}
			i++;
			while(i < n && nums[i] < nums[i-1]) i++;
			cout << tmp_left << " " << i << endl;
			if(i - tmp_left + 1 > res){
				left = tmp_left - 1;
				right = i -1;
				res = i - tmp_left + 1;
			}
		}
		cout << left << " " << right << endl;
	}
	return 0;
}

发表于 2017-08-22 17:11:59 回复(0)
#include <iostream> #include <string> #include <vector> #include <algorithm>  using namespace std; int main(){ int n; while(cin>>n){ vector<int> v; for(int i=0;i<n;i++){ int a;
            cin>>a;
            v.push_back(a);
        } bool flag = false; int cur=0;int max=0; int left=0,right=0; for(int i=1;i<n-1;i++){ if(flag){ if(v[i]<v[i-1]&&v[i+1]>v[i]){ if((i-cur)>max){
                        max=i-cur;
                        left=cur;
                        right=i;
                    }
                    cur=i;
                }
            }else{ if(v[i]>v[i-1]){
                    flag=true;
                    cur=i-1;
                }
            }
        } if(v[n-1]<v[n-2]){ if((n-1-cur)>max){
                left=cur;
                right=n-1;
            }
        }
        cout<<left<<" "<<right<<endl;
    } return 0;
}

发表于 2017-08-22 14:49:53 回复(0)


import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main{
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        List<Integer> list=new ArrayList<Integer>();
        while (list.size()<n) {
            list.add(scanner.nextInt());            
        }

        //找出波谷
         List<Integer> mins=new ArrayList<Integer>();
            for (int i = 1; i < list.size()-1; i++) {
                if (list.get(i)<list.get(i+1)&&list.get(i)<list.get(i-1)) {
                    mins.add(i);
                }
            }
            if (mins.size()<2) {
                System.out.println(-1+" "+-1);
                return;
            }
            //相邻波谷的距离
            int l=0;
        for (int i = 1; i < mins.size()-1; i++) {
            int temp=0;
            if ((mins.get(i)-mins.get(i-1))<(mins.get(i+1)-mins.get(i))) {
                temp=mins.get(i+1)-mins.get(i);
            }
            l=i;
        }
        System.out.println(mins.get(l)+" "+mins.get(l+1));
        
    }

}

发表于 2017-08-01 11:12:43 回复(0)
import java.util.ArrayList; import java.util.Scanner;  public class Main {   public static void main(String[] args) {  // write your code here  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 flag = 0;  int[] result = new int[2];  if (n==1){  result[0] = -1;  result[1] = -1;  }  for (int i=0; i<n-1; i++){  if (arr[i+1]-arr[i]>0)  flag++;  }  if (flag==0 || flag==n-1){  result[0] = -1;  result[1] = -1;  }else {  ArrayList<Integer> list = new ArrayList<Integer>();  if (arr[0]<arr[1]){  list.add(0);  }  for (int i=1; i<n-1; i++){  if (arr[i-1]>arr[i] && arr[i+1]>arr[i])  list.add(i);  }  int max=0;  for (int i=0; i<list.size()-1; i++){  if ((list.get(i+1)-list.get(i))>max){  max = list.get(i+1)-list.get(i);  result[0] = list.get(i);  result[1] = list.get(i+1);  }   }  }    System.out.println(result[0] + " " + result[1]);  } }
发表于 2017-07-31 21:59:41 回复(0)