LeetCode 题解工作台

最少翻转操作数

给定一个整数 n 和一个整数 p ,它们表示一个长度为 n 且除了下标为 p 处是 1 以外,其他所有数都是 0 的数组 arr 。同时给定一个整数数组 banned ,它包含数组中的一些限制位置。在 arr 上进行下列操作: 如果单个 1 不在 banned 中的位置上,反转大小为 k 的 子数组…

category

3

题型

code_blocks

6

代码语言

hub

3

相关题

当前训练重点

困难 · 图·搜索

bolt

答案摘要

我们注意到,对于一个子数组区间 中的任意一个下标 ,翻转后的下标 $j = l + r - i$。 如果子数组向右移动一个位置,那么 $j = l + 1 + r + 1 - i = l + r - i + 2$,即 会增加 。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 图·搜索 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给定一个整数 n 和一个整数 p,它们表示一个长度为 n 且除了下标为 p 处是 1 以外,其他所有数都是 0 的数组 arr。同时给定一个整数数组 banned ,它包含数组中的一些限制位置。在 arr 上进行下列操作:

  • 如果单个 1 不在 banned 中的位置上,反转大小为 k子数组

返回一个包含 n 个结果的整数数组 answer,其中第 i 个结果是将 1 放到位置 i 处所需的 最少 翻转操作次数,如果无法放到位置 i 处,此数为 -1 。

 

示例 1:

输入:n = 4, p = 0, banned = [1,2], k = 4

输出:[0,-1,-1,1]

解释:

  • 一开始 1 位于位置 0,因此我们需要在位置 0 上的操作数是 0。
  • 我们不能将 1 放置在被禁止的位置上,所以位置 1 和 2 的答案是 -1。
  • 执行大小为 4 的操作以反转整个数组。
  • 在一次操作后,1 位于位置 3,因此位置 3 的答案是 1。

示例 2:

输入:n = 5, p = 0, banned = [2,4], k = 3

输出:[0,-1,-1,-1,-1]

解释:

  • 一开始 1 位于位置 0,因此我们需要在位置 0 上的操作数是 0。
  • 我们不能在 [0, 2] 的子数组位置上执行操作,因为位置 2 在 banned 中。
  • 由于 1 不能够放置在位置 2 上,使用更多操作将 1 放置在其它位置上是不可能的。

示例 3:

输入:n = 4, p = 2, banned = [0,1,3], k = 1

输出:[-1,-1,0,-1]

解释:

执行大小为 1 的操作,且 1 永远不会改变位置。

 

提示:

  • 1 <= n <= 105
  • 0 <= p <= n - 1
  • 0 <= banned.length <= n - 1
  • 0 <= banned[i] <= n - 1
  • 1 <= k <= n 
  • banned[i] != p
  • banned 中的值 互不相同 。
lightbulb

解题思路

方法一:有序集合 + BFS

我们注意到,对于一个子数组区间 [l,..r][l,..r] 中的任意一个下标 ii,翻转后的下标 j=l+rij = l + r - i

如果子数组向右移动一个位置,那么 j=l+1+r+1i=l+ri+2j = l + 1 + r + 1 - i = l + r - i + 2,即 jj 会增加 22

同理,如果子数组向左移动一个位置,那么 j=l1+r1i=l+ri2j = l - 1 + r - 1 - i = l + r - i - 2,即 jj 会减少 22

因此,对于一个特定的下标 ii,其翻转后的所有位置构成了一个公差为 22 的等差数列,也即是说,翻转后的所有下标,奇偶性都是相同的。

接下来,我们考虑下标 ii 翻转后的位置 jj 的取值范围。

  • 如果不考虑边界的情况,那么 jj 的取值范围为 [ik+1,i+k1][i - k + 1, i + k - 1]
  • 如果子数组在最左边,那么 [l,r]=[0,k1][l, r] = [0, k - 1],因此 ii 翻转后的下标 j=0+k1ij = 0 + k - 1 - i,即 j=ki1j = k - i - 1,因此 jj 的左边界 mi=max(ik+1,ki1)mi = max(i - k + 1, k - i - 1)
  • 如果子数组在最右边,那么 [l,r]=[nk,n1][l, r] = [n - k, n - 1],因此 ii 翻转后的下标 j=nk+n1ij= n - k + n - 1 - i,即 j=n×2ki1j = n \times 2 - k - i - 1,因此 jj 的右边界 mx=min(i+k1,n×2ki1)mx = min(i + k - 1, n \times 2 - k - i - 1)

我们用两个有序集合分别存储所有待搜索的奇数下标和偶数下标,这里需要排除数组 bannedbanned 中的下标,以及下标 pp

接下来,我们使用 BFS 搜索,每次搜索当前下标 ii 所有翻转后的下标 jj,即 j=mi,mi+2,mi+4,,mxj = mi, mi + 2, mi + 4, \dots, mx,更新下标 jj 的答案,并将下标 jj 加入到待搜索的队列中,同时将下标 jj 从对应的有序集合中移除。

当搜索结束时,即可得到所有下标的答案。

时间复杂度 O(n×logn)O(n \times \log n),空间复杂度 O(n)O(n)。其中 nn 题目中给定的数组长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution:
    def minReverseOperations(
        self, n: int, p: int, banned: List[int], k: int
    ) -> List[int]:
        ans = [-1] * n
        ans[p] = 0
        ts = [SortedSet() for _ in range(2)]
        for i in range(n):
            ts[i % 2].add(i)
        ts[p % 2].remove(p)
        for i in banned:
            ts[i % 2].remove(i)
        ts[0].add(n)
        ts[1].add(n)
        q = deque([p])
        while q:
            i = q.popleft()
            mi = max(i - k + 1, k - i - 1)
            mx = min(i + k - 1, n * 2 - k - i - 1)
            s = ts[mi % 2]
            j = s.bisect_left(mi)
            while s[j] <= mx:
                q.append(s[j])
                ans[s[j]] = ans[i] + 1
                s.remove(s[j])
                j = s.bisect_left(mi)
        return ans
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Understanding BFS and how it guarantees minimum operations is key.

  • question_mark

    Watch for how the candidate handles blocked positions and restrictions.

  • question_mark

    Evaluate if the candidate can optimize the search process and handle edge cases efficiently.

warning

常见陷阱

外企场景
  • error

    Forgetting to handle banned positions correctly, leading to invalid solutions.

  • error

    Assuming the BFS will always find a valid path, without considering isolated or blocked positions.

  • error

    Not handling edge cases, such as when the starting position is the only valid position.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Change the operation size `k` to affect how the 1 can move, adding more complexity to the problem.

  • arrow_right_alt

    Introduce multiple 1s in the array and calculate the minimum operations to bring all 1s to every position.

  • arrow_right_alt

    Consider dynamic constraints where the banned positions can change during the operation sequence.

help

常见问题

外企场景

最少翻转操作数题解:图·搜索 | LeetCode #2612 困难