首页 > 试题广场 >

和为K的连续子数组

[编程题]和为K的连续子数组
  • 热度指数:18673 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个无序数组 arr , 其中元素可正、可负、可0。给定一个整数 k ,求 arr 所有连续子数组中累加和为k的最长连续子数组长度。保证至少存在一个合法的连续子数组。
[1,2,3]的连续子数组有[1,2],[2,3],[1,2,3] ,但是[1,3]不是

数据范围: 1 \le n \le 10^5
要求:空间复杂度 , 时间复杂度
示例1

输入

[1,-2,1,1,1],0

输出

3
示例2

输入

[0,1,2,3],3

输出

3

备注:
class Solution {
public:
    int maxlenEqualK(vector<int>& arr, int k) {
        int ans = 0;
        unordered_map<int, int>m;
        m[0] = -1;//为了解决//如果整个数组和刚好为k,也满足
        int temp = 0;
        for(int i = 0; i < arr.size(); i++) {
            temp += arr[i];
            if(m.find(temp - k) != m.end()) {
                ans = max(ans, i - m[temp - k]);
            }
            if(m.find(temp) == m.end()) {
                m[temp] = i;
            }
        }
        return ans;
    }
};
//全部满足的时候i = n - 1, 那么m[0] = -1, 所以长度为n - 1 + 1 = n

发表于 2021-08-08 23:46:18 回复(0)
public int maxlenEqualK (int[] arr, int k) {
         int sum=0;
	 int count=0;
	 for(int j=0;j<arr.length;j++) {
	    sum=0;
	    int tmp=0;
	    for(int i=j;i<arr.length;i++) {
		sum+=arr[i];
		tmp++;
		if(sum==k) {
		    if(count<tmp)
		        count=tmp;
		}
	    }
	    if(count>arr.length-j)
		break;
	 }
	return count;
    }

发表于 2020-12-13 17:21:27 回复(1)
import java.util.*;


public class Solution {
    /**
     * max length of the subarray sum = k
     * @param arr int整型一维数组 the array
     * @param k int整型 target
     * @return int整型
     */
    public int maxlenEqualK (int[] arr, int k) {
        // write code here
        int len = Integer.MIN_VALUE;
        int sum = 0;
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, -1);// 处理边界值

        // arr[i + 1, ..., j] = k
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
            // 只记录第一次的位置,因为要求最长数组
            if (!map.containsKey(sum)) {
                map.put(sum, i);
            }
            // 判断是否需要更新len
            if(map.containsKey(sum - k) && i - map.get(sum - k) > len){
                len = i - map.get(sum - k);
            }
        }

        return len;
    }
}

编辑于 2020-09-29 14:30:41 回复(0)
function maxlenEqualK( arr ,  k ) {
    // write code here
    let sum = 0
    let res = 0
    const map = new Map()
    let len = arr.length
    map.set(0,-1)   //应该从-1位置开始累加,也就是如果任何一个数都不加时,累加和为0, 
    for(let i=0;i<len;i++){
        sum += arr[i]
        let num = sum -k
        if(!map.has(sum)) map.set(sum,i)
        if( map.has(sum -k)) res = Math.max(res, i - map.get(sum -k)) 
    }
    return res
}

发表于 2020-12-29 18:26:08 回复(0)
public int maxlenEqualK (int[] arr, int k) {
        if(arr==null||arr.length==0) return 0;
        int sum=0;//记录从开头到第i个位置的总和
        HashMap<Integer,Integer>map=new HashMap<>();//记录每一个sum以及它出现的位置
        //基本思想是:如果第i个位置总和为a,第j个位置总和为b,那么在j位置时若发现b-a=k,则a-b之间就是总和为k的子数组
        map.put(0,-1);//初始化总和为0出现的位置
        int len=0;//最大长度
        for(int i=0;i<arr.length;i++){
            sum+=arr[i];
            if(map.containsKey(sum-k)) len=Math.max(len,i-map.get(sum-k));
            if(!map.containsKey(sum)) map.put(sum,i);
        }
        return len;
    }

