LeetCode1124. 表现良好的最长时间段(HashMap + 前缀和)

力扣

 

        

解题思路:

1.用一个 sum 变量记录前缀和,当大于8时,sum++, 小于8时,sum--。
由于从前向后遍历,当 sum > 0时,说明从开始到现在满足条件,时间必然是最长的,直接更新 ans = i + 1。


2.当 sum <= 0时呢?关键来了 : 
这里用一个HashMap记录所有 sum <= 0的最小下标,所谓最小,就是后面如果再碰到了同样的 cur,不需要更新,如果没有碰到过,则把这个下标记录下来。因为 sum - x >= 1 , x <= sum -1然后用 sum - 1 去map里找,如果找到了下标 j,那么就说明从0到 j 的前缀和是 sum-1,而从0到 i 的前缀和是 sum,那么显然从 j 到 i 的和是(sum - (sum - 1)) = 1 > 0,也就是说从 j + 1到 i 的表现肯定是满足的,并且由于 j 是 sum-1中最小的,所以 i - j 是最大的。
此时再跟 ans 比较看是否需要更新。

3.上面为什么只需要查找 sum-1?sum - x >= 1 , x <= sum -1 , 因为满足条件的前缀和只能是小于等于sum-1的,也就是说其实也可以查找 sum-2,sum - 3...,但是,sum - 2的下标一定不可能在 sum-1的下标左边。使用反证法,前提是sum -1代表的是最小下标,那么如果 sum - 2在 sum -1左边,而sum - 2的左边一定还会有 sum - 1出现(sum值是从0开始的),这就和最小下标的前提矛盾了。


4. 那么问题又来了,如果 sum-1不存在,是否要查找 sum-2,sum-3...呢?
也不需要,思路跟上面是一样的,如果 sum-1不存在,sum-2,sum-3...一定也不存在。

举个例子,不可能从0跳到-2,-3,而中间没有-1。

作者:li-zi-he
链接:https://leetcode-cn.com/problems/longest-well-performing-interval/solution/bie-gen-lao-fu-ti-shi-yao-dan-diao-zhan-by-li-zi-h/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

        

         

这里我画了一个示意图帮助理解上述思想:

 

class Solution {
public:
    int longestWPI(vector<int>& hours) 
    {
       int n = hours.size();
        int sum = 0;
        int ans = 0;
        unordered_map<int, int> index; //用于记录当sum < 0时 ,sum : i下标的映射


        for(int i=0;i<n;i++)
        {
            sum += (hours[i] > 8 ? 1 : -1);
            
            if(sum > 0)
            {
                ans = i+1;
            }
            else
            {
                if(index.count(sum) == 0) //查看是否存在这个sum : i的映射
                index[sum] = i;            //不存在添加映射关系
 
                if(index.count(sum - 1) != 0)  // sum - x =1 ,x = sum - 1; 
                ans = max(ans , i - index[sum-1]);  //找到 key = x的下标
                
            }

        }
        return ans;

    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值