leetcode练习——哈希表

目录

3. 无重复字符的最长子串

题目描述

解题思路

代码实现

349. 两个数组的交集

题目描述

解题思路

代码实现

​​​​454. 四数相加 II

题目描述

解题思路

代码实现

242. 有效的字母异位词

题目描述

解题思路

代码实现

438. 找到字符串中所有字母异位词

题目描述

解题思路

代码实现

202. 快乐数

题目描述

解题思路

代码实现

383. 赎金信

题目描述

解题思路

代码实现

387. 字符串中的第一个唯一字符

题目描述

解题思路

代码实现

3. 无重复字符的最长子串

题目描述


给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:

0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成


解题思路

使用滑动窗口的算法,并结合哈希表来快速判断某个字符是否已被访问过。

1.初始化:

获取字符串s的长度len。如果字符串为空(len == 0),则最长无重复字符子串的长度显然为0,直接返回0。

定义左指针left和右指针right,都初始化为0。这两个指针用于定义当前考虑的子串范围。定义maxLen用于记录当前找到的最长无重复字符子串的长度,初始化为0。

定义哈希表hash,大小为256,并全部初始化为0。哈希表的索引对应字符的ASCII值,值对应字符的访问状态(0表示未访问,1表示已访问)。

2.遍历字符串

使用while循环遍历字符串,直到右指针right达到字符串的末尾。

3.检查字符状态

在每次循环中,检查当前右指针right指向的字符s[right]的访问状态:

如果hash[s[right]]为0,表示该字符在当前考虑的子串中还未出现过:将hash[s[right]]设置为1,标记该字符为已访问。更新maxLen为当前子串长度(right - left + 1)和maxLen中的较大值。右指针right右移一位,继续考虑下一个字符。

如果hash[s[right]]为1,表示该字符在当前考虑的子串中已经出现过:为了找到最长无重复字符子串,需要移动左指针left,并重置左指针及其左侧所有字符的访问状态(在hash中对应位置设置为0)。左指针left右移一位。

4.返回结果

当遍历完整个字符串后,maxLen中保存的就是最长无重复字符子串的长度,将其作为结果返回。

代码实现

int lengthOfLongestSubstring(char* s) {
    int len = strlen(s);
    if (len == 0)
        return 0;
    int left = 0, right = 0;
    int maxLen = 0;
    int hash[256] = {0};
    while (right < len) {
        // 如果当前字符没有被访问过
        if (hash[s[right]] == 0) {
            hash[s[right]] = 1; // 标记当前字符为已访问
            maxLen = (right - left + 1) > maxLen ? (right - left + 1): maxLen; // 更新最大长度
            right++;                                       // 右指针右移
        } else {
            // 如果当前字符已经被访问过,则移动左指针,并重置左指针及其左侧所有字符的访问状态
            hash[s[left]] = 0;
            left++;
        }
    }
    return maxLen;
}

349. 两个数组的交集

题目描述


给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

提示:

1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000


解题思路


1.初始化哈希表和结果数组:

创建一个大小为1005的哈希表 hash,用于记录数组 nums1 中元素的出现次数。分配一个足够大的数组 result 来存储交集结果。这个数组的大小根据两个数组中较小的一个来确定,因为交集的大小不会超过较小的数组的大小。

2.记录 nums1 中元素的出现次数:

遍历数组 nums1,将每个元素作为索引,在哈希表 hash 中对应的位置增加计数。这样,哈希表就记录了 nums1 中每个元素的出现次数。

3.查找交集并填充结果数组:

遍历数组 nums2,对于每个元素,检查它在哈希表 hash 中对应的计数是否大于0。如果大于0,说明这个元素也出现在 nums1 中,因此它是交集的一部分。将这个交集元素添加到结果数组 result 中,并更新结果数组的索引 resultIndex。将哈希表中该元素对应的计数置为0,以避免重复添加同一个元素到结果数组中。

4.返回结果:

通过指针参数 returnSize 返回结果数组 result 的大小,并返回指向结果数组 result 的指针。

