关键观察:
只要s 中有某个字母出现至少 2 次,就能取这两个位置各自形成长度为 1 的子串(例如两个 a),这两个子串显然字符构成相同,答案为 Yes。
反之,若 s 中每个字母都只出现 1 次,则:
因此问题 等价 于判断 s 是否存在重复字符。 实现上用大小为 26 的布尔数组线性扫描即可,时间复杂度 O(n),额外空间 O(1)。
#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    long long n;
    string s;
    if (!(cin >> n)) return 0;
    cin >> s;
    // 只需判断是否有重复字符(小写字母)
    bool seen[26] = {false};
    for (char c : s) {
        int x = c - 'a';
        if (seen[x]) {
            cout << "Yes\n"; // 出现过 -> 存在两个长度为1的相同子串
            return 0;
        }
        seen[x] = true;
    }
    cout << "No\n"; // 无重复字符 -> 不存在两个构成相同的不同子串
    return 0;
}
import sys
data = sys.stdin.read().strip().split()
if not data:
    sys.exit(0)
# 输入格式:n, s
n = int(data[0])
s = data[1]
# 用布尔数组判断是否有重复字符
seen = [False] * 26
for ch in s:
    idx = ord(ch) - 97  # 'a' -> 0
    if seen[idx]:
        print("Yes")  # 有重复字符 -> 两个长度为1的相同子串
        break
    seen[idx] = True
else:
    print("No")  # 全部不同 -> 不存在两个构成相同的不同子串
import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line1 = br.readLine();
        if (line1 == null) return;
        String line2 = br.readLine();
        long n = Long.parseLong(line1.trim());
        String s = line2.trim();
        // 判断是否存在重复字符(小写字母)
        boolean[] seen = new boolean[26];
        for (int i = 0; i < s.length(); i++) {
            int idx = s.charAt(i) - 'a';
            if (seen[idx]) {
                System.out.println("Yes"); // 有重复 -> 存在两个长度为1的相同子串
                return;
            }
            seen[idx] = true;
        }
        System.out.println("No"); // 无重复 -> 不存在两个构成相同的不同子串
    }
}
        Zeeman 有一个长度为n 的由小写字母组成的字符串s ,Zeeman想知道,是否存在两个不同的非空子串,它们由完全相同的字符构成(即字符种类和数量完全一致)。
第一行输入一个整数n(1≤n≤106)。
第二行输入一个仅由小写字母组成的字符串 s。
如果存在这样的两个子串,输出 Yes;否则输出 No。
输入
3
abc
输出
No