找到具有相同数量的0和1的最大子阵列

时间:2015-07-03 07:39:31

标签: arrays algorithm

所以,我有一个只包含0&1和#1的数组。我必须找出包含相同数量的0和1的最大子阵列。一个天真的方法可以具有def resArray = context.getProperty("RES_DATA_ARRAY") def resData = context.getProperty("RESPONSE_DATA") def result = testRunner.results[testRunner.results.size()-1] long messageSize = result.getMessageExchanges().size.get(0) // get the response... def response result.testStep.getPropertyValue('response') log.info response // do something with the response... responseData.set.xxxxxxx //Some more values set in responseData object responseData.setMessageSize(messageSize)werqwerwerwerwerqwer resArray.add(responseData) 的复杂性,其中我获取外部循环中的每个元素并在内部循环中计算可能的子数组并且如果找到则继续更新最大大小。还有其他更好的方法(比如O(n))我可以使用吗?谢谢!

ffmpeg  -i rtsp://admin:admin@192.168.0.12:554/video_4 -f mpeg1video -b 800k -r 30 http://localhost:8082/yourpassword/640/4800/

10 个答案:

答案 0 :(得分:22)

这是一个O(n)时间,O(n)空间算法。我不确定它是否是最佳的,但它会超过二次时间。

基本思路如下。假设您从阵列的左侧扫描到正确的记录,在每个步骤中,1的数量和0的数量之间的差异。如果你在每一步都写出这些值,你会得到这样的结果:

  1,   0,   1,    0,    0,   0,   0
0,   1,   0,   1,    0,    -1,  -2,  -3

如果您的子数组具有相同数量的0和1,则子数组开头的0和1的净差将等于子数组后的净数。因此,这个问题可以重新定义为试图在辅助数组中找到两个相等且尽可能相等的相等值。

好消息是数组中的每个条目都在-n和+ n之间,因此您可以创建一个2n + 1个元素的表,并在其中存储每个数字出现的第一个和最后一个的索引。从那里,很容易找到最长的范围。总的来说,这需要O(n)空间,并且可以在O(n)时间内填充和搜索所有内容。

希望这有帮助!

答案 1 :(得分:5)

首先将零转换为-1。然后,您正在寻找零和的最大子阵列。对此的算法描述为here

答案 2 :(得分:1)

public int equalNumber(int arr[]){

    int sum[] = new int[arr.length];
    sum[0] = arr[0] == 0? -1 : 1;
    for(int i=1; i < sum.length; i++){
        sum[i] = sum[i-1] + (arr[i] == 0? -1 : 1);
    }

    Map<Integer,Integer> pos = new HashMap<Integer,Integer>();
    int maxLen = 0;
    int i = 0;
    for(int s : sum){
        if(s == 0){
            maxLen = Math.max(maxLen, i+1);
        }
        if(pos.containsKey(s)){
            maxLen = Math.max(maxLen, i-pos.get(s));
        }else{
            pos.put(s, i);
        }
        i++;
    }
    return maxLen;
}

答案 3 :(得分:0)

灵感来自@templatetypedef算法,我用python编写了代码,希望它对某人有帮助。

def check_max_length(input_array):
    length = len(input_array)
    mapping_dict = {}
    max_length = 0
    for i in range(length):
        if input_array[i] not in mapping_dict.keys():
            mapping_dict[input_array[i]] = i
        else:
            max_length = max(max_length,i-mapping_dict[input_array[i]])
    return max_length

def find_max_substring_length(input_string):
    def_array = [0]
    zero_count = 0
    one_count = 0
    # difference between number of zeroes and ones
    def_zero_one = 0
    for i in range(len(input_string)):
        if input_string[i] == '1':
            one_count+=1
        else:
            zero_count+=1

        def_array.append(one_count-zero_count)
    max_substring = check_max_length(def_array)
return max_substring

input_string = '1000100'
substring_length = find_max_substring_length(input_string)
print(substring_length) // will give result as 2

答案 4 :(得分:0)

这与@templatetypedef的答案密切相关。 但是,与其将其视为一和零之间的差异,不如将其视为。我看到的是tracker的一种类型,当看到一个1时递增,而看到零则减小。

