算法--最大值减去最小值小于或者等于num的子数组数量

package algorithm;

import java.util.LinkedList;

/**
 * 程序员代码代码面试指南:最大值减去最小值小于或者等于num的子数组数量
 * 1.变量
 * qmax:LinkedList<Integer>,用来实现子数组的最大值,队头为当前子数组的最大值
 * qmin:LinkedList<Integer>,用来实现子数组的最小值,队头为当前子数组的最小值
 * result:int,统计符合条件的子数组数量
 * 2.对输入进行校验
 * arr不为空,且长度大于0
 * 3.双重遍历
 * i,j为arr数组下标,i=0,j=i
 * j向右移动,到数组尽头完成一次遍历,j++,j<arr.length
 * i向右移动,i++,j再进行一次遍历
 * i移动到数组尽头,遍历结束,i<arr.length
 * 4.数组下标入队
 * 入队的下标为j
 * j进入qmax之前先进行循环判断,如果队尾元素小于或者等于arr[j],则要先弹出,直到没有比他小的元素再入队:!qmax.isEmpty()&&qmax.peekLast()<=arr[j]
 * j进入qmin之前先 进行循环判断,如果队尾元素大于或者等于arr[j],则要先弹出,直到没有比他大的元素再入队:!qmin.isEmpty()&&qmin.peekLast()>=arr[j]
 * 5.统计符合条件的子数组数量
 * 判断qmax和qmin的队头元素是否满足条件,满足则result++:qmax.peekFirst() - qmin.peekFirst() <= num
 * 6.清除无效下标
 * 如果队头元素不在范围就出队:qmax.peekFirst() < i || qmax.peekFirst() > j,qmin.peekFirst() < i || qmin.peekFirst() > j
 */
public class SubarrayNum {
    /**
     * 最大值减去最小值小于或者等于num的子数组数量
     * @param arr 原数组
     * @param num 要比较的值
     * @return 符合条件的字数组数量
     */
    public static int getNum(int[] arr, int num) {
        LinkedList<Integer> qmax = new LinkedList<>();
        LinkedList<Integer> qmin = new LinkedList<>();
        int result = 0;
        if (arr.length == 0 || arr == null) {
            return 0;
        }
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j < arr.length; j++) {
                while (!qmax.isEmpty() && qmax.peekLast() <= arr[j]) {
                    qmax.pollLast();
                }
                qmax.addLast(j);
                while (!qmin.isEmpty() && qmin.peekLast() >= arr[j]) {
                    qmin.pollLast();
                }
                qmin.addLast(j);
                if (qmax.peekFirst() - qmin.peekFirst() <= num) {
                    result++;
                }
                if (qmax.peekFirst() < i || qmax.peekFirst() > j) {
                    qmax.pollFirst();
                }
                if (qmin.peekFirst() < i || qmin.peekFirst() > j) {
                    qmin.pollFirst();
                }
            }
        }
        return result;
    }

    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        int[] arr = {3, 5, 7, 8, 6, 2};
        System.out.println(getNum(arr, 5));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值