首页 > 试题广场 >

未排序数组中累加和为给定值的最长子数组系列问题补2

[编程题]未排序数组中累加和为给定值的最长子数组系列问题补2
  • 热度指数:2145 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个无序数组arr,其中元素只能是1或0。求arr所有的子数组中0和1个数相等的最长子数组的长度 
[要求]
时间复杂度为,空间复杂度为

输入描述:
第一行一个整数N,表示数组长度
接下来一行有N个数表示数组中的数


输出描述:
输出一个整数表示答案
示例1

输入

5
1 0 1 0 1

输出

4

备注:
import java.util.*;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int n = scanner.nextInt();
        int[] arr = new int[n];
        for(int i=0;i<n;i++){
            arr[i] = scanner.nextInt();
        }
       
         Map<Integer,Integer> map = new HashMap<>();
        map.put(0,-1);
        int key = 0,maxLen = 0;
        for(int i=0;i<n;i++){
            key += arr[i]==0?-1:1;
            
            if(map.containsKey(key)){
                maxLen = Math.max(maxLen,i-map.get(key));
            }else{
                map.put(key,i);
            }
            
        }
        
        System.out.print(maxLen);
		
	}
}

发表于 2019-10-24 13:14:23 回复(0)
这个跟匹配括号的过程有点像,定义一个平衡因子balance,遇到一个1就自增,遇到一个0就自减。遍历数组更新这个平衡因子,用一个哈希表记录0~i位置的平衡因子,我们可以知道对于一段数组arr[0:j],如果它的平衡因子为balance,且存在某个前面的位置i<j,满足arr[0:i]的平衡因子也是balance,这就说明子数组arr[i+1:j]的0和1数量相等,平衡因子归零,可以更新一次长度。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        String[] strArr = br.readLine().split(" ");
        int[] arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = Integer.parseInt(strArr[i]);
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0, -1);
        int maxLen = 0, balance = 0;
        for(int i = 0; i < n; i++){
            balance += arr[i] == 1? 1: -1;
            if(map.containsKey(balance)){
                // 0和1达到平衡时就更新长度
                maxLen = Math.max(maxLen, i - map.get(balance));
            }else{
                map.put(balance, i);
            }
        }
        System.out.println(maxLen);
    }
}
发表于 2021-12-09 17:11:51 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin>>n;
    int a[n], Max=1;
    for(int i=0;i<n;i++)
        cin>>a[i];
    map<int,int> M;
    M[0] = -1;
    for(int i=0,s=0;i<n;i++){
        s += (a[i]==1?1:-1);
        if(M.find(s)!=M.end())
            Max = max(Max, i-M[s]);
        else
            M[s] = i;
    }
    cout<<Max<<endl;
    return 0;
}

发表于 2020-02-05 01:33:24 回复(0)
```
import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
public class Main{
      public static void main(String[]args){
          Scanner s=new Scanner(System.in);
          int n=s.nextInt();
          Map<Integer,Integer> map=new HashMap<>();
          int arr[]=new int[n];
          int max=0;
          for(int i=0;i<n;i++){
              arr[i]=s.nextInt();
               if(!map.containsKey(arr[i])){
                  map.put(arr[i],1);
               }else{
                   map.put(arr[i],map.get(arr[i])+1);
               }
              if(map.containsKey(0)&&map.containsKey(1)&&(map.get(0)==(map.get(1)))){
                  max=Math.max(max,map.get(0)+map.get(1));
              }
          }
          s.close();
          System.out.println(max);
      }
}
```哪儿错了,求解答,为什么过不去
发表于 2019-09-11 15:04:36 回复(1)
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    vector<int>num(n);
    map<int,int>mp;
    for(int i=0;i<n;i++)
    {
        cin>>num[i];
        if(num[i]==0)
            num[i]=-1;
    }
    mp[0] = -1;
    int ans = 1,sum = 0;
    for (int i=0; i<n; ++i) {
        sum += num[i];
        if (mp.count(sum)) 
            ans =max(ans, i-mp[sum]);
        if (mp.find(sum) == mp.end()) 
            mp[sum] = i;
    }
    cout<<ans<<endl;
    return 0;
}

发表于 2019-08-24 22:28:59 回复(0)
let num = parseInt(readline());
let arr = readline().split(" ").map(Number);
let one = 0,
  zero = 0,
  max = 0;
for (let i = 0; i < num; i++) {
  arr[i] === 0 ? zero++ : one++;
  zero === one && (max = i + 1);
}
print(max);//这到底错哪了
发表于 2022-05-26 11:03:12 回复(0)
import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;

public class Main {
  	public static int getMaxLength(int[] arr) {
        int len = 0, sum = 0, k = 0;
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, -1);
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i] == 0 ? -1 : 1;
            if (map.containsKey(sum - k)) {
                len = Math.max(len, i - map.get(sum - k));
            }
            if (!map.containsKey(sum)) {
                map.put(sum, i);
            }
        }
        return len;
    }

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for(int i = 0; i<n; i++){
            arr[i] = sc.nextInt();
        }
        System.out.println(getMaxLength(arr));
    }
}