这是一个经过测试的解决方案。

 /**
 * given an array of 0's and 1's return the length of the maximal
 * subarray that has only 0's and 1's
 * O(n) solution inspired by https://stackoverflow.com/a/31201586/919858
 *
 * in           0    0    1    1
 * aux         0  -1   -2   -1   0
 * @param in
 * @return
 */
static int lenMaxSubArray(int[] in) {
    int maxLen = -1;
    int[] oneCount = new int[in.length + 1];
    oneCount[0] = 0;
    for (int i = 0; i < in.length; i++) {
        if (in[i] == 1) {
            oneCount[i + 1] = oneCount[i] + 1;
        } else {
            oneCount[i + 1] = oneCount[i] - 1;
        }
    }

    Map<Integer, List<Integer>> map = new HashMap<>();
    for (int i = 0; i < oneCount.length; i++) {
        List<Integer> list = map.getOrDefault(oneCount[i], new ArrayList<>());
        list.add(i);
        map.put(oneCount[i], list);
    }

    for (int i = 0; i < oneCount.length; i++) {
        List<Integer> list = map.get(oneCount[i]);
        if (list != null) {
            int start = list.get(0);
            int end = list.get(list.size() - 1);
            maxLen = Math.max(maxLen, end - start);
        }
    }

    return maxLen;
}

答案 5 :(得分:0)

int maxLen(int nums[], int n)
{   
    unordered_map<int, int> m;
    m[0] = -1;
    int ans = 0, cur = 0;
    for (int i = 0; i < n; ++i) {
        cur += nums[i] ? 1 : -1;
        if (m.count(cur))
            ans = max(ans, i - m[cur]);
        else
            m[cur] = i;
    }
    return ans;
}

答案 6 :(得分:0)

@templatetypedef算法的JS实现,其中使用了映射来帮助查找最大长度的修改

function findMaxLen(a) {
// secondary array, initialized with the first element as 0
let b = [0]
let sum = 0

// populate the secondary array and update the sum as per the algorithm
for (let i = 0; i < a.length; i++) {
    b[i + 1] = a[i] == 0 ? sum - 1 : sum + 1
    sum = b[i + 1]
}

// map of sum vs the first index of the secondary array with the sum value
let map = new Map()
let maxLen = 0

for (let i = 0; i < b.length; i++) {
    if (map.has(b[i]))
        maxLen = Math.max(maxLen, i - map.get(b[i]))
    else
        map.set(b[i], i)
}

return maxLen
}

答案 7 :(得分:0)

class Solution {
public:
    int findMaxLength(vector<int>& nums) {
        int n=nums.size();
        if(n<=1) return 0;
        vector<int> arr(n,-1);
        arr[0]= (nums[0]==0)? -1:1 ;

        for(int i=1;i<n;i++)
        {
            arr[i] = arr[i-1] + ((nums[i]==0)? -1 : 1) ;
        }

        int sol=0;
        unordered_map<int,int> mp;
        for(int i=0;i<n;i++)
        {
            if(arr[i]==0) sol = i+1;
            else
            {
                if(mp.find(arr[i])==mp.end())
                {
                    mp[arr[i]]=i;
                }
                else
                {
                    sol=max(sol,i-mp[arr[i]]);
                }
            }
        }
        return sol;
    }
};

答案 8 :(得分:0)

在O(n)时间实现哈希图。

int count=0, max_length=0;
        unordered_map<int,int> mp;
        mp[0] = -1;

        for(int i=0; i<nums.size(); i++)
        {
            if(nums[i] == 0) count += -1;
            if(nums[i] == 1) count += 1;

            if(mp.find(count) != mp.end())
                max_length = max(max_length, i-mp[count]);
            else
                mp[count] = i;                        
        }

        return max_length;

希望此代码块有帮助。

答案 9 :(得分:0)

算法

我们利用HashMap映射以(index,count)的形式存储条目。每当遇到计数时,我们都会在映射中为计数输入一个条目,然后在以后使用相应的索引来查找最大等于n的子数组的长度。再次遇到相同计数时的零和一。

import pandas as pd
from IPython.core.display import HTML
from IPython.display import display

df = pd.DataFrame([[2,3,1], [3,2,2], [2,4,4]], columns=list("ABC"))

df.style.apply(lambda x: ['background: red' if v > x.iloc[0] else "" for v in x], axis = 1)
# df
# print(df)
# display(df)
# display(HTML(df.to_html()))