LeetCode分类训练:Task3查找(一)

群内编号:2-木铎铎
博文内容学习自DataWhale开源文档:
LeetCode分类训练 Task 3 查找


35. 搜索插入位置

直接法(速度居然能超70%???)

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        if target in nums:
            for i in range(len(nums)):
                if nums[i] == target:
                    return i
        else:
            for i in range(len(nums)):
                if nums[i] > target:
                    return i
            else:
                return i + 1

二分查找
这个方法主要也是考虑

  1. 不在列表里的数怎么处理
  2. 如果数字出现在边上能不能反应
    从而必须设hi = len(nums),保证lo能取边缘值,参考下面这种情况:
Example 3:
Input: [1,3,5,6], 7
Output: 4

这里

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:        
        lo, hi = 0, len(nums)
        while lo < hi:
            mid = (lo + hi) // 2
            if nums[mid] < target:
                lo = mid + 1
            else:
                hi = mid
        return lo
202. 快乐数

此题看起来是比较直接的,就是取出每一位求平方和,检查是否为1,如果为1就终止循环,否则把所得的平方和数再重复上述操作。难点在于,如果这个数是一个无限操作下去都无法得到1的数,循环终止的条件就会略微复杂一点。
这里给到的解法时发现了这个无限过程本身会出现重复这一特征来做的。采用集合这一数据结构来捕捉这个特征,一旦和数出现重复就跳出循环(这也表示次数不能归1,因此并不影响那些能被归一的数的得出)。

class Solution:
    def isHappy(self, n: int) -> bool:
        history = set()
        while n != 1:
            term = 0
            while n != 0:
                term += (n%10)**2
                n = n//10
            n = term
            if term in history:
                return False
            else:
                history.add(term)
        return True
205. 同构字符串

这道题和290题完完全全就是一道题,故本文着重分析290题的思路,此处不再赘述。

242. 有效的字母异位词

先附上我的代码,它超时了。

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:

        def str_to_dic(string):
            tmp = dict()
            for i in range(len(string)):
                tmp[string[i]] = 0
            for i in range(len(string)):
                for j in range(len(string)):
                    if string[i] == string[j]:
                        tmp[string[j]] += 1
            return tmp

        if str_to_dic(s) == str_to_dic(t):
            return True
        else:
            return False

再给出一个使用collections模块的方法,我认为和我的原理是一样的,但它的速度居然能超过92%的人,牛逼!回头研究研究collections的源码。

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        from collections import Counter
        s = Counter(s)
        t = Counter(t)
        if s == t:
            return True
        else:
            return False
290. 单词规律

这道题需要保存单词局部的关系,或者使用能够保留这种局部关系的一种数字编码关联两种字符。首先给出我的代码,它非常慢,只超过了10%的玩家。

class Solution:
    def wordPattern(self, pattern: str, string: str) -> bool:
        dic1 = {}
        dic2 = {}
        for i in range(len(pattern)):
            dic1[i] = pattern[i]
        string = string.split()
        for i in range(len(string)):
            dic2[i] = string[i]

        def helper(dic):
            tmp = dict()
            for k in dic.keys():
                tmp[k] = -1
            for k1 in dic.keys():
                for k2 in dic.keys():
                    if dic[k1] == dic[k2] and tmp[k2] == -1:
                        tmp[k2] = k1
            for k in tmp.keys():
                if tmp[k] == -1:
                    tmp[k] = k
            return tmp
        if helper(dic1) == helper(dic2):
            return True
        else:
            return False

之后再给出一个使用字符串index方法的巧妙写法,其实也没多快就快过40%的人,但是写得很简洁,是我理想中的Python。

class Solution:
    def wordPattern(self,pattern, str):
        str = str.split()
        return list(map(pattern.index,pattern)) == list(map(str.index,str))
349. 两个数组的交集

这道题很简单,就转化成集合以后直接求交集就行了:

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        nums1 = set(nums1)
        nums2 = set(nums2)
        return list(nums1 & nums2)
350. 两个数组的交集 II

这个要求保留共同出现的(最小)次数,但是不考虑最后输出的顺序。可以用字典来存储出现和次数这两个要素。
这次学会了,使用collections模块。

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        from collections import Counter
        nums1 = Counter(nums1)
        pub = []
        for k in nums2:
            if nums1[k] > 0:
                pub.append(k)
                nums1[k] -= 1
        return pub

这里面还有一个地方要注意一下,就是nums1[k] > 0nums1[k] -= 1这两个条件用得挺好,毕竟时交集,虽然记录次数,但是仍然只能匹配一次(也就是最少匹配次数),从而没匹配到一次就要减去一次,相应的判断条件也就应该写成是判断键得值(实际这就是定义这个字典希望达到的目的)。

451. 根据字符出现频率排序

自己写的代码,和文档给出的差不多。只有约53%。

class Solution:
    def frequencySort(self, s: str) -> str:
        from collections import Counter
        s_dic = Counter(s)
        s_sorted = sorted(s_dic.items(),key = lambda x:x[1],reverse = True)
        result = ''
        for item in s_sorted:
            for i in range(item[1]):
                result += item[0]
        return result
540. 有序数组中的单一元素

上一期学了python按位异或操作,有一道题就是这个,这里重现了一波,效率确实高(80%):

class Solution:
    def singleNonDuplicate(self, nums: List[int]) -> int:
        term = 0
        for num in nums:
            term ^= num
        return term

HARD难度得问题暂时先不写了,之后补上。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值