PREV-7连号区间数(Java)详解

PREV-7连号区间数(Java)详解

前言

读了半天题,没明白啥是连号区间,又没一个样例,后来才知道,拿第一个输入样例来说,[1,1],[1,2],[1,3],[1,4],[2,2],[3,3],[4,4]这7个就叫连号区间,分别对应的是[3],[3,2],[3,2,4],[3,2,1,4],[2],[4],[1].可能是语文水平太差了.下面给出两份代码,一份是自己的想法只能得80分,一份是蓝桥真题讲解视频中的.

问题描述

小明这些天一直在思考这样一个奇怪而有趣的问题:

在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:

如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。

当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就不是那么简单了,现在小明需要你的帮助。

输入格式

第一行是一个正整数N (1 <= N <= 50000), 表示全排列的规模。

第二行是N个不同的数字Pi(1 <= Pi <= N), 表示这N个数字的某一全排列。

输出格式

输出一个整数,表示不同连号区间的数目。

样例输入1

4
3 2 4 1

样例输出1

7

样例输入2

5
3 4 2 5 1

样例输出2

9 

代码1(自己的想法,只能得80分)

import java.util.Arrays;
import java.util.Scanner;
//想法是将每个区间取到新的数组里继续判断是不是连号区间
public class PREV_7 {

	/**
	 * @param args
	 */
	static int answer=0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int num[]=new int[n];
		for(int i=0;i<n;i++){
			num[i]=sc.nextInt();
		}
		for(int i=0;i<n;i++){//新数组的第一个数,即左区间对应的数字
			int  j=1;//其中最少也要有一个数
			while(j<=n-i){//j最大不能超过数组中的剩余数
			  solve(num,j,i);
			  j++;
			}
		}
		System.out.println(answer);
	}
	/*
	 * num[]原始数组,用于从中取数据到新数组
	 * count新数组的大小,从原始数组中提取数据的次数
	 * n开始提取的下标
	 */
	private static void solve(int []num,int count,int n){
		int m[]=new int [count];
		for(int i=0,j=n;i<count;i++){
			m[i]=num[j];//将原始数组中的数,转移到新数组中,便于判断给区间是不是连号区间
		}
		Arrays.sort(m);
		if(m[m.length-1]-m[0]==count-1)//满足题意的递增序列一定是最大数减最小值等于区间中个数减1
			answer++;
			return ;
	}

}

代码2(能够AC)

import java.util.Scanner;

public class PREV_7 {

	/**
	 * @param args
	 */
	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int num[]=new int[n+1];
		for(int i=1;i<=n;i++){
			num[i]=sc.nextInt();
		}
		int answer=0;
		for(int i=1;i<=n;i++){//左区间
			int max=num[i];
			int min=num[i];
			for(int j=i;j<=n;j++){//右区间
				//循环结束后,max是该区间的最大值,min是该区间的最小值
				if(num[j]>max)max=num[j];
				if(num[j]<min)min=num[j];
				if(i==j){//区间中只有一个数的时候
					answer++;
				}else{//j>i
					if(max-min==j-i)answer++;//满足题意的递增序列一定是最大数减最小值等于右区间的下标数-左区间的下标数
				}
			}
		}
		System.out.println(answer);
	}
}
	

总结

自己的思维还是太局限了,既比人家的麻烦又不能全部通过,最后一个很大的数,就运行超时了,还是太菜了.呜呜呜

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值