发表于 2021-03-15 14:28:59 回复(0)

C++直接处理输入数据


一串葫芦娃的题,0变-1,完事找和为0的最长子数组
问题不大,贴个代码摸个鱼
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin>>n;
    vector<int> v(n+1, 0);
    unordered_map<int,int> m;
    m[0] = 0;
    int res = 0;
    for(int i=1;i<=n;++i){
        cin>>v[i];
        if(v[i] == 0)
            v[i] = -1;
        v[i] += v[i-1];
        if(m.find(v[i]) != m.end())
            res = max(res, i-m[v[i]]);
        if(m.find(v[i]) == m.end())
            m[v[i]] = i;
    }
    cout<<res;
    return 0;
}


发表于 2020-07-18 11:30:39 回复(0)
N = int(input())
nums = list(map(int,input().split()))

sums = 0
dic = {0:-1}
ans = 0

for i in range(N):
    if nums[i]==1:
        sums += 1
    else:
        sums -= 1
    if sums not in dic:
        dic[sums] = i
    else:
        ans = max(ans,i-dic[sums])
print(ans)

发表于 2019-10-08 20:38:00 回复(0)
package com.hhdd.leetcode;

import java.util.HashMap;
import java.util.Scanner;

public class LargestNumNativeEqualsPositive {

    /*public static int func1(int[] arr) {
        //help1用来存放i到j上负数的个数,help2用来存放i到j上正数的个数
        int[][] help1 = new int[arr.length][arr.length];
        int[][] help2 = new int[arr.length][arr.length];
        //遍历生成从i到j上负数、正数的个数,并存在help1、help2
        for (int i = 0; i < arr.length; i++) {
            //count1用来记录负数的个数,count2用来记录正数的个数
            int count1 = 0;
            int count2 = 0;
            for (int j = i; j < arr.length; j++) {
                if (arr[j] < 0) {
                    help1[i][j] = ++count1;
                    help2[i][j] = count2;
                } else if (arr[j] > 0) {
                    help2[i][j] = ++count2;
                    help1[i][j] = count1;
                } else {
                    help1[i][j] = count1;
                    help2[i][j] = count2;
                }
            }
        }
        int ans = 0;
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j < arr.length; j++) {
                if (help1[i][j] != 0 && (help1[i][j] == help2[i][j])) {
                    ans = (j - i + 1) > ans ? (j - i + 1) : ans;
                }
            }
        }

        return ans;
    }*/

    public static int maxLength(int[] arr, int k) {

        if (arr == null || arr.length == 0) {
            return 0;
        }
        //map中的key用来记录累加和,对应的value是这个累加和第一次出现的下标
        HashMap<Integer, Integer> map = new HashMap<>();
        //这个很关键的,当数组从0开始的累加和是k时就会用到,所以一定要保证<0,-1>已经在map中了,这个当前i个和等于k时就用到了
        //当{1,2,3} k = 3时就可以体现出来,好好体会!
        map.put(0, -1);
        //sum用来记录数组前i项的和,length用来记录最后的答案
        int sum = 0, length = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
            //看看map中是否已经存过sum-k这个累加和了,有的话从那个值到目前的i就是length了
            if (map.containsKey(sum - k)) {
                int j = map.get(sum - k);
                length = i - j > length ? i - j : length;
            }
            if (!map.containsKey(sum)) {
                map.put(sum, i);
            }
        }
        return length;
    }



    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < arr.length; i++) {
            int temp = scanner.nextInt();
            if(temp ==1){
                arr[i] = temp;
            }else {
                arr[i] = -1;
            }
        }
        int ans  = maxLength(arr,0);
        System.out.println(ans);
    }


}

发表于 2019-09-01 00:26:56 回复(0)
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;
int getMaxLen(vector<int>&vec, int k)
{
	unordered_map<int, int> hashMap;
	hashMap[0] = -1;
	int sum = 0;
	int maxLen = 0;
	for (int i = 0; i < vec.size(); i++)
	{
		sum += vec[i];
		if (hashMap.find(sum) == hashMap.end())hashMap[sum] = i;

		auto tmp = hashMap.find(sum - k);
		if (tmp != hashMap.end())
		{
			int len = i - tmp->second;
			if (maxLen < len)maxLen = len;
		}
	}
	return maxLen;
}

int main()
{
	int n;
	scanf("%d", &n);
	vector<int>vec(n);
	for (int i = 0; i < n; i++)
	{
		int tmp;
		scanf("%d", &tmp);
		vec[i] = tmp == 0 ? -1 : 1;
	}
	printf("%d", getMaxLen(vec, 0));
}

发表于 2019-08-10 12:57:14 回复(0)