代码实现

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size,int* returnSize) {
    // 创建一个大小为 1005 的哈希表,初始值全部为 0
    int hash[1005] = {0};
    // lessSize
    // 存储两个数组中较小的那个数组的大小,这样可以确保结果数组的大小足够存放交集
    int lessSize = nums1Size < nums2Size ? nums1Size : nums2Size;
    // 分配足够空间来存储可能的交集结果,并用 calloc 初始化为 0
    int* result = (int*)calloc(lessSize, sizeof(int));
    // resultIndex 用于记录结果数组中当前的位置
    int resultIndex = 0;
    // 遍历第一个数组,将每个元素出现的次数记录在哈希表中
    for (int i = 0; i < nums1Size; i++) {
        hash[nums1[i]]++;
    }
    // 遍历第二个数组,查找与第一个数组有交集的元素
    for (int i = 0; i < nums2Size; i++) {
        // 如果哈希表中对应位置的值大于 0,说明该元素在第一个数组中出现过
        if (hash[nums2[i]] > 0) {
            // 将交集元素添加到结果数组中
            result[resultIndex] = nums2[i];
            // 更新结果数组中的位置索引
            resultIndex++;
            // 将哈希表中对应位置的值置为 0,表示该元素已被找到过一次
            hash[nums2[i]] = 0;
        }
    }
    // 通过指针参数返回交集数组的大小
    *returnSize = resultIndex;
    // 返回指向交集数组的指针
    return result;
}

​​​​454. 四数相加 II

题目描述

给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
示例 1:

输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0
示例 2:

输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]
输出:1
  提示:

n == nums1.length
n == nums2.length
n == nums3.length
n == nums4.length
1 <= n <= 200
-228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228


解题思路

观察发现,如果可以找到两个数对(来自不同数组),它们的和互为相反数,那么它们就可以组成一个满足条件的四元组。因此,问题可以转化为:对于每一对来自nums1和nums2的数,找到多少对来自nums3和nums4的数,它们的和与这对数的和互为相反数。

1.使用哈希表

哈希表是一种以平均常数时间复杂度进行插入、删除和查找的数据结构。在这个问题中,可以使用哈希表来存储nums1和nums2中所有两数之和及其出现的次数。

2.遍历并构建哈希表:

遍历nums1和nums2的所有组合,计算每对数的和(ikey)。

检查哈希表中是否已经存在这个键(两数之和)。

如果不存在,则创建一个新的哈希表项,键为两数之和,值为1(表示这个和第一次出现)。

如果已经存在,则增加该键对应的值(表示这个和又出现了一次)。

3.利用哈希表查找:

遍历nums3和nums4的所有组合,计算每对数的和的相反数(-ikey)。

在哈希表中查找这个相反数。

如果找到了,则将哈希表中该键对应的值累加到结果变量中,因为这个值表示在nums1和nums2中有多少对数的和与当前nums3和nums4中的数对的和互为相反数。

4.返回结果:

遍历完成后,结果变量中存储的就是所有满足条件的四元组的个数,返回这个结果。

代码实现

	struct hashTable {  
    int key;            // 哈希表项的键,用于存储nums1[i] + nums2[j]的和  
    int val;            // 哈希表项的值,用于存储键出现的次数  
    UT_hash_handle hh;  // uthash库提供的数据结构,用于处理哈希表的相关操作  
};  
  
// 计算四数之和为零的元组个数  
int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size,  
                 int* nums3, int nums3Size, int* nums4, int nums4Size) {  
    struct hashTable* hashtable = NULL; // 初始化哈希表为空  
  
    // 遍历nums1和nums2的所有组合,计算两数之和,并更新哈希表  
    for (int i = 0; i < nums1Size; i++) {  
        for (int j = 0; j < nums2Size; j++) {  
            int ikey = nums1[i] + nums2[j]; // 计算两数之和  
            struct hashTable* tmp;  
            HASH_FIND_INT(hashtable, &ikey, tmp); // 在哈希表中查找键ikey  
  
            if (tmp == NULL) {  
                // 如果没找到,则新建一个哈希表项  
                struct hashTable* tmp = malloc(sizeof(struct hashTable));  
                tmp->key = ikey;  
                tmp->val = 1; // 初始值为1,表示找到了一对数的和为ikey  
                HASH_ADD_INT(hashtable, key, tmp); // 将新项添加到哈希表中  
            } else {  
                // 如果找到了,则增加该键对应的值,表示又找到了一对数的和为ikey  
                tmp->val++;  
            }  
        }  
    }  
  
    int ans = 0; // 初始化结果变量为0  
  
    // 遍历nums3和nums4的所有组合,计算两数之和的相反数,并在哈希表中查找该相反数  
    for (int i = 0; i < nums3Size; i++) {  
        for (int j = 0; j < nums4Size; j++) {  
            int ikey = -nums3[i] - nums4[j]; // 计算两数之和的相反数  
            struct hashTable* tmp;  
            HASH_FIND_INT(hashtable, &ikey, tmp); // 在哈希表中查找该相反数  
  
            if (tmp != NULL) {  
                // 如果找到了,则将该键对应的值累加到结果变量中  
                // 因为对于nums3和nums4中的每一对数的和,如果哈希表中存在相反数,  
                // 则说明在nums1和nums2中存在另一对数的和与该相反数相等,从而四数之和为零  
                ans += tmp->val;  
            }  
        }  
    }  
return ans;//返回结果
}

