我得到了1和0的数组,以及数字k。我被允许最多k次翻转数组的元素。(0到1或1到0)。
我需要编写一个算法来翻转最多K个元素的状态,以便最大化具有相同元素的最大连续元素块的大小。
ex:
Array : 110001111 and k=2;
Solution is 2 , because: we can change the string to: 110101011, and the length of the maximum consecutive length is minimised to 2.
Array : 1001 k=1
Solution is 2, because: If we don't change the input string at all, the answer will be 2. It is the best value we can achieve under the given conditions.
有人可以帮我解决这个问题吗?
答案 0 :(得分:0)
让我试着开始简化这个问题:
我们有一个数字列表,代表相同类型的序列:
[a1,a2,a3...a_m]
使其总和为n
k
操作是以下任何一项:
a_i
替换为[a_i^1,1,a_i^2]
a_i
更改为a_i-1
,将a_{i-1}
更改为a_{i-1}+1
a_i
更改为a_i+1
,将a_{i-1}
更改为a_{i-1}-1
但很明显,如果a_i<=2
,操作2和3只比操作1好,除非只有一个元素且总长度为2,否则操作无意义在这种情况下做任何事情。所以我们可以认为这是如何分割价值的问题,在这种情况下我们不关心a_i
的顺序
通过k
次操作,您需要执行的k
操作是什么,max(a1,a2,...)
最后是最小的
很明显,如果我们不在最大字符串中翻转一下,那么我们就不会改变最大值。同样清楚的是,我们翻转比特的顺序无关紧要(例如,如果我们首先翻转第7位然后第4位,或者从第4位开始然后翻转第7位,则无关紧要)。所以我们不妨决定从拆分最大的连续块开始。
最大的连续块的最大长度为n
,因此我们已经找到了O(n^k)
算法。
答案 1 :(得分:-1)
让f(i,len,k,state)
代表索引i
之前的最小序列,其中len
是当前序列长度,k
是到目前为止翻转的数量{{1} }}是state
的状态。
然后:
a[i]
JavaScript代码:
if a[i] == 0:
// starting a new sequence
f(i, 1, k, 0) = min( f(i-1, len, k, 1) for all len)
// adding to a sequence (len > 1)
f(i, len, k, 0) = max( len, f(i-1, len-1, k, 0) )
// starting a new sequence
f(i, 1, k, 1) = min( f(i-1, len, k-1, 0) for all len)
// adding to a sequence (len > 1)
f(i, len, k, 1) = max( len, f(i-1, len-1, k-1, 1) )
if a[i] == 1:
...left as an exercise
&#13;