南大高级算法作业之子数组的取值范围

input:

1

3 6 4 3 2

3

output:

2

  本题的解题思路还是从简化整个流程入手,想要得到复杂度为N的算法,显然需要用到滑动窗口,仔细分析一下该题,其实想得到满足条件的连续子数组有以下两个规律:1.当[i,j]满足要求时,[i,j+1]必然满足要求;2.当[i,j]不满足要求时,[i-1,j]和[i,j-1]也同样不满足要求,所以窗口可以一直往前走,不需要回头。

  所以大致的逻辑是:以i=0开头,j递增向后寻找满足条件的连续子数组,找到后就不需要再移动j,因为往后走的每个数组都会满足条件;这个时候移动i,如果i不满足条件,那么就不用再移动i,因为上面的规律告诉我们不移动j不可能再出现极差大于给定值的数组。

  需要注意的细节是,队列内保存的应该是对应原数组中的序号,以便于我们判断i移动过程中最大最小队列里的值是否应该被移出去,其次我们需要在i开始移动时候增加判定来固定住j,最后就是注意i不能超过j。

代码:

import java.util.*;

public class Main {
	
	public static void main(String[] args) {
    	
    	Scanner scan = new Scanner(System.in);
		
		int e_num = Integer.parseInt(scan.nextLine());//测试数
		
		while(e_num>0){
			
			String num[] = scan.nextLine().split(" ");//目标数组
			
			int target = Integer.parseInt(scan.nextLine());//目标数
			
			int total = 0;
			
			LinkedList<Integer> max = new LinkedList<Integer>();//存放最大值的队
			
			LinkedList<Integer> min = new LinkedList<Integer>();//存放最小值的队
			
			int i = 0;//i代表窗口前端
			
			int j = 0;//j代表窗口后端
	
			while(i < num.length){//从以i为首的连续数组开始找
				
				if( !min.isEmpty() && !max.isEmpty() && (i < j) &&(Integer.parseInt(num[max.peekFirst()]))-(Integer.parseInt(num[min.peekFirst()])) > target){
					
					total += num.length - j + 1;
					
				}else{
				
					while(j < num.length){
						
						while(!min.isEmpty() && Integer.parseInt(num[j])<Integer.parseInt(num[min.peekLast()])){
						
							min.pollLast();
						
						}
							
						min.addLast(j);
					
						while(!max.isEmpty() && Integer.parseInt(num[j])>Integer.parseInt(num[max.peekLast()])){
							
							max.pollLast();
						
						}
							
						max.addLast(j);
						
						j ++;
						
						if((Integer.parseInt(num[max.peekFirst()]))-(Integer.parseInt(num[min.peekFirst()])) > target){
							
							total += num.length - j + 1;
							
							break;
							
						}
							
					}
				
				}
					
				if(max.peekFirst() == i){
					
					max.pollFirst();
					
				}
				
				if(min.peekFirst() == i){
					
					min.pollFirst();
					
				}
				
				i ++;
				
				
					
			}
			
			System.out.println(total);
				
			e_num --;
		
			}
    
		}
    
	}
发布了36 篇原创文章 · 获赞 2 · 访问量 2020

猜你喜欢

转载自blog.csdn.net/fumonster/article/details/102536746
今日推荐