关键观察:
只要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