zoukankan      html  css  js  c++  java
  • 【数据结构】算法 Longest Well-Performing Interval 表现良好的最长时间段

    Longest Well-Performing Interval 表现良好的最长时间段

    We are given hours, a list of the number of hours worked per day for a given employee.

    A day is considered to be a tiring day if and only if the number of hours worked is (strictly) greater than 8.

    A well-performing interval is an interval of days for which the number of tiring days is strictly larger than the number of non-tiring days.

    Return the length of the longest well-performing interval.

    每天的work time >8,代表这一天 tiring,表现良好的时间段,注意是时间段,被标记为tiring的天数要大于非tiring的天数,并且把这个时间段长度返回。

    Input: hours = [9,9,6,0,6,6,9]
    Output: 3
    Explanation: The longest well-performing interval is [9,9,6].
    

    思路

    将问题进行转换:

    数组元素a[i]>8,就标记b[i]=1,否则b[i]=-1。

    原来的a数组[9,9,6,0,6,6,9],会得到新数组b[1,1,-1,-1,-1,-1,1].此时我们是要寻找到b数组中区间和大于0 的部分。

    继续转换,将b数组的元素,转换为前缀和。c数组 ,c[i]=c[i-1]+c[i-2].....+c[0].由此可知c数组为[1,2,1,0,-1,-2,-1],此时问题转换为寻找c数组中c[j]-c[i]>0,(j>i)时,并且是长度最长的一段。

    如何能保证当j>i时 c[j]-c[i]>0。用人类的语言来说,就是从j位置向前寻找一个比c[j]小的数,这样才能保证 c[j]-c[i]>0。

    而且c数组是一组连续的数字,所以在从j位置向前寻找比c[j]小的数,如果存在的话,那么c[i]一定是满足c[j]-1= c[i];否则j前面就不会存在比c[j]小的数,从而就无法保证 c[j]-c[i]>0。

    方法一:

    public int longestWPI(int[] hours) {
        HashMap<Integer, Integer> ind = new HashMap<>();//每一种值第一次出现的位置
        HashMap<Integer, Integer> f = new HashMap<>();//每种值最长的序列长度
        ind.put(0,-1);//初始化,前缀和位置0 值为-1,数组的前缀和从位置1开始算
        f.put(0,0);
        int cnt = 0 ;//前缀和
        int ans = 0 ;
        for (int i = 0; i < hours.length; i++) {
            if (hours[i]>8){
                cnt+=1;
            }
            else{
                cnt -=1;
            }
            if(!ind.containsKey(cnt)){
                //没有出现过cnt,cnt的位置就是i
                ind.put(cnt,i);
                if(!ind.containsKey(cnt-1)){
                    //没有出现过cnt 而且没有出现过cnt-1,cnt的位置就是i
                    f.put(cnt,0);
                }
                else{
                    //f.get(n) 代表以n为结尾的最长的序列长度
                    //计算f(n)=f(n-1)+pos(n)-pos(n-1)
                    int i1 = f.get(cnt - 1) + (i - ind.get(cnt - 1));
                    f.put(cnt,i1);
                }
            }
            if(!ind.containsKey(cnt-1)){
                //没有出现过cnt-1,continue
                continue;
            }//否则就出现过cnt-1
            //计算当前f(n)和ans的max
            ans = Math.max(ans,i - ind.get(cnt-1)+f.get(cnt-1));
        }
        return ans;
    }
    

    方法二:

    public int longestWPI(int[] hours) {
            int sum = 0;
            int res = 0;
            HashMap<Integer, Integer> sumToIndex = new HashMap<>();
            for (int i = 0; i < hours.length; i++){
                if (hours[i] > 8) {
                    sum++;
                } else {
                    sum--;
                }
                if (sum > 0) {
                    res = i + 1;
                }
                else {
                    if (!sumToIndex.containsKey(sum)){
                        sumToIndex.put(sum, i);
                    }
                    if (sumToIndex.containsKey(sum - 1)) {
                        res = Math.max(res, i - sumToIndex.get(sum - 1));
                    }
                }
            }
            return res;
        }
    

    tag

    sum

  • 相关阅读:
    webmagic的使用学习
    redis在macOS上的安装及与springboot的整合使用
    Swagger-UI
    个人作业——软件工程实践总结&个人技术博客
    祝贺大野鸡喜提小黄衫一件
    软件评测(个人作业)
    结对第二次作业
    Springboot项目创建文件中相对路径问题
    二进制翻转
    欧拉降幂及广义欧拉降幂证明
  • 原文地址:https://www.cnblogs.com/dreamtaker/p/14639894.html
Copyright © 2011-2022 走看看