发表于 2021-03-28 16:48:28 回复(0)
map 的 k 代表第一个元素到当前元素的累加值, v 代表当前元素的下标:
   public int maxlenEqualK(int[] arr, int k) {
        // 使用哈希表存储前缀和及其第一次出现的位置
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, -1); // 初始化,用于处理整个前缀和正好等于k的情况
        int sum = 0; // 当前前缀和
        int maxLength = 0; // 最长子数组的长度

        for (int i = 0; i < arr.length; i++) {
            sum += arr[i]; // 更新当前前缀和

            // 如果sum-k存在于map中,说明找到一个子数组的和为k
            if (map.containsKey(sum - k)) {
                maxLength = Math.max(maxLength, i - map.get(sum - k));
            }

            // 只记录每个前缀和第一次出现的位置
            if (!map.containsKey(sum)) {
                map.put(sum, i);
            }
        }

        return maxLength;
    }


编辑于 2024-04-24 21:53:46 回复(0)
class Solution { public:     int maxlenEqualK(vector<int>& arr, int k) {         int ans = 0;         unordered_map<int>m;         m[0] = -1;//为了解决//如果整个数组和刚好为k,也满足         int temp = 0;         for(int i = 0; i < arr.size(); i++) {             temp += arr[i];             if(m.find(temp - k) != m.end()) {                 ans = max(ans, i - m[temp - k]);             }             if(m.find(temp) == m.end()) {                 m[temp] = i;             }         }         return ans;     } }; //全部满足的时候i = n - 1, 那么m[0] = -1, 所以长度为n - 1 + 1 = n</int></int>
发表于 2024-04-19 08:53:51 回复(0)
我就想问下,这道题目,是不是对C语言有歧视?
发表于 2024-03-28 23:57:07 回复(0)
#include<utility>
#include<unordered_map>
#include<iosteam>
using namespace std;

class SOLVE
{
 public:
    int max_lenth_func(const vector<int>&vec,const int& k)
    {
        unordered_map<int,int>cavetable;
        int max_lenth =0 , all_sum=0;
        
        for(int i =0;i<vec.size();i++)
        {
            all_sum += vec[i];
            if(all_sum == k)
                max_lenth = i+1;
            
            if(cavetable.find([all_sum -k])!=cavetable.end())
            {
                max_lenth = max(max_lenth,i -cavetable[all_sum - k]);
            }
            
            if(cavetable.find(vec[i])!= cavetable.end())
            {
                cavetable[vec[i]] = i;
            }
        }
        return max_lenth;
    }
}

编辑于 2024-03-07 11:17:53 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * max length of the subarray sum = k
     * @param arr int整型一维数组 the array
     * @param k int整型 target
     * @return int整型
     */
    public int maxlenEqualK (int[] arr, int k) {
        // write code here
        int len = arr.length;
        Map<Integer, Integer> map = new HashMap<>();
        int[] preSum = new int[len + 1];
        for(int i = 1; i <= len; i++) {
            preSum[i] = preSum[i - 1] + arr[i - 1];
            map.put(preSum[i], i);
        }
        int res = 0;
        // k = pre[j] - pre[i] -> pre[j] = pre[i] + k
        for(int i = 0; i <= len; i++) {
            if(map.containsKey(preSum[i] + k)) {
                res = Math.max(res, map.get(preSum[i] + k) - i);
            }
        }
        return res;
    }
}

编辑于 2024-02-04 16:22:08 回复(0)
使用前缀和,
然后只需要找到两个前缀和只差等于k,
双指针肯定会超时,On2
所以要一层循环,固定区间的右边界,然后找到左边界(左边界的前缀和等于前缀和【右边界】-k)。
这个查找需要时logn。所以需要进行有序的查找,因此将所有的前缀和放在map中,前缀和作为键,下标位置作为值。既可以得到。
发表于 2023-06-30 23:15:08 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * max length of the subarray sum = k
     * @param arr int整型一维数组 the array
     * @param k int整型 target
     * @return int整型
     */
    public int maxlenEqualK (int[] arr, int k) {
        // write code here
        int sum=0;
        int length=0;
        for(int i=0;i<arr.length;i++)
        {
            sum=0;
            if(length>(arr.length-i+1))
            {
                break;
            }
            for(int j=i;j<arr.length;j++)
            {
                sum=sum+arr[j];
                if(sum==k)
                {
                    if((j-i+1)>length)
                    {
                       length=j-i+1; 
                    }
                }
            }
        }
        return length;
    }
}
发表于 2022-07-12 16:47:54 回复(0)
int maxlenEqualK(int* arr, int arrLen, int k ) {
    // write code here
    int sum=0;
    int count=0;
    for(int j=0;j<arrLen;j++)
    {
        sum=0;
        int tmp=0;
        for(int i=j;i<arrLen;i++){
            sum+=arr[i];
            tmp++;
            if(sum==k){
                if(count<tmp)
                    count=tmp;
            }
        }
        if(count>arrLen-j)
            break;
    }
    return count;
}
发表于 2022-05-19 02:19:18 回复(0)
function maxlenEqualK( arr ,  k ) {
    // write code here
    let count = 0
    let n = arr.length
    for(let i=0;i<n;i++) {
       let sum = 0
       let temp = 0
       for(let j=i;j<n;j++) {
           sum += arr[j]
           temp++
           if (sum === k) {
               count = Math.max(count,temp)
           }
       }
       if(count>n-i) break;
    }
    return count
}
发表于 2022-04-15 19:18:27 回复(0)
class Solution {
public:
    unordered_map<int,int>mp;
    int maxlenEqualK(vector<int>& arr, int k) {
        if(arr.size()==0)
             return 0;
        int ans=1;
        int sum=0;
        mp[0]=0;
        for(int i=0;i<arr.size();i++)
        {
            sum+=arr[i];
            if(mp.count(sum-k)>0)
            {
                int te=mp[sum-k]-1;
                ans=max(ans,i-te);
            }
            if(mp.count(sum)<=0)
                mp[sum]=i+1;
        }
        return ans;
    }
};
发表于 2022-03-04 10:06:01 回复(0)

