最长连续子序列
题目描述
有N个正整数组成的一个序列, 给定整数sum, 求长度最长的连续子序列, 使他们的和等于sum, 返回此子序列的长度.
如果没有满足要求的序列, 返回-1
.
输入描述
- 第一行输入是: N个正整数组成的一个序列
- 第二行输入是: 给定整数sum
输出描述
最长的连续子序列的长度
备注:
- 输入序列仅由数字和英文逗号构成, 数字之间采用英文逗号分隔
- 序列长度:
1 <= N <= 200
- 输入序列不考虑异常情况
示例1
输入:
1,2,3,4,2
6
输出:
3
说明: 1,2,3和4, 2两个序列均能满足要求, 所以最长的连续序列为1,2,3, 因此结果为3.
示例2
输入:
1,2,3,4,2
20
输出:
-1
题解
Python
# 滑动窗口
def main():
nums = list(map(int, input().split(",")))
expected_sum = int(input())
assert 1 <= len(nums) <= 200
assert 1 <= expected_sum
# 最长子序的长度
subarray_max_len = -1
# 用于控制窗口左侧两侧的位置
left = 0
right = 0
# 计算当前子序列的和
current_sum = 0
while left <= right and right < len(nums):
if current_sum < expected_sum:
# 子序列的和太小, 将窗口右侧向右移
current_sum += nums[right]
right += 1
elif current_sum == expected_sum:
# 和相等, 计算当前的子序列长度
current_length = right - left
subarray_max_len = max(subarray_max_len, current_length)
current_sum += nums[right]
right += 1
else:
# 子序列的和太大, 将窗口左侧向右移
current_sum -= nums[left]
left += 1
print(subarray_max_len)
if __name__ == "__main__":
main()
Rust
#![allow(unused)] fn main() { use std::cmp::Ordering; use std::io::{stdin, BufRead}; // 滑动窗口 fn solution() { // 读取输入 let mut line = String::new(); let ret = stdin().lock().read_line(&mut line); assert!(ret.is_ok()); let nums: Vec<i32> = line.trim().split(',').map(|x| x.parse().unwrap()).collect(); line.clear(); let ret = stdin().lock().read_line(&mut line); assert!(ret.is_ok()); let expected_sum: i32 = line.trim().parse().unwrap(); // 最长子序的长度 let mut subarray_max_len: usize = 0; // 用于控制窗口左侧两侧的位置 let mut left: usize = 0; let mut right: usize = 0; // 计算当前子序列的和 let mut current_sum: i32 = 0; while left <= right && right < nums.len() { match current_sum.cmp(&expected_sum) { Ordering::Less => { // 子序列的和太小, 将窗口右侧向右移 current_sum += nums[right]; right += 1; } Ordering::Equal => { // 和相等, 计算当前的子序列长度 let current_length = right - left; subarray_max_len = subarray_max_len.max(current_length); // 并把窗口右侧向右移 current_sum += nums[right]; right += 1; } Ordering::Greater => { // 子序列的和太大, 将窗口左侧向右移 current_sum -= nums[left]; left += 1; } } } // 打印结果 println!("{subarray_max_len}"); } }
C++
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
// 滑动窗口
void solution() {
// 读取输入
std::string line;
std::cin >> line;
std::stringstream ss(line);
std::string part;
std::vector<int> nums;
while (std::getline(ss, part, ',')) {
const int num = std::stoi(part);
nums.push_back(num);
}
assert(1 <= nums.size() && nums.size() <= 200);
int expected_sum;
std::cin >> expected_sum;
assert(1 <= expected_sum);
// 最长子序的长度
int subarray_max_len = -1;
// 用于控制窗口左侧两侧的位置
int left = 0;
int right = 0;
// 计算当前子序列的和
int current_sum = 0;
while (left <= right && right < nums.size()) {
if (current_sum < expected_sum) {
// 子序列的和太小, 将窗口右侧向右移
current_sum += nums[right];
right += 1;
} else if (current_sum == expected_sum) {
// 和相等, 计算当前的子序列长度
const int current_length = right - left;
subarray_max_len = std::max(subarray_max_len, current_length);
current_sum += nums[right];
right += 1;
} else {
// 子序列的和太大, 将窗口左侧向右移
current_sum -= nums[left];
left += 1;
}
}
// 打印结果
std::cout << subarray_max_len << std::endl;
}