Problem
Given an array arr that represents a permutation of numbers from 1 to n.
You have a binary string of size n that initially has all its bits set to zero. At each step i (assuming both the binary string and arr are 1-indexed) from 1 to n, the bit at position arr[i] is set to 1.
You are also given an integer m. Find the latest step at which there exists a group of ones of length m. A group of ones is a contiguous substring of 1‘s such that it cannot be extended in either direction.
Return the latest step at which there exists a group of ones of length exactly m. If no such group exists, return -1.
Example 1:
1 | Input: arr = [3,5,1,2,4], m = 1 |
Example 2:
1 | Input: arr = [3,1,5,4,2], m = 2 |
Constraints:
n == arr.length1 <= m <= n <= 1051 <= arr[i] <= n- All integers in
arrare distinct.
Analysis
这道题目给出一个数组arr,包含[1,n]一共n个元素,还有一个值m。题目的操作是从一个长度为n的全0字符串开始,每次把第arr[i]上的0改为1,问第几步之后(latest,即最新)存在连续m个1的substring。这个是一个和子串以及长度有关的题目,但因为我们的操作顺序是按照arr,也不一定是连续的,所以很难用sliding window。
那么突破口就只能是在长度上做文章了,我们可以用一个数组记录子串的长度,如何用一个数组记录子串长度呢?这里有一个技巧就是只更新leftMost和rightMost。比如说0100,那么对应的长度就是[0, 1, 0, 0]。如果我把i = 2改成1,那么就更新为[0, 2, 2, 0],更general一点就是,当我改变a = arr[i]这个位置是,我先找到左边连续1的个数是left = length[a - 1],以及右边连续1的个数right = length[a + 1]。加上当前的这个位置,整个子串的左边界就是a - left,有边界就是a + right,更新这两个位置为left + right + 1。
上面说了怎么维护长度信息,那怎么判断是否存在有长度为m的连续1子串呢?我们只需要每次反转一个位置后,检查先反转完有没有生成长度为m的即可,因为要维护latest,所以只要有都更新,从前往后的遍历顺序保证了答案是最近的步骤。
Solution
无。
Code
1 | class Solution { |
Summary
这道题目的技巧之前用的比较少,所以我认为是非常值得总结的,通过维护子串两端的值去维护长度。这道题目的分享到这里,感谢你的支持!