思路分析:
1) 题目说了 需要寻找数组中最长连续子数组的和为k的长度,于是我们可以 循环遍历数组,每个索引位置,都可以作为 子数组的开头,所以可以定义一个 子函数maxlenFromNowEqualK(),用来计算这个 索引开头的子数组的和为k的最大长度 nowLength,然后和已经获取到的 最大的连续子数组的长度 maxLength
做对比,取最大的值即可,还有就是要注意 当 剩余的索引位置的数组长度已经比已经获取到的 满足条件的最长子数组的长度时,就直接 break 终止循环即可,最终返回这个 结果 maxLength即可

【代码】
import java.util.*;


public class Solution {
    /**
     * max length of the subarray sum = k
     * @param arr int整型一维数组 the array
     * @param k int整型 target
     * @return int整型
     */
    public int maxlenEqualK (int[] arr, int k) {
        // write code here
        return doMaxlenEqualK(arr, k);
         
    }
     
    public int doMaxlenEqualK (int[] arr, int k) {
        // write code here
        if(null == arr || arr.length == 0){
            return 0;
        }
        int len = arr.length;
        int maxLength = 0;
        int nowLength = 0;
        for(int i = 0; i < len; i++){
            if(len - i < maxLength){
                break;
            }
            // 获取以 i为开头的最长连续子数组和为 k的长度
            nowLength = maxlenFromNowEqualK(arr, k, i);
            maxLength = Math.max(maxLength, nowLength);


        }
        
        return maxLength;
         
    }
    
