这是第三次参赛,只完成做出了第二题,第三题做一半。其他参考各位大神做法。
一、旅行终点站
1、题目描述:
https://leetcode-cn.com/problems/destination-city/
2、题解:
创建一个集合res,创建一个Counter,先遍历paths一次,将路径中的第一个值的次数+1,并且把路径的两个值添加到res中。再次在res中遍历,查看出现的次数,如果次数为0那么就是终点。
class Solution:
def destCity(self, paths: List[List[str]]) -> str:
res = set()
c = collections.Counter()#创建一个Counter
for path in paths:#让paths中的每一个元素都添加到res中,并将每个path的第一个值出现的次数+1
c[path[0]] += 1
res.add(path[0])
res.add(path[1])
for x in res:#遍历,查看出现次数为0的就是终点
if c[x] == 0:
return x
创建一个集合res,放入所有路径的第二个值,遍历paths一次,如果路径的第一个值在res中,那么删除,最终剩下的就是终点。
class Solution:
def destCity(self, paths: List[List[str]]) -> str:
res = set(path[1] for path in paths)
for path in paths:
if path[0] in res:
res.remove(path[0])
return list(res)[0]
集合去重法,两个集合分别存开头和结尾,差集运算后,剩下的元素就是终点。
class Solution:
def destCity(self, paths: List[List[str]]) -> str:
n = len(paths)
begin = set() # 存储所有起点
end = set() # 存储所有终点
for i in range(n):
begin.add(paths[i][0])
end.add(paths[i][1])
print(begin, end)
where = list(end - begin) # 集合的差集运算
print(where)
return where[0]
3、注意:
collections模块的defaultdict和Counter用法:
defaultdict: dict在使用时,当key值不存在时,直接添加value时会出现错误,使用defaultdict可以很好的规避该错误。defaultdict是对字典类型的补充,它可以给字典的值设置一个类型,当key不存在时可以自动生成相应类型的value。
Counter: 字典子类,为可以哈希的对象计数。追踪元素出现的次数并按照从高到低的顺序排列成字典,对象为key,出现的次数为value。
b = set()
c = collections.Counter()
for p in paths:
c[p[0]] += 1
b.add(p[0])
b.add(p[1])
print(c)
print(c['djz'])
打印出:
Counter({'London': 1})
Counter({'London': 1, 'New York': 1})
Counter({'London': 1, 'New York': 1, 'Lima': 1})
0
二、是否所有 1 都至少相隔 k 个元素
1、题目描述:
https://leetcode-cn.com/problems/check-if-all-1s-are-at-least-length-k-places-away/
2、题解:
自己的解法:
滑动窗口法,维护一个首尾是1的窗口,不断往后走,遇到间隔小于k的直接返回False,否则,走到最后都没遇到,则返回T#
class Solution:
def kLengthApart(self, nums, k) :
#滑动窗口法
if nums == []:
return False
left,right = 0,0
while left <len(nums)-1 and right < len(nums) :
if nums[left] != 1:#先找窗口的左侧为1的下标
left += 1
elif nums[left] == 1:#若窗口的左侧为1,再找窗口的右侧为1的下标
right = left+1 #赋初值
while right <len(nums)-1 and nums[right] != 1:#找窗口右侧为1的下标
right += 1
if nums[right] == 1:#找到窗口的左右,则计算间隔,并与k进行比较
temp = right - left -1
if temp < k:
return False
left =right #移动,新窗口的左侧为原窗口的右侧。继续进行下个循环
elif right == len(nums) -1 :#考虑[1,0,0,0,0]这种情况
break
return True
设置哨兵,并更新哨兵,只要有一个间隔小于k的情况,就返回False。
class Solution:
def kLengthApart(self, nums: List[int], k: int) -> bool:
pre = -k -1 #哨兵,上一个1所在位置下标
for i in range(len(nums)):
if nums[i] == 1:
if i - pre - 1 < k :#间隔有小于k的情况,直接返回False
return False
pre = i
return True
三、绝对差不超过限制的最长连续子数组
2、题解:
滑动窗口法:引入bisect,题后有具体讲解。res是一个有序的数组,很容易得出最大、最小值。维护一个窗口,使窗口里的最大值与最小值之差不大于limit,如果有大于limit的,循环取出最左边的元素,并移动窗口的左侧;否则移动窗口的右侧。
class Solution:
def longestSubarray(self, nums: List[int], limit: int) -> int:
l, r, res, ans = 0, 0, [], 0
while r < len(nums):
bisect.insort(res, nums[r])
while res[-1] - res[0] > limit:
res.remove(nums[l])
l += 1
r += 1
ans = max(ans, len(res))
return ans
3、注意:
1、bisect模块的bisect和insort的用法:
bisect.bisect(a,b): a为列表,b为一个元素:bisect 返回b在列表a中的下标(此时a未改变)。假定列表是有序的。若列表无序,那么会返回插入到列表最后一个合适的位置。
bisect.insort (a,c) : a为列表,b为一个元素:会在列表a中插入元素c到正确位置,假定列表有序(无返回值)。如果列表无序,那么会返回空。默认插入到右边。
a = [1,2]
b = bisect.bisect(a,3)
print(a,b)
c = bisect.insort(a,3)
print(a,c)
结果:
[1, 2] 2
[1, 2, 3] None
2、remove(obj): 移除列表中某个值的第一个匹配(无返回值)。obj为列表中的值
列表的list.pop([index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。index为下标
字典的set.pop(key[,default]) 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
a = [1,2,3,4]
a.remove(3)
print(a)
b = a.pop()
print(a,b)
e = a.pop(0)
print(a,e)
c = {'djz':1,'lsd':2,'dd':3}
d = c.pop('djz')
print(c,d)
结果:
[1, 2, 4]
[1, 2] 4
[2] 1
{'lsd': 2, 'dd': 3} 1
四、有序矩阵中的第 k 个最小数组和
1、题目描述:
https://leetcode-cn.com/problems/find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows/
2、题解:
不断更新res值
class Solution:
def kthSmallest(self, mat: List[List[int]], k: int) -> int:
#不断更新
#m ,n = len(mat),len(mat[0])
res = mat[0]
for row in mat[1:]:
t = []
for x in row:
for y in res:
t.append(x+y)
res = sorted(t)[:k]
return res[-1]
bisect方法:
class Solution:
def kthSmallest(self, mat: List[List[int]], k: int) -> int:
import bisect
res = []
for row in mat:
if not res:
res = mat[0]
else:
temp = []
for x in row:
for y in res:
bisect.insort(temp, x + y)
res = temp
if len(res) > k:
res = res[:k]
return res[-1]