zoukankan      html  css  js  c++  java
  • 5402.绝对差不超过限制的最长数组

    image-20200503153922126

    image-20200503154005093

    思路1

    思路

    • 既然每个数字都要做开头 双重for循环 O(n^2)

    • 当开头的数字确定时,向后遍历

    • 在每一次向后遍历过程中,动态更新数列中的min和max,同时引用count计数器

    • 验证max-min的绝对差 与 limit 的关系

    • 将符合结果的count 装入集合list

    • 对集合list进行sort排序,取最大值

    • 结果 超出内存限制 时间就更不用提了

    代码

    /**
         * 绝对差不超过限制的最长连续子数组
         *
         * 给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,
         * 该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。
         * 如果不存在满足条件的子数组,则返回 0 。
         *
         *  
         * 53/54  超出内存时间限制
         * @param nums
         * @param limit
         * @return
         */
        public int longestSubarray(int[] nums, int limit) {
            List<Integer> list=new ArrayList<>();
            for(int i=0;i<nums.length;i++){
                int min=nums[i];
                int max=nums[i];
                int subMax=0;
                int count=0;
                for(int j=i;j<nums.length;j++){
                    min=Math.min(min,nums[j]);
                    max=Math.max(max, nums[j]);
                    subMax=Math.max(subMax, max-min);
                    if(subMax<=limit){
                        count++;
                    }else{
                        list.add(count);
                        break;
                    }
                    list.add(count);
                }
            }
            Collections.sort(list);
            return list.get(list.size()-1);
        }
    
    

    优化思路1

    思路

    • O(n^2)肯定需要降下来 ,当时想到滑动窗口 ,但用不熟
    • 没有必要使用集合list来保存各种结果,题目要求最大数组长,取个常量保存即可,在每次遍历中Math.max()方法比较集合
    • 结果 空间没超 时间依旧超出限制
    • 所以O(n^2)一定要降下来

    代码

    /*
    *超出时间限制
    **/
    public int longestSubarray2(int[] nums, int limit) {
            int ans=0;
            for(int i=0;i<nums.length;i++){
                int min=nums[i];
                int max=nums[i];
                int subMax=0;
                int count=0;
                for(int j=i;j<nums.length;j++){
                    min=Math.min(min,nums[j]);
                    max=Math.max(max, nums[j]);
                    subMax=Math.max(subMax, max-min);
                    if(subMax<=limit){
                        count++;
                    }else{
                        ans=Math.max(ans, count);
                        break;
                    }
                   ans=Math.max(ans, count);
                }
            }
            return ans;
        }
    

    思路2 (双指针)

    思路

    • 第一次写的时候 无脑双for ,O(n^2) 最后一个实例 超时超空间
    • 双指针 设置start end 指针,逐个遍历
    • 设置新起点那一步开始,应该可以继续优化

    代码

    class Solution {
        public int longestSubarray(int[] nums, int limit) {
            int ans = 0;
            int len = nums.length;
            int subMax = 0;
            int min=nums[0];
            int max=min;
            for (int start = 0, end = 0; start < len && end < len; end++) {
                min = Math.min(min,nums[end]);
                max = Math.max(max,nums[end]);
                subMax = Math.max(subMax, max - min);
                if (subMax > limit) {
                    ans = Math.max(ans, end - start);
                    start++;
                    //新起点
                    end=start;
                //因为本次循环结束 进入下一次循环end++,为了保证start和end指针同时指向 新起点,则end--;
                    end--;
                    min=max=nums[start];
                    subMax=0;
                }else{
                    ans=Math.max(ans, end-start+1);
                }
            }
            return ans;
        }
    }
    

    image-20200503170851737

  • 相关阅读:
    模板笔记2
    模板笔记
    qt打包可执行文件
    合并单独的视频和音频
    模板1
    mysql 数据表中查找重复记录
    mysql左连接右连接(查询两张表不同的数据)
    mysql--构造数据、导入导出
    mysql安装
    linux下启动tomcat服务
  • 原文地址:https://www.cnblogs.com/yh-simon/p/12822579.html
Copyright © 2011-2022 走看看