    private int maxlenFromNowEqualK(int[] arr, int k, int i){
        int len = arr.length;
        int maxCnt = 0;
        int sum = 0;
        int nowCnt = 0;
        for(int j = i; j < len; j++){
            if(sum == k){
                maxCnt =  Math.max(maxCnt, nowCnt);
            }
            sum += arr[j];
            nowCnt++;
            if(sum == k){
                maxCnt =  Math.max(maxCnt, nowCnt);
            }
        }
        return maxCnt;
    }
}



发表于 2022-02-20 11:31:06 回复(0)
对于每个arr[i],将前缀和arr[0]+......+arr[i],以及i存入字典的key,value中
如果两个前缀和的差值为k,说明它们中间那段子数组的和为k。我们可以通过两个index的差值得到子数组长度
class Solution:
    def maxlenEqualK(self , arr: List[int], k: int) -> int:
        # write code here
        d = {0:-1} # d记录前缀和,以及该前缀和对应的最小index
        total, maxlen = 0, 0 # total记录前缀和,maxlen记录最大长度
        for i in range(len(arr)):
            total += arr[i] # 更新前缀和
            if total-k in d:# 如果有前缀和等于total-k,说明中间连续子串之和为k
                if maxlen < i-d[total-k]: maxlen = i-d[total-k] # 子数组长度为index的差值,并更新maxlen
            if total not in d: # 如果该前缀和已存在,则只保留之前最小的index
                d[total] = i # 如果不存在,将前缀和及其index计入d,
        return maxlen

发表于 2022-02-02 16:46:47 回复(0)
class Solution:
    def maxlenEqualK(self , nums: List[int], k: int) -> int:
        # write code here
        dic={}
        max_len,sum_v=0,0
        dic[0]=-1
        for i in range(len(nums)):
            sum_v+=nums[i]
            if (sum_v-k in dic.keys()):
                max_len=max(i-dic[sum_v-k],max_len)
            if sum_v not in dic.keys():
                #重复也保留最小的那一个
                dic[sum_v]=i
        return max_len

发表于 2022-01-19 04:35:23 回复(1)
import java.util.*;


public class Solution {
    /**
     * max length of the subarray sum = k
     * @param arr int整型一维数组 the array
     * @param k int整型 target
     * @return int整型
     */
    public int maxlenEqualK (int[] nums, int k) {
       //连续子数组问题
        //前缀和
        int n=nums.length;

        Map<Integer,Integer> map=new HashMap<>();
        int[]pre=new int[n+1];
        for(int i=1;i<=n;i++) pre[i]=pre[i-1]+nums[i-1];
        // a-b=k  
        map.put(0,0);
        int res=1;
        for(int i=1;i<=n;i++){
            if(map.containsKey(pre[i]-k)){
                int j=map.get(pre[i]-k);
                res=Math.max(res,i-j);//i表示个数 
            }
            if(!map.containsKey(pre[i])) map.put(pre[i],i);
        }
        return res;
    }
}
发表于 2022-01-01 16:13:35 回复(0)
此答案超时
class Solution {
public:
    /**
     * max length of the subarray sum = k
     * @param arr int整型vector the array
     * @param k int整型 target
     * @return int整型
     */
    int maxlenEqualK(vector<int>& arr, int k) {
        // write code here
        int n = arr.size(), ans = 0;
        for (int i = 0; i < n; i++) {
            int sum = 0;
            vector<int> tmp;
            for (int j = i; j < n; j++) {
                sum += arr[j];
                tmp.push_back(arr[j]);
                if (sum == k) {
                    ans = ans > tmp.size() ? ans : tmp.size();
                }
            }
        }
        return ans;
    }
};

发表于 2021-12-08 15:21:26 回复(0)

问题信息

难度:
37条回答 4243浏览

热门推荐

通过挑战的用户

查看代码