2511. Maximum Enemy Forts That Can Be Captured【数组,双指针】1450

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

给你一个长度为 n ,下标从 0 开始的整数数组 forts ,表示一些城堡。forts[i] 可以是 -1 ,0 或者 1 ,其中:

  • -1 表示第 i 个位置 没有 城堡。
  • 0 表示第 i 个位置有一个 敌人 的城堡。
  • 1 表示第 i 个位置有一个你控制的城堡。

现在,你需要决定,将你的军队从某个你控制的城堡位置 i 移动到一个空的位置 j ,满足:

  • 0 <= i, j <= n - 1
  • 军队经过的位置 只有 敌人的城堡。正式的,对于所有 min(i,j) < k < max(i,j) 的 k ,都满足 forts[k] == 0 。

当军队移动时,所有途中经过的敌人城堡都会被 摧毁 。

请你返回 最多 可以摧毁的敌人城堡数目。如果 无法 移动你的军队,或者没有你控制的城堡,请返回 0 。

示例 1:

输入:forts = [1,0,0,-1,0,0,0,0,1]
输出:4
解释:
- 将军队从位置 0 移动到位置 3 ,摧毁 2 个敌人城堡,位置分别在 12- 将军队从位置 8 移动到位置 3 ,摧毁 4 个敌人城堡。
4 是最多可以摧毁的敌人城堡数目,所以我们返回 4

示例 2:

输入:forts = [0,0,1,-1]
输出:0
解释:由于无法摧毁敌人的城堡,所以返回 0

提示:

  • 1 <= forts.length <= 1000
  • -1 <= forts[i] <= 1

解法 模拟

根据题意可知,军队从 i i i 处移动到 j j j 处时需满足如下要求:

  • 由于在 i i i 处的城堡为你方军队控制的城堡,则一定满足 forts [ i ] = 1 \textit{forts}[i] = 1 forts[i]=1
  • 由于在 j j j 处为空位置,则一定满足 forts [ j ] = − 1 \textit{forts}[j] = -1 forts[j]=1
  • 在移动过程中如下,由于军队经过的位置只能为敌人的城堡,因此当
    k ∈ ( min ⁡ ( i , j ) , m a x ( i , j ) ) k \in (\min(i,j),max(i,j)) k(min(i,j),max(i,j))
    时,需满足 forts [ k ] = 0 \textit{forts}[k] = 0 forts[k]=0

当军队移动时,所有途中经过的敌人城堡都会被摧毁,题目要求找到一次移动后可以摧毁敌人城堡的最大数目。

根据以上分析可知,由于军队只能在不同位置之间连续移动,军队移动的起点为 1 1 1 ,军队移动的终点为 − 1 -1 1 ,军队可以向左移动也可以向右移动,因此我们只需要找到相邻的 1 1 1 − 1 -1 1 之间的最大距离即可,此时 1 1 1 − 1 -1 1 之间所有的 0 0 0 都会被摧毁。查找过程如下:

  • 依次遍历为数组 f o r t fort fort 中的每个元素,此时我们用 p r e pre pre 记录数组中前一个为 1 1 1 或者 − 1 -1 1 的位置;
  • 假设当前元素 forts [ i ] \textit{forts}[i] forts[i] 1 1 1 或者 − 1 -1 1,即当前位置可能为军队的起点或终点,此时假设 forts [ i ] ≠ forts [ pre ] \textit{forts}[i] \neq \textit{forts}[\textit{pre}] forts[i]=forts[pre] ,即此时可以在 i i i p r e pre pre 之间可以移动,此时可以摧毁的城堡数目为 i − pre − 1 i - \textit{pre} - 1 ipre1 ,更新当前的最大城堡数目,同时记录新的 p r e pre pre
  • 按照上述方法找到最大可以摧毁的城堡数目即可。
class Solution {
public:
    int captureForts(vector<int> forts) {
        int ans = 0;
        int pre = -1;
        for (int i = 0; i < forts.size(); ++i) {
            if (forts[i]) {
                if (pre >= 0 && forts[i] != forts[pre]) // 一个是1,另一个是-1
                    ans = max(ans, i - pre - 1);
                pre = i;
            }
        }
        return ans;
    }
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

你可能感兴趣的:(#,双指针,leetcode,算法)