列表

详情


100135. 找到最大非递减数组的长度

给你一个下标从 0 开始的整数数组 nums 。

你可以执行任意次操作。每次操作中,你需要选择一个 子数组 ,并将这个子数组用它所包含元素的  替换。比方说,给定数组是 [1,3,5,6] ,你可以选择子数组 [3,5] ,用子数组的和 8 替换掉子数组,然后数组会变为 [1,8,6] 。

请你返回执行任意次操作以后,可以得到的 最长非递减 数组的长度。

子数组 指的是一个数组中一段连续 非空 的元素序列。

 

示例 1:

输入:nums = [5,2,2]
输出:1
解释:这个长度为 3 的数组不是非递减的。
我们有 2 种方案使数组长度为 2 。
第一种,选择子数组 [2,2] ,对数组执行操作后得到 [5,4] 。
第二种,选择子数组 [5,2] ,对数组执行操作后得到 [7,2] 。
这两种方案中,数组最后都不是 非递减 的,所以不是可行的答案。
如果我们选择子数组 [5,2,2] ,并将它替换为 [9] ,数组变成非递减的。
所以答案为 1 。

示例 2:

输入:nums = [1,2,3,4]
输出:4
解释:数组已经是非递减的。所以答案为 4 。

示例 3:

输入:nums = [4,3,2,6]
输出:3
解释:将 [3,2] 替换为 [5] ,得到数组 [4,5,6] ,它是非递减的。
最大可能的答案为 3 。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int findMaximumLength(vector<int>& nums) { } };

python3 解法, 执行用时: 608 ms, 内存消耗: 36.5 MB, 提交时间: 2023-11-26 16:47:25

class Solution:
    def findMaximumLength(self, nums: List[int]) -> int:
        n = len(nums)
        s = list(accumulate(nums, initial=0))
        f = [0] * (n + 1)
        last = [0] * (n + 1)
        q = deque([0])
        for i in range(1, n + 1):
            # 去掉队首无用数据(计算转移直接取队首)
            while len(q) > 1 and s[q[1]] + last[q[1]] <= s[i]:
                q.popleft()
            
            # 计算转移
            f[i] = f[q[0]] + 1
            last[i] = s[i] - s[q[0]]
            
            # 去掉队尾无用数据
            while q and s[q[-1]] + last[q[-1]] >= s[i] + last[i]:
                q.pop()
            q.append(i)
        return f[n]

java 解法, 执行用时: 15 ms, 内存消耗: 54.9 MB, 提交时间: 2023-11-26 16:47:40

class Solution {
    public int findMaximumLength(int[] nums) {
        int n = nums.length;
        long[] s = new long[n + 1];
        int[] f = new int[n + 1];
        long[] last = new long[n + 1];
        int[] q = new int[n + 1]; // 数组模拟队列
        int front = 0, rear = 0;
        for (int i = 1; i <= n; i++) {
            s[i] = s[i - 1] + nums[i - 1];
            
            // 去掉队首无用数据(计算转移直接取队首)
            while (front < rear && s[q[front + 1]] + last[q[front + 1]] <= s[i]) {
                front++;
            }
            
            // 计算转移
            f[i] = f[q[front]] + 1; 
            last[i] = s[i] - s[q[front]];
            
            // 去掉队尾无用数据
            while (rear >= front && s[q[rear]] + last[q[rear]] >= s[i] + last[i]) {
                rear--;
            }
            q[++rear] = i;
        }
        return f[n];
    }
}

cpp 解法, 执行用时: 212 ms, 内存消耗: 150.3 MB, 提交时间: 2023-11-26 16:47:59

class Solution {
public:
    int findMaximumLength(vector<int> &nums) {
        int n = nums.size();
        vector<long long> s(n + 1), last(n + 1);
        vector<int> f(n + 1), q(n + 1); // 数组模拟队列
        int front = 0, rear = 0;
        for (int i = 1; i <= n; i++) {
            s[i] = s[i - 1] + nums[i - 1];

            // 去掉队首无用数据(计算转移直接取队首)
            while (front < rear && s[q[front + 1]] + last[q[front + 1]] <= s[i]) {
                front++;
            }

            // 计算转移
            f[i] = f[q[front]] + 1;
            last[i] = s[i] - s[q[front]];

            // 去掉队尾无用数据
            while (rear >= front && s[q[rear]] + last[q[rear]] >= s[i] + last[i]) {
                rear--;
            }
            q[++rear] = i;
        }
        return f[n];
    }
};

golang 解法, 执行用时: 148 ms, 内存消耗: 10.5 MB, 提交时间: 2023-11-26 16:48:23

func findMaximumLength(nums []int) (ans int) {
	n := len(nums)
	s := make([]int, n+1)
	f := make([]int, n+1)
	last := make([]int, n+1)
	q := []int{0}
	for i := 1; i <= n; i++ {
		s[i] = s[i-1] + nums[i-1]

		// 去掉队首无用数据(计算转移直接取队首)
		for len(q) > 1 && s[q[1]]+last[q[1]] <= s[i] {
			q = q[1:]
		}

		// 计算转移
		f[i] = f[q[0]] + 1
		last[i] = s[i] - s[q[0]]

		// 去掉队尾无用数据
		for len(q) > 0 && s[q[len(q)-1]]+last[q[len(q)-1]] >= s[i]+last[i] {
			q = q[:len(q)-1]
		}
		q = append(q, i)
	}
	return f[n]
}

上一题