什么是哈希表?
哈希表,是根据关键码值而直接进行访问的数据结构。
简单但来说是根据在集合内的所有数据所具有的唯一,确定的属性,以此为查找依据,来查找到,并访问该数据内容。
例如:一个学生在学校中的学号是唯一确定的,我们想要了解到该学生的信息,只需要通过学号的查询,就可访问到该学生在学校中的所有信息。哈希表的使用原理与之相似。
如何简单的使用哈希表
由于笔者也是出于初学阶段,仅仅只能通过在LeetCode上面所见到的经典题型进行分析。
在遇到此问题时我们所能最直观的想到的就是通过双层循环,遍历每一次所出现的字符,在之后是否会出现。这样的思路对于这道题来说,是可以解决的,但是同时时间复杂度也是很高的,达到了o(n^2)。因此我们所需要做的就是想办法如何降低时间复杂度。
对于如何降低时间复杂度,我们通过可以建立一个数组,通过牺牲空间,来换取时间来达到降低时间复杂度的目的,在上面所说过,哈希表中需要一个唯一,确定的属性来标识不同的数据,对于字符来说,他们不同的属性就是其ASCLL码。众所周知,字符一共有256个。因此,我们可以申请一个数组ASCLL[256]。用这个数组来记录每个字符出现的个数,最终通过对于数组内容的查看,就可知道每个字符所出现的次数。
程序实现
int firstUniqChar(char * s){
int arr[256] = {0}; //创建数组
char *p = s; //保存字符串首地址
int r = -1;
while(*p != '\0') //单次循环记录每个字符出现的次数
{
arr[*p]++;
p++;
}
p = s;
while(*p != '\0') //根据字符出现的顺序,遍历出第一个符合要求的字符
{
if(arr[*p]==1)
{
r = p-s; //得到改字符的下标
break;
}
p++;
}
return r;
}
通过创建数组的使用我们可以发现,我们将循环的嵌套转变为了,多次(2次)循环。时间复杂度也从o(n^2)减少成为了o(n)。
这道题与第一道题类似,只是将字符串换成了数组。对于这样道题,最直接的办法就是将数组排序,一次从0开始遍历,找到缺失的那个数字。同样时间复杂的也是o(n^2)。
这道题同样我们也可以根据数组的建立,来找到这个缺失的数字,但是问题在于创建数组,我们需创建多大的,数字不同于字符,字符的个数是一定的,但数字是无限的,但是通过题目我们可以得到,数字所出现的范围是n以内,那好我们只需要一个n大的数组就完全可以满足题目要求。
程序实现
int missingNumber(int* nums, int numsSize){
int *arr = (int *)malloc(sizeof(int)*(numsSize+1)); //因为数组在创建是需要给定确定的大小,
//所有我们只能通过动态开辟空间来实现
memset(arr,-1,sizeof(int)*(numsSize+1)); //对于新开辟空间的初始化很重要,若未初始化,则可能会对最终结果产生影响
int i = 0;
for(i = 0; i < numsSize; i++) //依次遍历,记录下每个数字
{
arr[nums[i]] = nums[i];
}
for(i = 0; i <= numsSize; i++)
{
if(arr[i] != i) //因为数字从0开始,与只对应的下标相同,所有只要判断下标和其中保存的内容是否相同,
//由于有0,所以在初始化是,将里面的所有内容都置为-1
break;
}
free(arr); //记得释放空间
return i;
}
这道题与第二道题做法类似,但却略有却别,我们对于数组的访问只是从0号下标到numsSize-1,但这道题中,所给的数组大小,与其中所给的数字并不都满足这个范围,因此我们需要格外注意,但辛好题目只要求给出没有出现最小的正整数,因此在n大的数组中,没有出现最小的正整数最大就是n+1。因此我们可以根据这个突破口来找到这个数字。
程序实现
int firstMissingPositive(int* nums, int numsSize){
int *arr = (int *)malloc(sizeof(int)*(numsSize+1)); //开辟空间,因为最大时n+1所以多开辟一个空间
int i = 0;
memset(arr,0,sizeof(int)*(numsSize+1)); //初始化内存
for(i = 0; i < numsSize;i++) //记录每个在合法下标内出现的数字
{
if(nums[i]<=numsSize&&nums[i]>0)
arr[nums[i]] = 1;
}
for(i = 1; i <= numsSize; i++) //遍历所创建的数组,因为是最小正整数,所以我们从1开始遍历
{
if(arr[i]==0)
break;
}
free(arr); //释放空间
return i;
}
由于笔者仅仅是初学,所以对于哈希表的使用有限,仅仅只能通过开辟数组来达到使用效果。还请各路大佬多多指点。