小红的顺子
[题目链接](https://www.nowcoder.com/practice/76d6ca3612bd42a2900e540b511d2292)
思路
给定一个长度为 的数组(是
到
的排列去掉一个数),要求找出最长的"顺子"——即一段连续子数组,满足相邻元素之差恰好为
(即
)。
一次遍历
这是一道经典的线性扫描题。用一个变量 记录以当前元素结尾的顺子长度:
- 如果
,说明当前元素可以接在前一个顺子后面,
加
;
- 否则,当前元素无法延续之前的顺子,
重置为
。
遍历过程中维护 的最大值即为答案。
样例演示
,数组为
:
| 是否接续 | ||||
|---|---|---|---|---|
| 0 | 1 | — | 1 | 1 |
| 1 | 2 | 2 | 2 | |
| 2 | 4 | 1 | 2 | |
| 3 | 5 | 2 | 2 |
两段顺子 和
,最大长度为
。
复杂度
- 时间复杂度:
,一次遍历。
- 空间复杂度:
,存储数组(若边读边处理可做到
)。
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d",&n);
vector<int> a(n-1);
for(int i=0;i<n-1;i++) scanf("%d",&a[i]);
int ans=1, cur=1;
for(int i=1;i<n-1;i++){
if(a[i]==a[i-1]+1) cur++;
else cur=1;
ans=max(ans,cur);
}
printf("%d\n",ans);
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n - 1];
for (int i = 0; i < n - 1; i++) a[i] = sc.nextInt();
int ans = 1, cur = 1;
for (int i = 1; i < n - 1; i++) {
if (a[i] == a[i - 1] + 1) cur++;
else cur = 1;
ans = Math.max(ans, cur);
}
System.out.println(ans);
}
}
import sys
input = sys.stdin.readline
n = int(input())
a = list(map(int, input().split()))
m = len(a)
ans = 1
cur = 1
for i in range(1, m):
if a[i] == a[i-1] + 1:
cur += 1
else:
cur = 1
ans = max(ans, cur)
print(ans)
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => lines.push(line.trim()));
rl.on('close', () => {
const n = parseInt(lines[0]);
const a = lines[1].split(' ').map(Number);
let ans = 1, cur = 1;
for (let i = 1; i < a.length; i++) {
if (a[i] === a[i - 1] + 1) cur++;
else cur = 1;
ans = Math.max(ans, cur);
}
console.log(ans);
});

京公网安备 11010502036488号