Leetcdoe算法之哈希

1、宝石与石头 #771

给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。
J 中的字母不重复,J 和 S中的所有字符都是字母。字母区分大小写,因此”a”和”A”是不同类型的石头。

示例 1:
输入: J = “aA”, S = “aAAbbbb”
输出: 3
思路:实质上就是寻找S中有多少个字符在J中

python版三种思路
1、这种比较常规,很多语言都是这个思路
class Solution:
    def numJewelsInStones(self, J, S):
        k = 0
        for i in range(len(J)):
            for j in range(len(S)):
                if S[j]==J[i]:
                    k+=1
        return k 
2、利用python的特性,进阶,更加简洁
class Solution:
    def numJewelsInStones(self, J, S):
        k = 0
        for s in S:
            if s in J:
                k+=1
        return k 
3、利用python的特性,进一步进阶,更加简洁
class Solution:
    def numJewelsInStones(self, J, S):
        return sum([s in J for s in S])

列表生成式[s in J for s in S]的结果是[True, True, True, False, False, False, False],应用sum()可以计算加和,结果为3,即True的个数

2、两句话中的不常见单词 #884

给定两个句子 A 和 B 。 (句子是一串由空格分隔的单词。每个单词仅由小写字母组成。)
如果一个单词在其中一个句子中只出现一次,在另一个句子中却没有出现,那么这个单词就是不常见的。
返回所有不常用单词的列表。
您可以按任何顺序返回列表。

示例 1:
输入:A = “this apple is sweet”, B = “this apple is sour”
输出:[“sweet”,”sour”]
示例 2:
输入:A = “apple apple”, B = “banana”
输出:[“banana”]

思路及难点:实质上就是将两个句子中的单词合并在一起,把所有相同单词都删除,难点在于识别句子中的单词以及识别相同的单词并全部删除
解决方法:

用python的几种代码思路示例

示例1

class Solution:
    def uncommonFromSentences(self, A, B):
        LA = [] #统计A中没有重复项的元素
        LB = [] #统计B中没有重复项的元素
        f = []  #统计A中有重复项的元素
        g = []  #统计B中有重复项的元素
        k = 0  #用于标记A中空格后的第一个字母
        j = 0  #用于标记B中空格后的第一个字母
        i = 0  #用于遍历A
        t = 0  #用于遍历B
        while i<len(A):
            if A[i]==' ':
                if A[k:i] not in LA and A[k:i] not in f:
                    LA.append(A[k:i])
                elif A[k:i] in LA and A[k:i] not in f:
                    f.append(LA.pop(LA.index(A[k:i]))) 
                k=i+1
            elif i==(len(A)-1):
                i+=1
                if A[k:i] not in LA and A[k:i] not in f:
                    LA.append(A[k:i])
                elif A[k:i] in LA and A[k:i] not in f:
                    f.append(LA.pop(LA.index(A[k:i])))                 
            i+=1

        while t<len(B):
            if B[t]==' ':
                if B[j:t] not in LB and B[j:t] not in g:
                    LB.append(B[j:t])
                elif B[j:t] in LB and B[j:t] not in g:
                    g.append(LB.pop(LB.index(B[j:t])))
                j=t+1
            elif t==(len(B)-1):
                t+=1
                if B[j:t] not in LB and B[j:t] not in g:
                    LB.append(B[j:t])
                elif B[j:t] in LB and B[j:t] not in g:
                    g.append(LB.pop(LB.index(B[j:t])))                   
            t+=1  

        L1 = [i for i in LB if i not in LA  and i not in f]
        L2 = [i for i in LA if i  not in LB  and i not in g]
        L1.extend(L2)
        return L1

这种思路比较常规,没有太多应用python语言的特性,其他语言都可以借鉴

示例2

class Solution:
    def uncommonFromSentences(self, A, B):
        i = 0
        k = 0
        l = [] #统计相同元素的下标
        LA = A.split(' ')
        LB = B.split(' ')
        LA.extend(LB)
        while i<len(LA):
            k= i+1
            while k<len(LA):
                if LA[i]==LA[k]:
                    l.append(i) #这里会重复统计i,下面的k也会重复统计
                    l.append(k)
                k+=1
            i+=1
        l = list(set(l))   #用set去除相同l中元素
        l.sort(reverse=True) #一定要逆序,不然下面的循环会溢出
        for i in l:
            LA.pop(i)
        return LA

示例2用了split()方法,以空格为分隔符分离字符串返回list,统计单词很方便,随后用两个while循环统计相同元素的下标,这里统计下标会有不少重复值,所以随后用set去除重复值,逆序排序之后才能顺利用pop()逐步删除相同元素的下标,不然如果随着pop()的进行,list中下标不断减小,原来的统计的下标会溢出

3、字符串中的第一个唯一字符 #387

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

案例:
s = “leetcode”
返回 0.
s = “loveleetcode”,
返回 2.
注意事项:您可以假定该字符串只包含小写字母。

思路:实质上就是从第一个字符为准,遍历字符串找到相同的就停下,再以第二个字符为准,依次寻找下去,找不到相同的就返回这个字符的下标

python代码示例
class Solution:
    def firstUniqChar(self, s):
        i=0
        j=0
        if len(s)==1:   #如果字符长度为1,直接返回下标0
            return 0
        while i<len(s):
            while j<len(s):
               #两者相等且下标不等时,即比较的不是同一个字符时跳出第一个循化                
                if s[i]==s[j] and i!=j:
                    break
                j+=1
            if(j==len(s)):  #查找到最后还是找不到相同的字符时,直接返回i下标
                return i
            i+=1
            j=0
        return -1

4、 单词模式 #290

给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循相同的模式。

这里的遵循指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应模式。

示例1:
输入: pattern = “abba”, str = “dog cat cat dog”
输出: true

示例 2:
输入:pattern = “abba”, str = “dog cat cat fish”
输出: false

示例 3:
输入: pattern = “aaaa”, str = “dog cat cat dog”
输出: false

思路:先把str的单词提取出来,这里用python中split()方法,以空格为分隔符返回字符串中的单词,比如str = “dog cat cat dog” ,L=str.split(‘ ’)返回L=[‘dog’,’cat’,’cat’,’dog’],然后两个while循环遍历pattern找到相同的则比较str相同下标的是否相同,不相同直接返回false,同理,如果pattern有不同的而str有相同的直接返回false。如果能遍历完,则证明两个模式相同,直接返回true

python代码示例
class Solution:
    def wordPattern(self, pattern, str):
        L=str.split(' ')
        j=1
        i=0
        if len(L)!=len(pattern):   #两者长度不一样,直接返回False
            return False
        while i<len(L):
            while j<len(L):              
                if pattern[j]==pattern[i]:
                    if L[j]!=L[i]:
                        return False
                elif pattern[j]!=pattern[i]:
                    if L[j]==L[i]:
                        return False
                j+=1
            i+=1
            j=i+1  #不从j=0开始循环减少循环次数
        return True
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值