数列分段

线性扫描数列,每次相邻数字变化时计入一个新的连续段。

OJ: shumeng

题目 ID: CSP201509A

难度:入门

标签:模拟数组

日期: 2026-07-31 16:21

形式化题目

给定 nn 个整数组成的数列,把数列划分为若干段,使得每段内的数全部相同,且段与段之间不能再合并,求最少的段数。

思路

数列被划分成极长连续相同段:同一段内相邻数字都相等,段与段交界处相邻数字不同。因此只需线性扫描:

  1. 第一个数字一定单独开始一段,答案初始为 11
  2. 之后每读入一个数字,只要它和前一个数字不同,就说明新的一段从这里开始,答案加一;
  3. 全程只保留前一个数字,无需存储整个数列。

代码

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-31 16:21
 * update_at: 2026-08-17 22:54
 */
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    // 第一个数字一定形成第一段。
    int previous;
    cin >> previous;
    int answer = 1;
    // 相邻数字不同就说明新的一段从这里开始。
    for (int i = 2; i <= n; i++) {
        int current;
        cin >> current;
        if (current != previous) answer++;
        previous = current;
    }
    cout << answer << '\n';
    return 0;
}

复杂度

  • 时间:每个数字只比较一次,O(n)O(n)
  • 空间:只保存前一个数字,O(1)O(1)

总结

连续段的边界恰好是“相邻数字不相同”的位置。保留前一个数字即可在线统计,这是入门级“扫描计数”题的标准写法。