523-Continuous Subarray Sum

本文介绍了一种中等难度的动态规划问题,旨在判断数组中是否存在至少包含两个元素的连续子数组,其总和为给定整数k的倍数。通过累加数组元素并利用哈希表记录特定余数首次出现的位置来解决该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类别:dynamic programming

难度:medium


题目描述

Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.

Example 1:

Input: [23, 2, 4, 6, 7],  k=6
Output: True
Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6.

Example 2:

Input: [23, 2, 6, 4, 7],  k=6
Output: True
Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42.

Note:

  1. The length of the array won't exceed 10,000.
  2. You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

算法分析

(1)首先,对数字进行累加运算

(2)因为对于两个数字,如果%k得到相同的余数,那么两者之差为k的整数倍

(3)由于需要用到除以k的操作,所以需要对k=0的情况做特别的处理(只要有两个相邻的0(或者以上)即可)

(4)这个算法的关键点是:a[i]+a[i+1]+....a[j] = S[j] - S[i - 1]

(5)判断是否满足条件,除了判断余数是否相同之外,还需要判断之间相邻的数目是否大于等于2

(6)用到了map的find操作,存储的是具有余数x的累加数的下标


代码实现

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        int n = nums.size();
        int sum = 0;
        if (n < 2) return false;
        //  因为后面用到取余操作,所以需要都除数为0的情况特殊考虑 
        if (k == 0) {
        	for (int i = 1; i < n; ++i) {
        		if (nums[i] == 0 && nums[i - 1] == 0) return true;
			}
			return false;
		}
        for (int i = 1; i < n; ++i) {
        	nums[i] += nums[i - 1];
            if (nums[i] % k == 0 && i != 0) return true;
		}
		map<int, int> remain;
		for (int i =  0; i < n; ++i) {
            // 两个数字如果除以k有同样的余数,说明两者之差为k的整数倍
			if (remain.find(nums[i] % k) == remain.end()) {
				remain[nums[i] % k] == i;
			} else {
				if (i - remain[nums[i] % k] > 1) return true;
			}
		}
	   return false;
    }
};


### Java Split Array Largest Sum Implementation Solution #### Problem Description Given an array `nums` which consists of non-negative integers and an integer `m`, split the array into `m` non-empty continuous subarrays. The goal is to minimize the largest sum among these `m` subarrays. To achieve this objective, binary search can be applied over possible values of the maximum subarray sum combined with a helper function that checks whether it's feasible to partition the array under certain constraints[^2]. #### Binary Search Approach The key idea lies in performing a binary search on the range between the minimum potential value (which would be the highest single element within the input list) up until the total summation of all elements inside said list as follows: ```java public class Solution { public int splitArray(int[] nums, int m) { long lo = 0; long hi = 0; for (int num : nums) { lo = Math.max(lo, num); hi += num; } while (lo < hi) { long mid = lo + (hi - lo) / 2; if (isFeasible(nums, m, mid)) { hi = mid; } else { lo = mid + 1; } } return (int) lo; } private boolean isFeasible(int[] nums, int m, long maxSumAllowed) { int currentSubarrayCount = 1; long currentSubarraySum = 0; for (int num : nums) { if (currentSubarraySum + num <= maxSumAllowed) { currentSubarraySum += num; } else { currentSubarrayCount++; if (currentSubarrayCount > m || num > maxSumAllowed) { return false; } currentSubarraySum = num; } } return true; } } ``` This code snippet demonstrates how to implement the solution using binary search along with checking feasibility through iteration across the given numbers array. By adjusting boundaries based upon results from testing midpoint against conditions set forth by problem requirements, optimal solutions may thus be found efficiently even when dealing with large datasets or complex scenarios involving multiple partitions.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值