242. 有效的字母异位词

题目描述

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"
输出: true

示例 2:

输入: s = "rat", t = "car"
输出: false

提示:

  • 1 <= s.length, t.length <= 5 * 104
  • s 和 t 仅包含小写字母

解题思路

  1. 初始化
    • 创建一个大小为26的整数数组 record,并初始化所有元素为0。数组的每个索引对应一个小写字母(例如,record[0] 对应字母 'a')。
    • 获取字符串 s 和 t 的长度,分别存储在 slength 和 tlength 中。
  2. 长度检查
    • 如果两个字符串的长度不同,它们显然不可能是异位词,因为异位词要求字符完全相同,只是顺序不同。因此,直接返回 false(0)。
  3. 计算字符频率
    • 遍历字符串 s 中的每个字符,将对应字母在 record 数组中的计数加1。这是通过计算字符与 'a' 的ASCII码差值,并用该差值作为数组索引来实现的。
    • 同时,遍历字符串 t 中的每个字符,将对应字母在 record 数组中的计数减1。
    • 如果 s 和 t 是异位词,那么 record 数组中的每个索引都应该最终为0,因为每个字符在 s 中出现的次数与在 t 中出现的次数应该相同。
  4. 检查记录数组
    • 遍历 record 数组,检查是否有任何非零值。
    • 如果发现任何非零值,说明 s 和 t 不是变位词,因为这意味着至少有一个字符在两个字符串中的出现次数不同。因此,返回 false(0)。
  5. 返回结果
    • 如果 record 数组中的所有值都是0,说明 s 和 t 是异位词,因为它们的字符组成完全相同,只是顺序不同。因此,返回 true(1)。

代码实现

bool isAnagram(char* s, char* t) {
    int record[26] = {0}, slength = strlen(s), tlength = strlen(t);
    int i;
    if (slength != tlength)
        return 0;
    for (i = 0; i < slength; i++) {
        record[s[i] - 'a'] += 1;
        record[t[i] - 'a'] -= 1;
    }
    for (i = 0; i < 26; i++) {
        if (record[i] != 0) {
            return 0;
        }
    }
    return 1;
}

438. 找到字符串中所有字母异位词

题目描述


给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
 示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

提示:

1 <= s.length, p.length <= 3 * 104
s 和 p 仅包含小写字母

解题思路


利用哈希表来记录字符频率,并使用滑动窗口的方法来遍历字符串s。

1.初始化

首先,获取字符串s和p的长度,并检查p的长度是否大于s的长度。如果大于,那么s中不可能有与p构成异位词的子串,所以直接返回空数组。

初始化两个哈希表shash和phash,用于存储s和p中字符出现的次数。因为题目中说s 和 p 仅包含小写字母,所以哈希表的大小为26。

2.计算p中字符的出现次数

遍历p中的每个字符,并在phash中对应的位置增加计数。

3.初始化结果数组和滑动窗口

分配内存给结果数组ans,大小为slen - plen + 1。这是因为最多可能有slen - plen + 1个与p等长的子串存在于s中。

初始化计数器count为0,用于记录找到的异位词子串的数量。

初始化滑动窗口的左边界left为0。

4.使用滑动窗口遍历s

使用变量right作为滑动窗口的右边界,从0开始遍历s。

在每次迭代中,更新shash中对应s[right]字符的计数。

当滑动窗口的大小达到p的长度时,检查shash和phash是否相等。可以通过memcmp函数实现,它比较两个内存区域的内容。

