算法习题17:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b

这是一道2006年Google的笔试题,目标是在字符串中找到第一个只出现一次的字符。解决方案包括排序后检查、使用频率数组或位操作。位操作方法通过使用7个字节的计数器记录字符出现次数,达到O(N)的时间复杂度和较低的空间复杂度。

题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff则输出b。   

分析:这道题2006年google的一道笔试题。

---------------------------------

这里大家要看清两个条件:第一次 && 只出现一次!

我暂时先简化题目:只出现一次,其实这个方法有很多:

(1)先排序,然后判断前后是否相同,如果不同,那么就是那个只出现一次的字母了!(这部分我在排序总结里有提到:)

(2)上面的时间复杂度O(NlogN),似乎还是不满意,有没有O(N),那就是遍历一次就能得到结果,当然需要空间上的牺牲,这里我们建立一个频率数组,记录每个字母出现次数,我权且叫它hashTable,那遍历一次后就可以知道所有出现次数情况,题目也就迎刃而解

再加上那个第一次条件,那么我们发现(1)这个方法似乎打乱了顺序,找第一次似乎有点困难了

(2)却可以,仍然顺序遍历,找出频率为1的即可!

这个问题大家再细想,是否可以把空间复杂度降低呢?(见下面)

//============================================================================
// Name        : SearchFirst.cpp
// Author      : YLF
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

#define MAX 50

void SearchFirstCharacter(char* arr, int num);
void QuickSort(char* &arr, int l, int h);

int main() {

	char c = 1;
	char arr[MAX];
	int num = -1;

	while(true){
		num++;
		cin>>c;
		if(c != '0')
			arr[num] = c;
		else
			break;
	}

	SearchFirstCharacter(arr, num);
	return 0;
}

void SearchFirstCharacter(char* arr, int num){
	int hashTable[26];
	memset(hashTable,0,sizeof(hashTable));
	int i = 0;
	for(;i<num;i++){
		hashTable[arr[i] - 97]++;
	}

	for(i=0;i<num;i++){
		if(hashTable[arr[i] - 97] == 1){
			cout<<arr[i];
			break;
		}
	}
}


这里由于只考虑26个字母,所以我们建立一个int[26]的频率辅助数组 这里需要26*4 = 104字节

我们知道这里只是需要考虑添加一个计数器罢了,而且只要三个状态 0,1,大于1 ,那就是两位00,01,10(可记录三态)所以这里最多就用52位即可,就是7个字节了(如果觉得位操作很复杂,那就用char[26],也只要26个字节,这里是很值得优化的部分,尤其对于内存少,数据量大的情况)

原谅我,位操作太累了。。。就不写了。。。。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值