给定一个无序数组arr,其中元素可正、可负、可0。求arr所有子数组中正数与负数个数相等的最长子数组的长度。
[要求]
时间复杂度为
,空间复杂度为
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().trim());
String[] strArr = br.readLine().split(" ");
int[] arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(strArr[i]);
}
int balance = 0, maxLen = 0;
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
for(int i = 0; i < n; i++){
if(arr[i] == 0) continue;
balance += arr[i] > 0? 1: -1;
if(map.containsKey(balance)){
maxLen = Math.max(maxLen, i - map.get(balance));
}else{
map.put(balance, i);
}
}
System.out.println(maxLen);
}
} #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-1];
else if(v[i] < 0)
v[i] = -1 + v[i-1];
else
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;
} #include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[n], Max=0;
map<int,int> M;
M[0] = -1;
for(int i=0,s=0;i<n;i++){
cin>>a[i];
if(a[i]>0)
s++;
else if(a[i]<0)
s--;
if(M.find(s)!=M.end())
Max = max(Max, i-M[s]);
else
M[s] = i;
}
cout<<Max<<endl;
return 0;
} import java.io.*;
import java.util.HashMap;
public class Main {
public static int N;
public static int[] arr=new int[100001];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(System.out);
while (in.nextToken() != StreamTokenizer.TT_EOF) {
N=(int)in.nval;
for (int i = 0; i < N; i++) {
in.nextToken();
arr[i]=(int)in.nval;
}
out.println(positivesEqualsNegtivesLongestSubarray());
}
out.flush();
out.close();
br.close();
}
public static int positivesEqualsNegtivesLongestSubarray() {
int[] count=new int[N];
int sum=0;
int length=0;
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1); // 初始化,处理从0开始的子数组
for (int i = 0; i < N; i++) {
if(arr[i]>0) sum++;
else if(arr[i]<0) sum--;
else{
sum=sum;
}
if (map.containsKey(sum)) {
length = Math.max(length, i - map.get(sum));
} else {
map.put(sum, i);
}
}
return length;
}
}
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String[] str = in.readLine().split(" ");
int n = Integer.parseInt(str[0]);
int[] arr = new int[n];
int j = 0;
for(String i:in.readLine().split(" ")){
arr[j++] = Integer.parseInt(i);
}
System.out.println(getLength(arr));
}
static int getLength(int[] arr){
int len = 0;
int sum = 0;
HashMap<Integer,Integer> map = new HashMap<>();
map.put(0,-1);
for(int i=0;i<arr.length;i++){
if(arr[i]>0)
arr[i] = 1;
if(arr[i]<0)
arr[i] = -1;
}
for(int i=0;i<arr.length;i++){
sum += arr[i];
if(!map.containsKey(sum))
map.put(sum,i);
if(map.containsKey(sum))
len = Math.max(i - map.get(sum),len);
}
return len;
}
} import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine().trim());
int[] arr = new int[len];
String[] rawData = br.readLine().trim().split(" ");
for (int i = 0; i < len; i++) {
int tmp = Integer.parseInt(rawData[i]);
if(tmp > 0) {
arr[i] = 1;
} else if (tmp < 0) {
arr[i] = -1;
}
}
// 求符合条件的子数组长度, 和为0的最长子数组长度
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int max = 0, currentSum = 0;
for (int i = 0; i < len; i++) {
currentSum += arr[i];
if (map.containsKey(currentSum)) {
int j = map.get(currentSum);
max = Math.max(i - j, max);
}
if (!map.containsKey(currentSum)) {
map.put(currentSum, i);
}
}
System.out.print(max);
}
} import java.io.*;
public class Main {
public static void main(String[] args) {
BufferedReader br = null;
int n = 0;
String nums = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
nums = br.readLine();
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (br.readLine() != null)
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int[] numbers = new int[n];
boolean hasZero = false;
int negtiveCounter = 0;
int normalCounter = 0;
int len = 0;
String[] arr = nums.split(" ");
System.out.println("arr.length=" +arr.length);
if (arr.length == n) {
for ( int i = 0; i < arr.length; i++) {
//遍历数组分别统计正数,负数的个数,并标记是否含“0”元素
numbers[i] = Integer.parseInt(arr[i]);
if (numbers[i] < 0)
negtiveCounter++;
else if (numbers[i] > 0) {
normalCounter++;
} else
hasZero = true;
}
} else {
System.exit(-1);
}
//统计:取正数个数和负数个数的最小值,这个值就是正数负数一一对应的个数,再考虑数组是否含“0”
if(negtiveCounter == 0 || normalCounter==0) {
len = 0;
} else {
if (hasZero)
len = 2*Math.min(negtiveCounter, normalCounter)+1;
else
len = 2*Math.min(negtiveCounter, normalCounter);
}
System.out.println(len);
}
}
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<>();
//key为 正数个数-负数个数
map.put(0,-1);
int key = 0,maxLen = 0;
for(int i=0;i<n;i++){
key += arr[i]==0?0:arr[i]/Math.abs(arr[i]);
if(map.containsKey(key)){
maxLen = Math.max(maxLen,i-map.get(key));
}else{
map.put(key,i);
}
}
System.out.print(maxLen);
}
} // 与上一题类似,这里相当于将正数看做1,负数看做-1。计算总和为0的最长子数组长度。
import java.util.Scanner;
import java.util.HashMap;
public class Main{
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
HashMap<Integer,Integer> map = new HashMap<>();
int N = sc.nextInt();
int sum = 0, val = 0, len = 0;
for(int i = 0; i < N ; i++){
val = sc.nextInt();
if(val > 0)
sum ++;
else if(val < 0)
sum--;
if(sum == 0){ // 如果sum刚好为0则数组[0~i]为最长数组。这里相当于预先在map中加入(0,-1)
len = i + 1;
continue;
}
if(map.containsKey(sum)){
len = len > i - map.get(sum) ? len : i - map.get(sum);
}else{
map.put(sum ,i);
}
}
System.out.println(len);
sc.close();
}
} 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<0){
arr[i] = -1;
}else if(temp>0){
arr[i] = 1;
}else {
arr[i] = 0;
}
}
int ans = maxLength(arr,0);
System.out.println(ans);
}
}
#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 ? 0 : (tmp > 0 ? 1 : -1);
}
printf("%d", getMaxLen(vec, 0));
}