群内编号: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
二分查找
这个方法主要也是考虑
- 不在列表里的数怎么处理
- 如果数字出现在边上能不能反应
从而必须设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] > 0
和nums1[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难度得问题暂时先不写了,之后补上。