给定一个无序数组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)); }