题目描述
有N个正整数组成的一个序列。给定整数sum,求长度最长的连续子序列,使他们的和等于sum,返回此子序列的长度,
如果没有满足要求的序列,返回-1。
输入描述
第一行输入是:N个正整数组成的一个序列
第二行输入是:给定整数sum
输出描述
最长的连续子序列的长度
备注
- 输入序列仅由数字和英文逗号构成,数字之间采用英文逗号分隔
- 序列长度:1 <= N <= 200
- 输入序列不考虑异常情况
用例
输入 |
1,2,3,4,2 |
输出 | 3 |
说明 | 1,2,3和4,2两个序列均能满足要求,所以最长的连续序列为1,2,3,因此结果为3。 |
输入 | 1,2,3,4,2 20 |
输出 | -1 |
说明 | 没有满足要求的子序列,返回-1 |
前缀和解法
本题数量级不大,可以考虑求解输入序列的前缀和数组,实现O(1)时间复杂度计算任意区间和,关于前缀和可以看:
JS算法源码
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
const nums = (await readline()).split(",").map(Number);
const target = parseInt(await readline());
console.log(getResult(nums, target));
})();
function getResult(nums, target) {
const n = nums.length;
const preSum = new Array(n + 1).fill(0);
for (let i = 1; i <= n; i++) {
preSum[i] = preSum[i - 1] + nums[i - 1];
}
let maxLen = -1;
for (let l = 0; l <= n - 1; l++) {
for (let r = l + 1; r <= n; r++) {
if (preSum[r] - preSum[l] == target) {
maxLen = Math.max(maxLen, r - l);
}
}
}
return maxLen;
}
Java算法源码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] nums = Arrays.stream(sc.nextLine().split(",")).mapToInt(Integer::parseInt).toArray();
int target = Integer.parseInt(sc.nextLine());
System.out.println(getResult(nums, target));
}
public static int getResult(int[] nums, int target) {
int n = nums.length;
// 前缀和数组
int[] preSum = new int[n + 1];
for (int i = 1; i <= n; i++) {
preSum[i] = preSum[i - 1] + nums[i - 1];
}
// 记录最长连续子序列的长度
int maxLen = -1;
// 求解所有连续子序列的区间和
for (int l = 0; l <= n - 1; l++) {
for (int r = l + 1; r <= n; r++) {
if (preSum[r] - preSum[l] == target) {
maxLen = Math.max(maxLen, r - l);
}
}
}
return maxLen;
}
}
Python算法源码
# 输入获取
nums = list(map(int, input().split(",")))
target = int(input())
# 算法入口
def getResult():
n = len(nums)
preSum = [0] * (n + 1)
for i in range(1, n + 1):
preSum[i] = preSum[i - 1] + nums[i - 1]
maxLen = -1
for l in range(0, n):
for r in range(l + 1, n+1):
if preSum[r] - preSum[l] == target:
maxLen = max(maxLen, r - l)
return maxLen
# 算法调用
print(getResult())
C算法源码
#include <stdio.h>
#define MAX(a,b) (a) > (b) ? (a) : (b)
#define MAX_SIZE 200
int getResult(int nums[], int nums_size, int target);
int main() {
int nums[MAX_SIZE];
int nums_size = 0;
while(scanf("%d", &nums[nums_size++])) {
if(getchar() != ',') break;
}
int target;
scanf("%d", &target);
printf("%dn", getResult(nums, nums_size, target));
return 0;
}
int getResult(int nums[], int nums_size, int target) {
int preSum[nums_size+1];
preSum[0] = 0;
for(int i=1; i<=nums_size; i++) {
preSum[i] = preSum[i-1] + nums[i-1];
}
int maxLen = -1;
for(int l=0; l<= nums_size-1; l++) {
for(int r=l+1; r <= nums_size; r++) {
if(preSum[r] - preSum[l] == target) {
maxLen = MAX(maxLen, r - l);
}
}
}
return maxLen;
}
双指针解法
本题可以利用双指针解决。
同时,有一种特殊情况
2023.06.12
本题的第二行输入是:给定整数sum
因此sum可能取负数,0,正数,对于sum为负数,0的情况,可以直接返回-1,因为第一行输入是:N个正整数组成的一个序列
JavaScript算法源码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const lines = [];
rl.on("line", (line) => {
lines.push(line);
if (lines.length === 2) {
const arr = lines[0].split(",").map(Number);
const sum = parseInt(lines[1]);
console.log(getMaxLen(arr, sum));
lines.length = 0;
}
});
function getMaxLen(arr, sum) {
let ans = -1;
if (sum <= 0) return ans;
let l = 0;
let r = 0;
let n = arr.length;
let total = arr[l];
while (true) {
if (total > sum) {
l++;
total -= arr[l - 1];
if (l < n && r < l) {
r = l;
total += arr[r];
}
} else if (total < sum) {
r++;
if (r < n) total += arr[r];
else break;
} else {
ans = Math.max(ans, r - l + 1);
l++;
r++;
if (r < n) total += arr[r] - arr[l - 1];
else break;
}
}
return ans;
}
Java算法源码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Integer[] arr =
Arrays.stream(sc.nextLine().split(",")).map(Integer::parseInt).toArray(Integer[]::new);
int sum = Integer.parseInt(sc.nextLine());
System.out.println(getResult(arr, sum));
}
public static int getResult(Integer[] arr, int sum) {
int ans = -1;
if (sum <= 0) return ans;
int l = 0;
int r = 0;
int n = arr.length;
int total = arr[l];
while (true) {
if (total > sum) {
l++;
total -= arr[l - 1];
if (l < n && r < l) {
r = l;
total += arr[r];
}
} else if (total < sum) {
r++;
if (r < n) total += arr[r];
else break;
} else {
ans = Math.max(ans, r - l + 1);
l++;
r++;
if (r < n) total += arr[r] - arr[l - 1];
else break;
}
}
return ans;
}
}
Python算法源码
# 输入获取
arr = list(map(int, input().split(",")))
sumV = int(input())
# 算法入口
def getResult():
ans = -1
if sumV <= 0:
return ans
l = 0
r = 0
n = len(arr)
total = arr[l]
while True:
if total > sumV:
l += 1
total -= arr[l - 1]
if r < l < n:
r = l
total += arr[r]
elif total < sumV:
r += 1
if r < n:
total += arr[r]
else:
break
else:
ans = max(ans, r - l + 1)
l += 1
r += 1
if r < n:
total += arr[r] - arr[l - 1]
else:
break
return ans
# 算法调用
print(getResult())
C算法源码
#include <stdio.h>
#define MAX(a, b) (a) > (b) ? (a) : (b)
#define MAX_SIZE 200
int getResult(int nums[], int nums_size, int target);
int main() {
int nums[MAX_SIZE];
int nums_size = 0;
while (scanf("%d", &nums[nums_size++])) {
if (getchar() != ',') break;
}
int target;
scanf("%d", &target);
printf("%dn", getResult(nums, nums_size, target));
return 0;
}
int getResult(int nums[], int nums_size, int target) {
int maxLen = -1;
if (target <= 0) return maxLen;
int l = 0;
int r = 0;
int sum = nums[l];
while (1) {
if (sum > target) {
l++;
sum -= nums[l - 1];
if (l < nums_size && r < l) {
r = l;
sum += nums[r];
}
} else if (sum < target) {
r++;
if (r < nums_size) sum += nums[r];
else break;
} else {
maxLen = MAX(maxLen, r - l + 1);
l++;
r++;
if (r < nums_size) sum += nums[r] - nums[l - 1];
else break;
}
}
return maxLen;
}
免责声明:
1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文
评论0