找到要翻转的零,以便最大化连续1的数量

时间:2016-08-15 07:52:26

标签: algorithm dynamic-programming

找到要翻转的零,以便最大化连续1的数量。

import ctypes

hello = open("hello.exe")
shellcode = hello.read()

shellcode_buffer = ctypes.create_string_buffer(shellcode, len(shellcode))

shellcode_func = ctypes.cast(shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p))

shellcode_func()

我们可以翻转最多2个零。如果我们翻转 arr [5]和arr [7],我们得到8个连续的1' s 在给定的约束下最大可能。

现在,如果我们只找到可能的1的最大数量,是否可以使用动态编程方法解决?

1 个答案:

答案 0 :(得分:1)

这个问题可以在线性时间O(N)线性空间O(N)中解决。它不是完全成熟的动态编程,但它与使用预计算

相似。

使用的数据结构:

1.left :它是一个整数数组,长度与给定数组相同。它经过预先计算,以便 for every position i

left[i] = Number of consecutive 1's to the left position i

2.right :它是一个整数数组,长度与给定数组相同。它经过预先计算,以便 for every position i

right[i] = Number of consecutive 1's to the right position i

这些可以在数组的single traversal中计算。假设arr是原始数组,遵循伪代码完成工作:

用于填充left array

的伪代码
left()
{
        int count = 0;
        for(int i = 0;i < arr length; ++i)
        {
            if(i == 0)
            {
                left[i] = 0;
                if(arr[i] == 1)
                 count++;
                continue;
            }
            else
            {
                left[i] = count;
                if(arr[i] == 1)
                 count++;
                else count = 0;
            }
        }
}

用于填充right array

的伪代码
right()
{
    int count = 0;
    for(int i = arr length - 1;i >= 0; --i)
    {
        if(i == arr length - 1)
        {
            right[i] = 0;
            if(arr[i] == 1)
             count++;
            continue;
        }
        else
        {
            right[i] = count;
            if(arr[i] == 1)
             count++;
            else count = 0;
        }
    }
}

现在我们唯一需要做的就是:检查所有位置i和j (i < j),使arr[i] = 0arr[j] = 0以及i和j之间没有位置arr [i]应为0并跟踪我们获得以下最大值的货币对:

<强> left[i] + right[j] + right[l]

您还可以使用left[i] + right[j] + left[r]

left[i]告诉位置i左侧的连续1的数量,right[j]告诉位置j右侧的连续1的数量和ij之间的连续1可以计为left[r] OR right[l],因此,我们有两个候选表达式。

这也可以使用以下伪代码在单次遍历中完成:

max_One()
  {
    max = 0;
    l = -1, r = -1;
    for(int i = 0;i < arr length; ++i)
    {
     if(arr[i] == 0)
     { 
        if(l == -1)
         l = i;
        else
        {
            r = i;          
            if(left[l] + right[r] + right[l] > max)
            {
                max = left[l] + right[r] + right[l];                
                left_pos = l;
                right_pos = r;
            }
            l = r;
        }
     }
    }
   }
相关问题