OD统一考试(E卷)
分值: 100分
题解: Java / Python / C++
2024华为OD机试(E卷+D卷+C卷)最新题库【超值优惠】Java/Python/C++合集
题目描述
有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。
题解
这个题目属于“滑动窗口”或“双指针”类型的题目,目的是在一个整数数组中找到和等于给定整数
sum
的连续子序列,并返回此子序列的最大长度。如果没有满足要求的序列,返回 -1。解题思路
- 滑动窗口:我们可以使用两个指针(或称作滑动窗口的左右边界),用一个窗口表示当前的子序列。我们逐渐向右移动右边界来扩大窗口,当窗口内的和超过
sum
时,我们移动左边界来缩小窗口。当窗口内的和刚好等于sum
时,记录窗口的长度,并与当前最长的长度比较。- 步骤:
- 初始化两个指针
left
和right
,表示窗口的左右边界,left
从序列开始,right
开始遍历序列。- 使用一个变量
current_sum
记录当前窗口的元素和。- 如果
current_sum
大于sum
,则需要收缩左边界(移动left
),直到current_sum
小于等于sum
。- 如果
current_sum
等于sum
,更新最长子序列的长度。- 重复这个过程直到
right
遍历完序列。- 时间复杂度:由于每个元素最多会被访问两次(一次作为右边界,一次作为左边界),所以时间复杂度为 O(N),其中 N 是数组的长度。
Java
import java.util.Arrays;
import java.util.Scanner;
/**
* @author code5bug
*/
public class Main {
public static int longestSubsequenceWithSum(int[] nums, int targetSum) {
int n = nums.length;
int left = 0, currentSum = 0, maxLength = -1;
for (int right = 0; right < n; right++) {
currentSum += nums[right];
// 当当前窗口的和大于目标值时,缩小窗口
while (currentSum > targetSum) {
currentSum -= nums[left];
left++;
}
// 如果当前窗口的和等于目标值,更新最大长度
if (currentSum == targetSum) {
maxLength = Math.max(maxLength, right - left + 1);
}
}
return maxLength;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 输入处理
int[] nums = Arrays.stream(scanner.nextLine().split(","))
.mapToInt(Integer::parseInt).toArray();
int targetSum = scanner.nextInt();
// 输出结果
int result = longestSubsequenceWithSum(nums, targetSum);
System.out.println(result);
}
}
Python
def longest_subsequence_with_sum(nums, target_sum):
n = len(nums)
left = 0
current_sum = 0
max_length = -1
for right in range(n):
current_sum += nums[right]
# 如果当前窗口的和大于目标值,则收缩窗口
while current_sum > target_sum:
current_sum -= nums[left]
left += 1
# 如果找到和为目标值的子序列,更新最大长度
if current_sum == target_sum:
max_length = max(max_length, right - left + 1)
return max_length
# 输入处理
sequence = input().strip() # 获取输入的序列
target_sum = int(input().strip()) # 获取目标和
nums = list(map(int, sequence.split(','))) # 将输入的序列转化为整数列表
# 输出结果
result = longest_subsequence_with_sum(nums, target_sum)
print(result)
C++
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
int longestSubsequenceWithSum(const vector<int>& nums, int targetSum) {
int n = nums.size();
int left = 0, currentSum = 0, maxLength = -1;
for (int right = 0; right < n; right++) {
currentSum += nums[right];
// 当当前窗口的和大于目标值时,缩小窗口
while (currentSum > targetSum) {
currentSum -= nums[left];
left++;
}
// 如果当前窗口的和等于目标值,更新最大长度
if (currentSum == targetSum) {
maxLength = max(maxLength, right - left + 1);
}
}
return maxLength;
}
int main() {
string input;
getline(cin, input);
// 输入处理
stringstream ss(input);
string num;
vector<int> nums;
while (getline(ss, num, ',')) {
nums.push_back(stoi(num));
}
int targetSum;
cin >> targetSum;
// 输出结果
int result = longestSubsequenceWithSum(nums, targetSum);
cout << result << endl;
return 0;
}
🙏整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