java解法

关键思路:
暴力法:我们可以通过两层循环来遍历数组的所有子数组。在外层循环中,我们固定子数组的起始位置 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());

        // 输出结果,调用findMaxSubarrayLength函数计算最大长度
        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;  // 返回解析后的数组
    }

    // 找到和为targetSum的最长子数组的长度
    public static int findMaxSubarrayLength(int[] numbers, int targetSum) {
        int maxLength = -1;  // 初始化最大长度,-1表示没有找到符合条件的子数组

        // 外层循环:遍历数组中的每个起始位置
        for (int start = 0; start < numbers.length; start++) {
            int currentSum = 0;  // 初始化当前子数组的和

            // 内层循环:遍历从start到数组末尾的每个结束位置
            for (int end = start; end < numbers.length; end++) {
                currentSum += numbers[end];  // 更新当前子数组的和

                // 如果当前子数组的和等于targetSum
                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"}">

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, ",");  // 使用strtok以逗号分隔字符串
    int* result = malloc(100 * sizeof(int));  // 分配一个较大的内存空间,假设最大输入为100个数
    int index = 0;

    // 遍历所有的token,将其转换为整数并存储到结果数组中
    while (token != NULL) {
        result[index++] = atoi(token);  // 使用atoi将字符串转换为整数
        token = strtok(NULL, ",");  // 获取下一个token
    }

    *length = index;  // 将数组的长度存入length中
    return result;  // 返回解析得到的整数数组
}

// 使用滑动窗口技术查找和为targetSum的最长子数组
int findLongestSubarray(int* nums, int length, int targetSum) {
    int maxLen = -1;  // 初始化最大长度为-1,表示如果没有找到子数组,则返回-1
    int currentSum = 0;  // 当前窗口的和
    int left = 0;  // 滑动窗口的左指针

    // 遍历数组,右指针从0到length-1
    for (int right = 0; right < length; right++) {
        currentSum += nums[right];  // 将当前元素加入到窗口中,更新当前和

        // 当当前窗口的和大于targetSum时,移动左指针缩小窗口
        while (currentSum > targetSum && left <= right) {
            currentSum -= nums[left++];  // 从窗口中移除左边的元素,并将左指针向右移动
        }

        // 如果当前窗口的和等于targetSum,更新最大长度
        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);  // 读取目标和

    // 调用findLongestSubarray函数计算结果并打印
    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"}">

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));  // 输入完成后返回输入数组
    });
}

// 查找和为target的最长连续子数组
function findLongestSubsequence(nums, sum) {
    const prefixSumMap = new Map();  // 用哈希表记录前缀和和其对应的索引
    prefixSumMap.set(0, -1);  // 初始前缀和为0,对应的索引为-1
    let maxLen = -1;  // 存储最长子数组的长度
    let prefixSum = 0;  // 当前前缀和

    // 遍历数组
    for (let i = 0; i < nums.length; i++) {
        prefixSum += nums[i];  // 更新当前前缀和

        // 检查前缀和是否已经出现过,若出现过,说明存在一个和为target的子数组
        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();  // 调用main函数,开始执行

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/145065075"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!