如果哈希值匹配,说明找到了一个与p构成异位词的子串,将左边界的索引left添加到结果数组ans中,并增加计数器count。

然后,移动滑动窗口的左边界,即将left右移一位,并更新shash中对应s[left]字符的计数。

5.返回结果

设置结果数组的大小为count。

返回结果数组ans。

【补充】C 库<string.h>函数 - memcmp()

作用:把存储区 str1 和存储区 str2 的前 n 个字节进行比较。

函数声明:int memcmp(const void *str1, const void *str2, size_t n)

参数:str1 -- 指向内存块的指针。

str2 -- 指向内存块的指针。

n -- 要被比较的字节数。

返回值:

如果str1 小于 str2,返回值 < 0。

如果str1 大于 str2,返回值 > 0。

如果str1 等于 str2,返回值 = 0。

代码实现

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findAnagrams(char * s, char * p, int* returnSize){
    int slen = strlen(s), plen = strlen(p);  
    // 如果p的长度大于s的长度,直接返回空数组
    if (plen > slen) {  
        *returnSize = 0;  
        return NULL;  
    }  
    // 初始化两个哈希表,用于存储p和s中字符出现的次数
    int shash[26] = {0}, phash[26] = {0};  
    // 计算p中字符出现的次数
    for (int i = 0; i < plen; i++) {  
        phash[p[i] - 'a']++;  
    }  
    // 为结果数组分配内存
    int *ans = (int*)malloc(sizeof(int) * (slen - plen + 1));  
    // 初始化结果数组的计数器和滑动窗口的左边界
    int count = 0, left = 0;  
    // 遍历字符串s
    for (int right = 0; right < slen; right++) {  
        // 维护滑动窗口的哈希值
        shash[s[right] - 'a']++;  
        // 当窗口大小达到p的长度时,开始检查哈希值是否匹配
        if (right - left + 1 == plen) {  
            // 如果哈希值匹配,将左边界的索引添加到结果数组中
            if (memcmp(shash, phash, sizeof(phash)) == 0) {  
                ans[count++] = left;  
            }  
            // 移动窗口左边界,并更新哈希值
            shash[s[left] - 'a']--;  
            left++;  
        }  
    }  
    // 设置结果数组的大小
    *returnSize = count;  
    // 返回结果数组
    return ans;  
}

202. 快乐数

题目描述

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:

输入:n = 2
输出:false

提示:

  • 1 <= n <= 231 - 1

解题思路

  1. 定义一个辅助函数 getSum,这个函数用于计算一个整数的各位数字的平方和。
    • 通过循环,每次取整数 n 的最后一位数字(n % 10),计算其平方,然后累加到 sum 中。
    • 接着将 n 除以 10,去掉已经处理过的最后一位数字。
    • 当 n 为 0 时,循环结束,返回 sum
  2. 定义主函数 isHappy,用于判断一个数是否为快乐数。
    • 首先调用 getSum 函数,计算输入数 n 的各位数字的平方和 sum
    • 定义一个哈希表 hash,用于记录已经出现的 sum 值。初始时,所有元素都设为 0。
    • 进入一个循环,当 sum 不等于 1 时继续循环:
      • 如果 sum 在哈希表中已经出现过(即 hash[sum] == 1),则返回 false,表示 n 不是快乐数。
      • 否则,将 hash[sum] 的值设为 1,表示 sum 已经出现过。
      • 再次调用 getSum 函数,更新 sum 的值为其各位数字的平方和。
    • 如果循环正常结束(即 sum 等于 1),则返回 true,表示 n 是快乐数。

代码实现

int getSum(int n) {
    int sum = 0;
    while (n) {
        sum += (n % 10) * (n % 10);
        n /= 10;
    }
    return sum;
}
bool isHappy(int n) {
    int sum = getSum(n);
    int hash[1005] = {0};
    while (sum != 1) {
        if (hash[sum] == 1) {
            return false;
        } else {
            hash[sum]++;
        }
        sum = getSum(sum);
    }
    return true;
}

383. 赎金信

题目描述

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

示例 1:

输入:ransomNote = "a", magazine = "b"
输出:false

示例 2:

输入:ransomNote = "aa", magazine = "ab"
输出:false

示例 3:

输入:ransomNote = "aa", magazine = "aab"
输出:true

提示:

  • 1 <= ransomNote.length, magazine.length <= 105
  • ransomNote 和 magazine 由小写英文字母组成

解题思路

  1. 初始化哈希表
    • 创建一个大小为26的整数数组hash,用于存储每个小写字母出现的次数。数组的每个索引对应一个小写字母(例如,hash[0]对应字母'a',hash[1]对应字母'b',以此类推)。
    • hash数组的所有元素初始化为0。
  2. 统计magazine中字符的出现次数
    • 遍历magazine字符串中的每个字符。
    • 对于每个字符,将其对应的哈希表索引增加1。这是通过计算字符与'a'的ASCII码差值来实现的(例如,字符'b'会对应索引1,因为'b' - 'a' = 1)。
  3. 减少ransomNote中字符的出现次数
    • 遍历ransomNote字符串中的每个字符。
    • 对于每个字符,将其对应的哈希表索引减少1。
  4. 检查哈希表
    • 遍历整个哈希表。
    • 如果发现任何索引的值小于0,这意味着ransomNote中的某个字符在magazine中的出现次数不足以满足其需求。因此,函数返回0,表示无法用magazine构造ransomNote
  5. 返回结果
    • 如果哈希表中所有索引的值都大于等于0,这意味着magazine中的字符足够用来构造ransomNote。因此,函数返回1。

代码实现

bool canConstruct(char* ransomNote, char* magazine) {
    int hash[26] = {0}, i = 0;
    for (i = 0; magazine[i] != '\0'; i++) {
        hash[magazine[i] - 'a']++;
    }
    for (i = 0; ransomNote[i] != '\0'; i++) {
        hash[ransomNote[i] - 'a']--;
    }
    for (i = 0; i<26; i++) {
        if (hash[i] < 0)
            return 0;
    }
    return 1;
}

387. 字符串中的第一个唯一字符

题目描述

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

示例 1:

输入: s = "leetcode"
输出: 0

示例 2:

输入: s = "loveleetcode"
输出: 2

示例 3:

输入: s = "aabb"
输出: -1

提示:

  • 1 <= s.length <= 105
  • s 只包含小写字母

解题思路

  1. 初始化:
    • 定义一个 hashTable 结构体,它包含两个整型成员:key 和 val,以及一个 UT_hash_handle 类型的成员 hh。这个结构体用于存储字符和其出现的频率。
    • 使用 UT_hash_handle 是因为代码中使用了 uthash 这个库,它是一个用于 C 语言的轻量级哈希表库。
  2. 计算频率:
    • 创建一个空的哈希表 frequency
    • 遍历字符串 s 中的每个字符:
      • 对于每个字符,将其 ASCII 值作为键(ikey)在哈希表中查找。
      • 如果找不到该键(tmp == NULL),则创建一个新的 hashTable 结构体实例,并设置其 key 为当前字符的 ASCII 值,val 为 1,然后将它添加到哈希表中。
      • 如果找到了该键,则将对应结构体的 val 值加 1,表示该字符的出现频率增加。
  3. 查找第一个只出现一次的字符:
    • 再次遍历字符串 s 中的每个字符:
      • 对于每个字符,使用其 ASCII 值在哈希表中查找。
      • 如果找到了该键,并且其对应的 val 值为 1(即该字符只出现了一次),则返回当前字符的索引 i
  4. 返回结果:
    • 如果在字符串 s 中没有找到只出现一次的字符,则返回 -1。

代码实现

struct hashTable {
    int key;
    int val;
    UT_hash_handle hh;
};

int firstUniqChar(char* s) {
    struct hashTable* frequency = NULL;
    int n = strlen(s);
    for (int i = 0; i < n; i++) {
        int ikey = s[i];
        struct hashTable* tmp;
        HASH_FIND_INT(frequency, &ikey, tmp);
        if (tmp == NULL) {
            tmp = malloc(sizeof(struct hashTable));
            tmp->key = ikey;
            tmp->val = 1;
            HASH_ADD_INT(frequency, key, tmp);
        } else {
            tmp->val++;
        }
    }
    for (int i = 0; i < n; i++) {
        int ikey = s[i];
        struct hashTable* tmp;
        HASH_FIND_INT(frequency, &ikey, tmp);
        if (tmp != NULL && tmp->val == 1) {
            return i;
        }
    }
    return -1;

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值