给定一个无序数组arr, 其中元素可正、可负、可0。给定一个整数k,求arr所有子数组中累加和为k的最长子数组长度
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,x;
cin>>n>>x;
vector<int>res(n);
for(int i=0;i<n;i++)
cin>>res[i];
map<int,int> hm;
hm[0] = -1;
int len = 0, sum = 0;
for (int i = 0; i < res.size(); i++){
sum += res[i];
if (hm.find(sum - x) != hm.end())
len = max(len, i - hm.find(sum - x)->second);
if (hm.find(sum) == hm.end())
hm[sum] = i;
}
cout<<len;
return 0;
} 循环遍历每个数字,记录累加结果,找到sums-k
while True:
try:
n, k = map(int,input().split())
inputs = list(map(int,input().split()))
sums = 0
res = 0
dict = {0:-1}
for i in range(n):
sums+=inputs[i]
if sums not in dict:
dict[sums]=i
if sums-k in dict:
res=max(res,i-dict[sums-k])
print(res)
except:break
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, k, Max=0;
cin>>n>>k;
int a[n];
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];
if(M.find(s-k)!=M.end())
Max = max(Max, i-M[s-k]);
if(M.find(s)==M.end())
M[s] = i;
}
cout<<Max<<endl;
return 0;
} import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = 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 sum = 0,maxLen = 0;
for(int i=0;i<n;i++){
sum += arr[i];
if(!map.containsKey(sum)){
map.put(sum,i);
}
if(map.containsKey(sum-k)){
maxLen = Math.max(maxLen,i-map.get(sum-k));
}
}
System.out.print(maxLen);
}
} package com.hhdd.leetcode;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;
/**
* 求最长子数组的累加和为k
*/
public class MaxLengthAddEqualsK {
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];
int k =scanner.nextInt();
for (int i = 0; i < arr.length; i++) {
arr[i] = scanner.nextInt();
}
int ans = maxLength(arr,k);
System.out.println(ans);
}
}
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));
String[] params = br.readLine().split(" ");
int n = Integer.parseInt(params[0]), k = Integer.parseInt(params[1]);
params = br.readLine().split(" ");
int[] arr = new int[n];
for(int i = 0; i < n; i++) arr[i] = Integer.parseInt(params[i]);
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int presum = 0, maxLen = 0;
for(int i = 0; i < n; i++){
presum += arr[i];
if(map.containsKey(presum - k))
maxLen = Math.max(maxLen, i - map.get(presum - k));
if(!map.containsKey(presum))
map.put(presum, i);
}
System.out.println(maxLen);
}
} import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashMap;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static int MAXN = 100001;
public static int[] arr = new int[MAXN];
public static int n, aim;
// key : 某个前缀和
// value : 这个前缀和最早出现的位置
public static HashMap<Integer, Integer> map = new HashMap<>();
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(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
n = (int) in.nval;
in.nextToken();
aim = (int) in.nval;
for (int i = 0; i < n; i++) {
in.nextToken();
arr[i] = (int) in.nval;
}
out.println(compute());
}
out.flush();
out.close();
br.close();
}
public static int compute() {
map.clear();
// 重要 : 0这个前缀和,一个数字也没有的时候,就存在了
map.put(0, -1);
int ans = 0;
for (int i = 0, sum = 0; i < n;
i++) { /// 在循环中求解 以i为结尾的子数组的最大长度
sum += arr[i]; /// 当前的总的 sum
if (map.containsKey(sum - aim)) {
// 60 i 到达i时候的和是100,aim=40
// 0...13 14 15 16 /// 16-13
ans = Math.max(ans, i - map.get(sum - aim)); /// 求最大长度
}
if (!map.containsKey(
sum)) { /// 只有不包含才进行加入,因为map记录的是最早的,第一次
map.put(sum, i);
}
}
return ans;
}
} #include "bits/stdc++.h"
using namespace std;
int main()
{
int len;cin>>len;
int target;cin>>target;
unordered_map<int,int> ump;
int sum=0;
int cur;
vector<int> arr(len);
for(int i=0;i<len;i++)
{
cin>>cur;
sum+=cur;
ump[sum]=i;
arr[i]=sum;
}
int ret=0;
for(int i=0;i<len;i++)
{
if(arr[i]==target) ret=max(ret,i+1);
if((ump.count(target+arr[i])==1)&&ump[target+arr[i]]>i)
{
int k=ump[target+arr[i]]-i;
ret=max(ret,k);
}
}
cout<<ret;
return 0;
} package main
import (
"fmt"
)
func main() {
var (
n int
k int
num int
)
fmt.Scan(&n,&k)
arr := make([]int,n)
for i:=0;i<n;i++ {
fmt.Scan(&num)
arr[i] = num
}
result := getMaxLength(arr,k)
fmt.Printf("%d\n",result)
}
func getMaxLength(arr []int, k int) int {
if len(arr) == 0 {
return 0
}
length, sum := 0, 0
m := make(map[int]int)
//初始化位置
m[0] = -1
for i :=0;i<len(arr);i++ {
sum += arr[i]
if v,ok := m[sum-k];ok {
length = max(length,i-v)
}
if _,ok := m[sum]; !ok {
m[sum] = i
}
}
return length
}
func max(a,b int) int {
if a>b {
return a
}
return b
}
#include<iostream>
#include<map>
#include<vector>
using namespace std;
int main()
{
int N,k,res=0,sum=0;
cin>>N>>k;
map<int,int> map;
map[0]=-1;
vector<int> arr(N,0);
for(int i=0;i<N;++i){
cin>>arr[i];
}
for(int i=0;i<arr.size();++i){
sum+=arr[i];
if(map.find(sum)==map.end()){
map[sum]=i;
}
if(map.find(sum-k)!=map.end()){
res=max(res,i-map[sum-k]);
}
}
cout<<res<<endl;
} import java.util.Scanner;
import java.util.HashMap;
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i<n; i++){
arr[i] = sc.nextInt();
}
System.out.println(getMaxLength(arr,k));
}
public static int getMaxLength(int[] arr,int k){
if(arr==null||arr.length==0){
return 0;
}
HashMap<Integer,Integer> map=new HashMap<Integer,Integer>();
map.put(0,-1);
int len=0;
int sum=0;
for(int i=0;i<arr.length;i++){
sum+=arr[i];
if(map.containsKey(sum-k)){
len=Math.max(i-map.get(sum-k),len);
}
if(!map.containsKey(sum)){
map.put(sum,i);
}
}
return len;
}
} package test;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = scanner.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
// solution
Map<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int maxLen = 0, curSum = 0;
for (int i = 0; i < n; i++) {
curSum += arr[i];
if (!map.containsKey(curSum)) {
map.put(curSum, i);
}
int gap = curSum - k;
if (map.containsKey(gap)) {
maxLen = Math.max(i - map.get(gap), maxLen);
}
}
System.out.println(maxLen);
}
}
/*
【示例1】
11 0
1 -2 1 1 1 -1 1 -1 1 -1 2
答案:9
解析:1 [-2 1 1 1 -1 1 -1 1 -1] 2
【示例2】
20 0
-1 1 0 4 5 -2 2 -2 2 -2 2 -4 4 5 -2 -2 -1 1 1 1
答案:12
解析:-1 1 0 4 5 [-2 2 -2 2 -2 2 -4 4 5 -2 -2 -1] 1 1 1
*/ sums,sums[j]-sums[i]可以表达[i, j)区间和 0->n-1,右指针从n->左指针位置+现有的最大长度(由于只需要找最长的,因此可以直接提高下界) ps. sums为了处理方便,多加了一个0值
详见代码
#include <bits/stdc++.h>
int main()
{
int n, k;
int ret=0;
std::cin >> n >> k;
int arr[n];
int sums[n+1];
memset(sums, 0, sizeof(sums));
for(int i=0; i<n; ++i)
{
std::cin >> arr[i];
sums[i+1] = sums[i] + arr[i];
}
for(int i=0; i<n; ++i)
{
for(int j=n; j-i>ret; --j)
{
if(sums[j] - sums[i] == k)
{
ret = std::max(ret, j-i);
break;
}
}
}
std::cout << ret;
}
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, k;
cin>>n>>k;
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];
v[i] += v[i-1];
if(m.find(v[i]-k) != m.end())
res = max(res, i-m[v[i]-k]);
if(m.find(v[i]) == m.end())
m[v[i]] = i;
}
cout<<res;
return 0;
} #include<vector>
(721)#include<iostream>
#include<map>
using namespace std;
int main(){
size_t n;
int k;
std::cin >> n >> k;
vector<int> sums(n + 1, 0);
for(int i = 0; i < n; i++){
int temp;
std::cin >> temp;
sums[i + 1] = sums[i] + temp;
}
int longest = 0;
for(int i = 1; i < sums.size(); i++){
if(sums[i] == k){
longest = max(longest, i);
}else{
for(int j = 1; j < i; j++){
int subSum = sums[i] - sums[j];
if(subSum == k){
longest = max(longest, i - j);
break;
}else if(i - j <= longest){
break;
}
}
}
}
std::cout << longest << std::endl;;
return 0;
} #include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
int main() {
int N, K;
cin >> N >> K;
vector<int> v(N);
unordered_map<int, int> m;
for (int i = 0; i < N; ++i) {
cin >> v[i];
}
m.insert(make_pair(0,-1));
int index = 0;
int len = 0;
int sum = 0;
while (index < N) {
sum += v[index];
m.insert(make_pair(sum,index));
auto it = m.find(sum - K);
if (it != m.end()) {
len = max(len, index - (*it).second);
}
index++;
}
cout << len << endl;
return 0;
} #include<bits/stdc++.h>
using namespace std;
#define N 100005
int main()
{
long n,k;
cin>>n>>k;
vector<long>v(n+1);
for(int i=1;i<=n;++i)
cin>>v[i];
long long temp;
int ans = 1;
for(int i=1;i<=n;++i)
{
for(int j=i;j<=n;++j)
{
if(j==i)
temp=v[i];
else
{
temp+=v[j];
if(temp==k)
ans = max(ans,j-i+1);
}
}
// 这步很关键 参考大佬的思路 ,剪枝 时间优化 不然只过70%
if(ans>n-i)
break;
}
cout<<ans<<endl;
return 0;
}