面试题 找到字符串中第一个只出现一次的字符


简单面试题

http://blog.csdn.net/geniusluzh/article/details/8248988

       这道题的确切描述是:一个字符串的长度小于10^4,只由大写字母组成,让你找到第一个只出现一次的字符的下标。比如ABACC,那么结果就是1。如果我们需要在O(N)的时间复杂度和O(1)的空间复杂度内解决该题,有什么好的办法呢?

       之前看到别人描述这道题的时候,题意描述的有点不确切,所以没有什么好的思路。但是现在一看到这个描述,思路就很明确了。只有大写字母,那么我们使用一个整型进行位压缩来记录一个每个字符是否出现。我们只需要用两个整型数便能够压缩整个字符串的状态,一个数用来表示对应位的字母是否出现,另外一个表示对应位的字母是否重复出现,扫两边字符串就能够得到结果了!那么显然达到了时间复杂度为O(N),空间复杂度为O(1)的要求。

       具体实现的细节可以看代码!

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX = 10010;
 
int in, re;
char s[MAX];
 
void inline set_k(int &n, int k)
{
    n |= (1<<k);
}
 
bool inline test_k(int n, int k)
{
    if((n&(1<<k)) == 0) return false;
    else    return true;
}
 
 
int main()
{
    while(scanf("%s", s) != EOF)
    {
        re = in = 0;
        int len = strlen(s);
        for(int i=0; i<len; i++)
        {
            int k = s[i] - 'A';
            if(test_k(in, k))
            {
                set_k(re, k);
            }
            else
            {
                set_k(in, k);
            }
        }
        int ans = -1;
 
        for(int i=0; i<len; i++)
        {
            int k = s[i] - 'A';
            if(!test_k(re, k))
            {
                ans = i;
                break;
            }
        }
 
        printf("%d\n", ans);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值