LeetCode: 1124

As we need to compare the counts of tiring days and non-tiring days, we can use number 1 to indicate tiring day and -1 to indicate non-tiring day. Then, the sum of interval represented by -1/1 will reveal if tiring days are strictly greater than non-tiring days.

Then the goal of this problem becomes: find the longest interval such that the sum of this interval will be strictly greater than 0, and the length of this interval is the final answer.

First, let’s introduce some definitions:

  • S ( i , j ) S_{(i, j)} S(i,j): the sum of interval [i, j] represented by -1/1 described above. The index of interval starts from 0. For example, if the interval is [1, -1, -1, 1], then S ( 1 , 3 ) = − 1 + ( − 1 ) + 1 = − 1 S_{(1, 3)} = -1 + (-1) + 1 = -1 S(1,3)=1+(1)+1=1.
  • S i S_i Si: abbreviation of S ( 0 , i ) S_{(0, i)} S(0,i).

Based on such notations, the final answer can be descibed as: for all position i i i, find out the longest interval [h, i], such that 0 ≤ h &lt; i 0 \le h \lt i 0h<i and S ( h , i ) &gt; 0 S_{(h, i)} \gt 0 S(h,i)>0. And the answer of this problem is ( i − h + 1 ) (i - h + 1) (ih+1) .

Apparently, this can be solved by pre-solved sub-problem with dynamic programming method.

For a specific position i i i, define dp[i] as the length of longest interval ending with i i i and S i &gt; 0 S_i \gt 0 Si>0. Then the final answer should be the largest of dp[i], where 0 ≤ i &lt; i n p u t _ a r r _ l e n g t h 0 \le i \lt input\_arr\_length 0i<input_arr_length.

For a specifice position i i i, if S i &gt; 0 S_i \gt0 Si>0, then dp[i] equals ( i + 1 ) (i + 1) (i+1).

If S i ≤ 0 S_i \le 0 Si0, dp[i] is the length of longest interval [h, i], which satisfying conditions: 0 ≤ h &lt; i 0\le h \lt i 0h<i and S ( h , i ) &gt; 0 S_{(h, i)} \gt 0 S(h,i)>0.

As [0, i] = [0, h-1] + [h, i] , we have S i = S h − 1 + S ( h , i ) S_{i}=S_{h-1} + S_{(h, i)} Si=Sh1+S(h,i), i.e. S i − S h − 1 = S ( h , i ) &gt; 0 S_{i} - S_{h-1} = S_{(h,i)} \gt 0 SiSh1=S(h,i)>0, which is equivalent to S i &gt; S h − 1 S_i \gt S_{h-1} Si>Sh1. This tells us: if we can find interval satisfying above conditions, S i S_i Si must be strictly greater than S h − 1 S_{h-1} Sh1.

Suppose [k, i] is the longest interval we’re searching for, we propose a statement that: S ( k − 1 ) = S i − 1 S_{(k-1)} = S_i - 1 S(k1)=Si1, i.e. S k − 1 S_{k-1} Sk1 only less than 1 comparing to S i S_i Si, which can’t become a much smaller number.

Proof by contradiction: if S k − 1 S_{k-1} Sk1 can be smaller, as the change of each S i S_i Si is continuous with “1” difference, there must be a position j j j such that j &lt; ( k − 1 ) j \lt (k-1) j<(k1) and S j = S i − 1 S_j = S_{i} - 1 Sj=Si1. Apparently, [j, i] is a interval longer than [k, i], which contradicts the longest assumption that [k, j] is the longest interval satisfying conditions.

Thus, if there exising longest interval [k, i], S k − 1 S_{k-1} Sk1 must be equal to S i − 1 S_i - 1 Si1. If there’s another pre-positions satisfying this equation, we should choose the smallest position to get the longest interval. So we only need to check if there’s a interval [0, k-1] such that S k − 1 S_{k-1} Sk1 equals S i − 1 S_i - 1 Si1, and we choose the smallest position k k k as answer.

Specifically, we can use a map to store each pre-interval sum S i S_i Si as key, and its correpsonding position i i i as value. We should add (key, val) pair of this map only when the key hasn’t been put into this map, which ensure it stores the smallest position of each sum value. Then, we only need to check if this map holds the key S i − 1 S_i -1 Si1. If it holds, we get a candidate answer ( i − k + 1 ) (i - k + 1) (ik+1). Otherwise, it just shows there’s no interval such that the sum of [k, i] is greater than 0.

private boolean isTiringDay(int work) {
    return (work > 8);
}

public int longestWPI(int[] hours) {
    if (null == hours) { return 0; }
    int res = 0, sum = 0;
    Map<Integer, Integer> sumMap = new HashMap<>();

    for (int i = 0; i < hours.length; i++) {
        sum += isTiringDay(hours[i]) ? 1 : -1;

        if (sum > 0) {
            res = i + 1;
        } else {
            sumMap.putIfAbsent(sum, i);
            if (sumMap.containsKey(sum-1)) {
                res = Math.max(res, i - sumMap.get(sum-1));
            }
        }
    }

    return res;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值