给定一个只包含小写字母的字符串,请你找到最后一个仅出现一次的字符。C++,无需中文输出提示
时间: 2025-07-14 18:01:36 浏览: 1
<think>好的,用户想要在C++中实现一个函数,找到字符串中最后一个仅出现一次的字符。我需要仔细思考如何解决这个问题,并确保代码高效正确。首先,我得明确需求:最后一个只出现一次的字符,也就是所有唯一字符中最后出现的那个。例如,字符串“abba”中,最后一个唯一字符不存在,而“abcab”中的最后一个唯一字符是'c'。
首先,我需要考虑如何统计每个字符的出现次数。通常的做法是使用哈希表或者数组来记录频率。对于ASCII字符,可以使用一个大小为256的数组来统计,这样效率更高。遍历字符串,统计每个字符出现的次数,这一步的时间复杂度是O(n),其中n是字符串长度。
接下来,需要再次遍历字符串,找到最后一个出现次数为1的字符。这里需要注意的是,要从字符串的末尾开始向前遍历,一旦遇到第一个出现次数为1的字符,就立即返回它,这样就能保证找到的是最后一个符合条件的字符。这样第二次遍历的时间复杂度也是O(n),总的时间复杂度为O(n),空间复杂度是O(1)(因为数组大小固定为256)。
不过,我需要确认是否所有可能的字符都被考虑到,包括大小写字母、数字、特殊字符等。假设题目中的字符是扩展的ASCII字符,所以数组大小设为256是正确的。此外,要注意字符串为空的情况,这时候应该返回空字符或者某种标识。
现在考虑边界情况。例如,字符串全为重复字符,这时候应该返回空或者null。或者字符串只有一个字符,直接返回该字符。还有像所有字符都唯一的情况,返回最后一个字符。
然后,编写代码的大致步骤:
1. 初始化一个大小为256的数组,初始值为0。
2. 第一次遍历字符串,统计每个字符的出现次数。
3. 第二次从后往前遍历字符串,检查每个字符的计数是否为1,第一个符合条件的字符即为答案。
测试几个例子:
比如输入“leetcode”,字符出现次数为l:1, e:3, t:1, c:1, o:1, d:1。从后往前找,最后一个出现次数1的是'd'?不,原字符串是'l','e','e','t','c','o','d','e'。最后的字符是'e',但'e'出现三次,所以应检查前面的字符。最后一个出现次数1的应该是'c'?或者可能我记错了例子。比如另一个例子“aabbcdd”,最后一个唯一字符是'c',对吗?
代码实现部分,需要注意字符串的遍历顺序。例如,在第二次遍历时,从str.size()-1开始,递减到0,检查每个字符对应的count是否为1。一旦找到,立即返回该字符。
可能的优化:可以将两次遍历合并为一次,但这样可能需要存储每个字符最后一次出现的位置,然后找出其中出现次数为1且位置最大的那个。但这样空间复杂度可能更高,因为需要保存两个数组:频率和最后出现的位置。不过,对于这个问题,两次分开遍历可能更简单且效率相当。
现在编写代码的结构:
函数参数是const string&,返回char。如果没找到,可以返回'\0'或者抛出异常,但根据题目要求,可能需要返回空字符。
代码示例:
char findLastUniqueChar(const string &s) {
vector<int> count(256, 0);
for (char c : s) {
count[static_cast<unsigned char>(c)]++;
}
for (int i = s.size() - 1; i >= 0; --i) {
if (count[static_cast<unsigned char>(s[i])] == 1) {
return s[i];
}
}
return '\0';
}
这里要注意的是,字符可能是有符号的,所以转换为unsigned char来避免负的索引。例如,如果字符是0xFF,在signed char中会被视为-1,导致数组越界。所以必须用static_cast<unsigned char>来转换,确保索引在0-255之间。
测试用例:
测试1:字符串“aabccdeff”,每个字符出现次数为a:2, b:1, c:2, d:1, e:1, f:2。从后往前遍历,最后一个出现次数1的是'e'?或者检查每个字符的顺序。字符串的顺序是a,a,b,c,c,d,e,f,f。从后往前是f,f,e,d,c,c,b,a,a。第一个count为1的是e,对吗?是的,所以返回'e'。
测试2:字符串“abcabc”,所有字符出现两次,返回空。
测试3:字符串“z”,返回'z'。
这样看来,代码是正确的。
另外,需要考虑输入为空的情况,此时返回'\0'。用户可能希望返回一个特定的值,比如空字符,或者使用std::optional,但根据问题描述,可能直接返回空字符即可。
总结下来,这样的实现应该是正确且高效的。时间复杂度O(n),空间O(1)。符合要求。</think>### 查找字符串中最后一个仅出现一次的字符(C++实现)
要实现查找字符串中最后一个仅出现一次的字符,可以分两步完成:统计字符频率,然后逆序遍历寻找目标字符。
**步骤说明**
1. **统计字符出现次数**
使用长度为256的数组(覆盖扩展ASCII字符)记录每个字符的出现次数。
```cpp
vector<int> count(256, 0);
for (char c : s) {
count[static_cast<unsigned char>(c)]++;
}
```
2. **逆序查找首个唯一字符**
从字符串末尾向前遍历,找到第一个计数为1的字符:
```cpp
for (int i = s.size() - 1; i >= 0; --i) {
if (count[static_cast<unsigned char>(s[i])] == 1) {
return s[i];
}
}
return '\0'; // 未找到时返回空字符
```
**完整代码**
```cpp
#include <vector>
#include <string>
using namespace std;
char findLastUniqueChar(const string &s) {
vector<int> count(256, 0);
for (char c : s) {
count[static_cast<unsigned char>(c)]++;
}
for (int i = s.size() - 1; i >= 0; --i) {
if (count[static_cast<unsigned char>(s[i])] == 1) {
return s[i];
}
}
return '\0'; // 无唯一字符时返回空字符
}
```
**复杂度分析**
- **时间复杂度**:$O(n)$,两次线性遍历字符串。
- **空间复杂度**:$O(1)$,固定大小的计数数组。
---
阅读全文
相关推荐


















