1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
java解法
解题思路 本题要求在给定的数组中,找到和为 targetSum 的最长子数组的长度。该问题本质上是寻找一个和为给定值的连续子数组,并返回其最大长度。我们可以通过暴力法(两层循环)来解决这个问题。
关键思路: 暴力法:我们可以通过两层循环来遍历数组的所有子数组。在外层循环中,我们固定子数组的起始位置 start,在内层循环中遍历从 start 到数组末尾的所有可能的子数组结尾位置 end,计算每个子数组的和。
条件判断:如果某个子数组的和等于 targetSum,就更新最大长度 maxLength。
时间复杂度:这种方法的时间复杂度为 O(n²),其中 n 是数组的长度。因为我们对于每个可能的子数组,都要计算其和。
算法步骤: 输入处理:读取数组和目标值 targetSum。 解析输入:将输入的字符串分割并转换为整数数组。 暴力查找:通过两层循环,计算每个可能的子数组和,若等于目标值,更新最大长度。 返回结果:输出找到的最大长度
import java. util. Scanner ;
public class Main {
public static void main ( String [ ] args) {
Scanner scanner = new Scanner ( System . in) ;
int [ ] numbers = parseSequence ( scanner. nextLine ( ) ) ;
int sum = Integer . parseInt ( scanner. nextLine ( ) ) ;
System . out. println ( findMaxSubarrayLength ( numbers, sum) ) ;
}
public static int [ ] parseSequence ( String input) {
String [ ] tokens = input. split ( "," ) ;
int [ ] result = new int [ tokens. length] ;
for ( int i = 0 ; i < tokens. length; i++ ) {
result[ i] = Integer . parseInt ( tokens[ i] ) ;
}
return result;
}
public static int findMaxSubarrayLength ( int [ ] numbers, int targetSum) {
int maxLength = - 1 ;
for ( int start = 0 ; start < numbers. length; start++ ) {
int currentSum = 0 ;
for ( int end = start; end < numbers. length; end++ ) {
currentSum += numbers[ end] ;
if ( currentSum == targetSum) {
maxLength = Math . max ( maxLength, end - start + 1 ) ;
}
}
}
return maxLength;
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
C++解法
更新中
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
C解法
关键思路: 滑动窗口:我们通过两个指针 left 和 right 来维持一个“窗口”,窗口内的元素之和小于等于 targetSum。每次扩展窗口(即增加 right 指针),当当前窗口的和大于 targetSum 时,我们通过移动 left 指针来缩小窗口,直到当前窗口的和不大于 targetSum。
动态更新窗口:每次找到符合条件的窗口时,检查该窗口的大小是否是目前找到的最大值,并更新最大长度。
时间复杂度:这个方法的时间复杂度是 O(n),其中 n 是数组的长度。通过滑动窗口技巧,left 和 right 每个指针最多只会遍历一次数组,因此时间复杂度为线性
# include
# include
# include
int * parseInput ( char * input, int * length) {
char * token = strtok ( input, "," ) ;
int * result = malloc ( 100 * sizeof ( int ) ) ;
int index = 0 ;
while ( token != NULL ) {
result[ index++ ] = atoi ( token) ;
token = strtok ( NULL , "," ) ;
}
* length = index;
return result;
}
int findLongestSubarray ( int * nums, int length, int targetSum) {
int maxLen = - 1 ;
int currentSum = 0 ;
int left = 0 ;
for ( int right = 0 ; right < length; right++ ) {
currentSum += nums[ right] ;
while ( currentSum > targetSum && left <= right) {
currentSum -= nums[ left++ ] ;
}
if ( currentSum == targetSum) {
if ( right - left + 1 > maxLen) {
maxLen = right - left + 1 ;
}
}
}
return maxLen;
}
int main ( ) {
char input[ 100 ] ;
fgets ( input, sizeof ( input) , stdin ) ;
input[ strcspn ( input, "\n" ) ] = 0 ;
int length;
int * nums = parseInput ( input, & length) ;
int targetSum;
scanf ( "%d" , & targetSum) ;
printf ( "%d\n" , findLongestSubarray ( nums, length, targetSum) ) ;
free ( nums) ;
return 0 ;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
JS解法
关键思路: 前缀和(Prefix Sum): 前缀和是指数组中某个位置之前(包括当前位置)的元素和。我们可以通过维护当前的前缀和来快速计算某一范围内的子数组的和。
哈希表(Map): 我们使用哈希表来记录每个前缀和首次出现的位置。具体地,假设当前索引为 i,当前前缀和为 prefixSum,我们希望找到一个之前的索引 j 使得 prefixSum - sum 出现在哈希表中,这样就能得到一个和为 sum 的子数组。子数组的长度就是 i - j。
具体步骤:
初始化一个哈希表 prefixSumMap,用来存储每个前缀和首次出现的索引,最初将 prefixSumMap[0] = -1,表示如果当前前缀和等于目标和 sum,从 0 到当前位置就是一个合法的子数组。 遍历数组,计算当前的前缀和 prefixSum,并检查 prefixSum - target 是否已经出现在哈希表中。如果出现,则说明找到了一个和为 target 的子数组,更新最大子数组长度 maxLen。 最终返回最长子数组的长度。 时间复杂度: 时间复杂度为 O(n),其中 n 是数组的长度。我们只遍历一次数组,并且每次操作哈希表的查询和更新都是常数时间 O(1)。 空间复杂度: 空间复杂度为 O(n),用于存储哈希表
async function main ( ) {
const input = await getInput ( ) ;
const nums = input[ 0 ] . split ( "," ) . map ( Number) ;
const target = Number ( input[ 1 ] ) ;
console. log ( findLongestSubsequence ( nums, target) ) ;
}
function getInput ( ) {
return new Promise ( ( resolve ) => {
const rl = require ( 'readline' ) . createInterface ( { input : process. stdin } ) ;
const inputs = [ ] ;
rl. on ( 'line' , ( line ) => inputs. push ( line) )
. on ( 'close' , ( ) => resolve ( inputs) ) ;
} ) ;
}
function findLongestSubsequence ( nums, sum ) {
const prefixSumMap = new Map ( ) ;
prefixSumMap. set ( 0 , - 1 ) ;
let maxLen = - 1 ;
let prefixSum = 0 ;
for ( let i = 0 ; i < nums. length; i++ ) {
prefixSum += nums[ i] ;
if ( prefixSumMap. has ( prefixSum - sum) ) {
maxLen = Math. max ( maxLen, i - prefixSumMap. get ( prefixSum - sum) ) ;
}
if ( ! prefixSumMap. has ( prefixSum) ) {
prefixSumMap. set ( prefixSum, i) ;
}
}
return maxLen;
}
main ( ) ;
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。 解题不易,如对您有帮助,欢迎点赞/收藏
评论记录:
回复评论: