力扣----哈希表

文章介绍了多个编程题目,包括计算好数对的数目、差的绝对值为K的数对、制造字母异位词的最小步骤、判断变位词组、找数组中重复的数据、检查字符串是否几乎相等、判断数字计数是否等于数位值。解题思路涉及双指针、字符计数和字符串操作等方法。
摘要由CSDN通过智能技术生成

题目

  1. 1512. 好数对的数目
  2. 2006. 差的绝对值为 K 的数对数目
  3. 1347. 制造字母异位词的最小步骤数
  4. 面试题 10.02. 变位词组
  5. 442. 数组中重复的数据
  6. 2068. 检查两个字符串是否几乎相等
  7. 2283. 判断一个数的数字计数是否等于数位的值
  8. 884. 两句话中的不常见单词

解题思路与代码详情

【题1】1512. 好数对的数目

1512. 好数对的数目: 给你一个整数数组 nums 。
如果一组数字 (i,j) 满足 nums[i] == nums[j] 且 i < j ,就可以认为这是一组 好数对
返回好数对的数目。

题目解析: 将所有英文字符前后位置反转,其中字符串中包含非英文字符,若遇非英文字符,则反转时顺位。
解题思路: 设置双指针分别表示前后字符的位置,若当前前后位置都为英文字符,则进行元素互换,若前后位置有任何一处为非英文字符,则顺位。

# python3
class Solution:
    def numIdenticalPairs(self, nums: List[int]) -> int:
        n = len(nums)
        ans=0
        for i in range(n):
            for j in range(i+1,n):
                if nums[i]==nums[j]:
                    ans+=1
        return ans
//C
int numIdenticalPairs(int* nums, int numsSize){
    int ans=0;
    for(int i=0;i<numsSize;i++){
        for(int j=i+1;j<numsSize;j++){
            if(nums[i]==nums[j]){
                ans++;
            }
        }
    }
    return ans;
}

【题2】2006. 差的绝对值为 K 的数对数目

2006. 差的绝对值为 K 的数对数目: 给你一个整数数组 nums 和一个整数 k ,请你返回数对 (i, j) 的数目,满足 i < j 且 |nums[i] - nums[j]| == k 。
|x| 的值定义为:
如果 x >= 0 ,那么值为 x 。
如果 x < 0 ,那么值为 -x

题目解析: 找出一组数中加和为目标值的唯一一对数。
解题思路: 设置前后位置双指针,判断加和与目标值的关系。

#python3
class Solution:
    def countKDifference(self, nums: List[int], k: int) -> int:
        n=len(nums)
        ans=0
        for i in range(n):
            for j in range(i+1,n):
                if abs(nums[i]-nums[j])==k:
                    ans+=1
        return ans
//C
int countKDifference(int* nums, int numsSize, int k){
    int ans=0;
    for(int i=0;i<numsSize;i++){
        for(int j=i+1;j<numsSize;j++){
            if(abs(nums[i]-nums[j])==k){
                ans++;
            }
        }
    }
    return ans;
}

【题3】1347. 制造字母异位词的最小步骤数

**1347. 制造字母异位词的最小步骤数:**给你两个长度相等的字符串 s 和 t。每一个步骤中,你可以选择将 t 中的 任一字符 替换为 另一个字符。
返回使 t 成为 s 的字母异位词的最小步骤数。
字母异位词 指字母相同,但排列不同(也可能相同)的字符串。

题目解析: 比较两个版本号的大小。
解题思路: 字符整型的转换。

#python3
class Solution:
    def minSteps(self, s: str, t: str) -> int:
        hashs=[0]*26
        hasht=[0]*26
        n=len(s)
        ans=0
        for i in range(n):
            hashs[ord(s[i])-ord('a')]+=1
            hasht[ord(t[i])-ord('a')]+=1
        for i in range(26):
            if hashs[i]!=0 and hasht[i]!=0:
                ans+=min(hashs[i],hasht[i])
        ans=n-ans
        return ans
int minSteps(char * s, char * t){
    int hashs[26];
    int hasht[26];
    memset(hashs,0,sizeof(hashs));
    memset(hasht,0,sizeof(hasht));
    int lens=strlen(s);
    int ans=0;
    for(int i=0;i<lens;i++){
        hashs[s[i]-'a']++;
        hasht[t[i]-'a']++;
    }
    for(int i=0;i<26;i++){
        if(hashs[i]!=0&&hasht[i]!=0){
            ans+=fmin(hashs[i],hasht[i]);
        }
    }
    ans=lens-ans;
    return ans;
}

【题4】面试题 10.02. 变位词组

面试题 10.02. 变位词组: 编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。变位词是指字母相同,但排列不同的字符串。
注意:本题相对原题稍作修改

题目解析: 需要在原列表中记录原列表中出现的字符与字符出现次数,若出现次数为1,则仅记录出现的字符,若出现次数大于等于10,则将出现的次数分割成0-9之内的数字。
解题思路:
(1)分别设置表示写入,遍历位置,求算出现次数的指针write,left,right。
(2)每次新字母开始遍历的位置为left,从该位置开始遍历只要字母相同,就继续往下查找,直至字母不再相同,记录该字符出现的次数
(3)将字母以及出现的次数依次替换原列表中的元素
(4)若出现次数大于10,则需要将出现次数分割为0-9以内的数字。

class Solution:
    def compress(self, chars: List[str]) -> int:
        n=len(chars)
        write=0
        left=0
        while left<n:
            num=0
            right=left
            while right<n and chars[right]==chars[left]:
                right+=1
            num=right-left
            chars[write]=chars[left]
            write+=1
            if num>1:
                for c in str(num):
                    chars[write]=c
                    write+=1
            left=right
        return write
//C
void swap(char *a, char *b) {
    char t = *a;
    *a = *b, *b = t;
}
void reverse(char *a, char *b) {
    while (a < b) {
        swap(a++, --b);
    }
}
int compress(char* chars, int charsSize){
    int write=0;
    int left=0;
    int num;
    while(left<charsSize){
        num=0;
        int right;
        right=left;
        while(right<charsSize && chars[right]==chars[left]){
            right++;
        }
        num=right-left;
        chars[write++]=chars[left];
        left=right;
        if(num>1){
            int ancor=write;
            while(num>0){
                chars[write++]=num % 10 +'0';
                num /= 10;  
            }
        reverse(&chars[ancor], &chars[write]);
        }   
}
    return write;
}

【题5】442. 数组中重复的数据

442. 数组中重复的数据: 给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次两次 。请你找出所有出现 两次 的整数,并以数组形式返回。
你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。

题目解析: 反转从下标0到目标元素位置的子字符串。
解题思路: 遍历查找目标元素记录位置,反转子字符串。

class Solution:
    def findDuplicates(self, nums: List[int]) -> List[int]:
        ret=[]
        for value,num in Counter(nums).items():
            if num==2:
                ret.append(value)
        return ret
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findDuplicates(int* nums, int numsSize, int* returnSize){
    int *ret=(int*)malloc(sizeof(int)*numsSize);
    int hash[numsSize];
    int num=0;
    memset(hash,0,sizeof(hash));
    for(int i=0;i<numsSize;i++){
        hash[nums[i]-1]++;
        if(hash[nums[i]-1]==2){
            num++;
            ret[num-1]=nums[i];
        }
    }
    *returnSize=num;
    return ret;
    free(ret);
}

【题6】2068. 检查两个字符串是否几乎相等

2068. 检查两个字符串是否几乎相等: 如果两个字符串 word1 和 word2 中从 ‘a’ 到 ‘z’ 每一个字母出现频率之差都 不超过 3 ,那么我们称这两个字符串 word1 和 word2 几乎相等 。
给你两个长度都为 n 的字符串 word1 和 word2 ,如果 word1 和 word2 几乎相等 ,请你返回 true ,否则返回 false 。
一个字母 x 的出现 频率 指的是它在字符串中出现的次数。

#python3
class Solution:
    def checkAlmostEquivalent(self, word1: str, word2: str) -> bool:
        listhash=[0]*26
        for c in word1:
            listhash[ord(c)-ord('a')]+=1
        for c in word2:
            listhash[ord(c)-ord('a')]-=1
        return all(abs(x) <= 3 for x in listhash)
//C
bool checkAlmostEquivalent(char * word1, char * word2){
    int hash[52];
    memset(hash,0,sizeof(hash));
    int nword1=strlen(word1);
    int nword2=strlen(word2);
    for(int i=0;i<nword1;i++){
        hash[word1[i]-'a']++;
    }
    for(int i=0;i<nword2;i++){
        hash[word2[i]-'a'+26]++;
    }
    for(int i=0;i<26;i++){
        if(hash[i]-hash[i+26]>3||hash[i]-hash[i+26]<-3){
            return false;
        }
    }
    return true;
}

【题7】2283. 判断一个数的数字计数是否等于数位的值

2283. 判断一个数的数字计数是否等于数位的值: 给你一个下标从 0 开始长度为 n 的字符串 num ,它只包含数字。
如果对于 每个 0 <= i < n 的下标 i ,都满足数位 i 在 num 中出现了 num[i]次,那么请你返回 true ,否则返回 false 。

题目解析: 求供暖器与房间之间的距离,确定每个供暖器与每个房间之间的所有最小距离中的最大值。
解题思路: 此处使用了排序+二分排序。
(1)将所有供暖器的位置按升序顺序排序
(2)逐一将房间的位置作为目标值,在供暖器的位置数组中二分查找与该目标值最近的那个值。
(3)(2)中的所有值取最大值。

class Solution:
    def digitCount(self, num: str) -> bool:
        numhash=[0]*10
        n=len(num)
        for c in num:
            numhash[int(c)]+=1
        for i in range(n):
            if numhash[i]!=int(num[i]):
                return False
        return True
//C
bool digitCount(char * num){
    int hash[10];
    memset(hash,0,sizeof(hash));
    int n=strlen(num);
    for(int i=0;i<n;i++){
        hash[num[i]-'0']++;
    }
    for(int i=0;i<n;i++){
        if(hash[i]!=num[i]-'0') return false;
    }
    return true;
}

【题8】884. 两句话中的不常见单词(缺C)

884. 两句话中的不常见单词: 句子 是一串由空格分隔的单词。每个 单词 仅由小写字母组成。
如果某个单词在其中一个句子中恰好出现一次,在另一个句子中却 没有出现 ,那么这个单词就是 不常见的
给你两个** 句子** s1 和 s2 ,返回所有 不常用单词 的列表。返回列表中单词可以按 任意顺序 组织。

题目解析: 求两个整数数组各个元素之间的绝对差值,确定所有绝对差值中的最小值。
解题思路: 此处使用了排序+双指针。
(1)将两个整数数组都按升序顺序排序
(2)逐一比较两个数组元素之间的大小关系,求算绝对差值最小值

class Solution:
    def uncommonFromSentences(self, s1: str, s2: str) -> List[str]:
        list1dict=collections.Counter(s1.split())
        list2dict=collections.Counter(s2.split())
        ret=[]
        for c in list1dict:
            if list1dict[c]==1 and c not in list2dict:
                ret.append(c)
        for c in list2dict:
            if list2dict[c]==1 and c not in list1dict:
                ret.append(c)
        return ret
#题解代码https://leetcode.cn/problems/uncommon-words-from-two-sentences/solution/liang-ju-hua-zhong-de-bu-chang-jian-dan-a8bmz/
class Solution:
    def uncommonFromSentences(self, s1: str, s2: str) -> List[str]:
        freq = Counter(s1.split()) + Counter(s2.split())
    
        ans = list()
        for word, occ in freq.items():
            if occ == 1:
                ans.append(word)
        
        return ans
/*先排序,然后两数字互相逼近*/
/*先排序,然后两数字互相逼近*/
#define ABS_NUM(a)              ((a) > 0  ? (a) : -(a))
#define MIN_NUM(a, b)           ((a) > (b) ? (b) : (a))
/*
long long ABS_NUM(long long a){
    return a>0?a:(-a);
}
long long MIN_NUM(long long a, long long b){
    return a>b?b:a;
}*/

int cmp(const void *a, const void *b) {
    //const int l = *(int *)a;
    //const int r = *(int *)b;
    //return l > r ? 1 : -1;
    return *(int*)a>*(int*)b;
}
int smallestDifference(int* a, int aSize, int* b, int bSize){
    //if (a == NULL || aSize == 0 || b == NULL || bSize == 0) {
        //return 0;
    //}
    qsort(a, aSize, sizeof(int), cmp);
    qsort(b, bSize, sizeof(int), cmp);
    long long min = ABS_NUM((long long)(a[0] - b[0]));
    int i = 0, j = 0;
    while (i < aSize && j < bSize) {
        if (a[i] > b[j]) {
            min = MIN_NUM(min, ABS_NUM((long long)(a[i] - b[j])));
            j++;
        }else if (a[i] < b[j]) {
            min = MIN_NUM(min, ABS_NUM((long long)(a[i] - b[j])));
            i++;
        }else {
            return 0;
        }
    }
    return min;
}

参考文献

  1. https://blog.csdn.net/WhereIsHeroFrom/article/details/124522256
  2. https://blog.csdn.net/WhereIsHeroFrom/article/details/125076627
  3. Python:解析zip函数和zip_longest函数
  4. python zip_longest如何使用
  5. C 库函数 - atoi()
  6. C 库函数 - strtok()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值