LeetCode #1124 Longest Well-Perf

2022-04-27  本文已影响0人  air_melt

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

Description:
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.

Example:

Example 1:

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

Example 2:

Input: hours = [6,6,6]
Output: 0

Constraints:

1 <= hours.length <= 10^4
0 <= hours[i] <= 16

题目描述:
给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。

我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。

所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大于「不劳累的天数」。

请你返回「表现良好时间段」的最大长度。

示例 :

示例 1:

输入:hours = [9,9,6,0,6,6,9]
输出:3
解释:最长的表现良好时间段是 [9,9,6]。

示例 2:

输入:hours = [6,6,6]
输出:0

提示:

1 <= hours.length <= 10^4
0 <= hours[i] <= 16

思路:

单调栈 ➕ 前缀和
先将 hours 数组按照是否大于 8 赋值 1/-1
求取新数组的前缀和
转化为在前缀和数组中找到一个子数组, 使得子数组的和大于 0, 且长度最长
即 max(j - i), s.t. pre[j] - pre[i] > 0, 0 < i < j < n
先将前缀和中的数按照严格递减顺序加入单调栈
然后从后往前遍历前缀和数组, 将当前下标之后的单调栈元素进行比较得到最长的子数组
时间复杂度为 O(n), 空间复杂度为 O(n)

代码:
C++:

class Solution 
{
public:
    int longestWPI(vector<int>& hours) 
    {
        int n = hours.size(), result = 0, i = 0;
        vector<int> score(n), pre(n + 1);
        stack<int> s;
        for (i = 0; i < n; i++) score[i] = hours[i] > 8 ? 1 : -1;
        for (i = 1; i <= n; i++) pre[i] = pre[i - 1] + score[i - 1];
        for (i = 0; i <= n; i++) if (s.empty() or pre[s.top()] > pre[i]) s.push(i);
        for (i = n; i > result; i--)
        {
            while (!s.empty() and pre[s.top()] < pre[i])
            {
                result = max(result, i - s.top());
                s.pop();
            }
        }
        return result;
    }
};

Java:

class Solution {
    public int longestWPI(int[] hours) {
        int n = hours.length, result = 0, score[] = new int[n], pre[] = new int[n + 1], i = 0;
        Stack<Integer> stack = new Stack<>();
        for (i = 0; i < n; i++) score[i] = hours[i] > 8 ? 1 : -1;
        for (i = 1; i <= n; i++) pre[i] = pre[i - 1] + score[i - 1];
        for (i = 0; i <= n; i++) if (stack.isEmpty() || pre[stack.peek()] > pre[i]) stack.push(i);
        for (i = n; i > result; i--) while (!stack.isEmpty() && pre[stack.peek()] < pre[i]) result = Math.max(result, i - stack.pop());
        return result;
    }
}

Python:

class Solution:
    def longestWPI(self, hours: List[int]) -> int:
        n, pre, result, stack = len(hours), [0] + list(accumulate([1 if h > 8 else -1 for h in hours])), 0, []
        for i in range(n + 1):
            if not stack or pre[stack[-1]] > pre[i]:
                stack.append(i)
        i = n
        while i > result:
            while stack and pre[stack[-1]] < pre[i]:
                result = max(result, i - stack.pop())
            i -= 1
        return result
上一篇下一篇

猜你喜欢

热点阅读