Leetcode周赛_198学习笔记

学习来源:

leetcode官方题解

1518

1、模拟:
先把所有的酒喝完,得到n个空酒瓶。随后,每次可以拿e个空酒瓶换1瓶新酒,将这1瓶新酒喝完,与剩下的e-1个酒瓶,去换新酒……

res = numBottles
emptyBottles = numBottles
while emptyBottles >= ExchangeBottles:
	# 换酒
	emptyBottles -= ExchangeBottles
	# 喝完新酒
	emptyBottles += 1
	# 多喝了一瓶
	res += 1
return res

2、数学方法:
方法1中可以看出,每次换酒后,空瓶子会减少e-1个,直到剩余空酒瓶无法换取新酒。假设当前一共换了n瓶,则有:emptyBottles = emptyBottles - n*(e-1)。因此,只需求解使得emptyBottles - n*(e-1) < ExchangeBottles成立的最小n。

if numBottles < ExchangeBottles:
	return numBottles
else:
	numBottles += (numBottles-ExchangeBottles)//(ExchangeBottles-1)+1
	return numBottles
1519

算法思想:DFS
tips:当题目只说给出一棵树,或者说连通的无环无向图时,需要考虑的含义,l = [a,b]不表示ab的父节点,只能说明二者存在连线。
DFS传递父节点方法:

edge_list = collections.defaultdict(list)
# 存储节点间关系
for i,j in edges:
	edge_list[i].append(j)
	edge_list[j].append(i)
def dfs(cur_node,pre_node):
	# 统计当前节点的label
	count_list[cur_node][ord(labels[cur_node])-ord('a')] = 1
	# 深度搜索当前节点下所有相连节点的label
	for next_node in edge_list[cur_node]:
		# 排除父节点
		if next_node != pre_node:
		
			dfs(next_node,cur_node)
			for i in range(26):
				count_list[cur_node][i] += count_list[next_node][i]
count_list = [[0]*26 for _ in range(n)]
dfs(0,-1)
res = []
for i in range(n):
      res.append(count_list[i][ord(labels[i])-ord('a')])
return res

DFS访问列表标记

edge_list = collections.defaultdict(list)
# 存储节点间关系
for i,j in edges:
    edge_list[i].append(j)
    edge_list[j].append(i)
# 传递访问标记列表
def dfs(cur_node,visit):
    visit[cur_node] = 1
    count_list[cur_node][ord(labels[cur_node])-ord('a')] = 1
    for next_node in edge_list[cur_node]:
    
        if visit[next_node] == 0:
        
            dfs(next_node,visit)
            for i in range(26):
                count_list[cur_node][i] += count_list[next_node][i]
count_list = [[0]*26 for _ in range(n)]
visit = [0 for _ in range(n)]
dfs(0,visit)
res = []
for i in range(n):
    res.append(count_list[i][ord(labels[i])-ord('a')])
return res
1520

算法思想:贪心
template:有一个[0,n-1]的线段,其中n=s.length,要求我们用尽可能多的小线段覆盖这个线段,且线段之间不能重合,线段之和最小。
answer_tips:将可用线段按右端点为第一关键字,长度为第二关键字进行排序。随后从前往后遍历线段,遇到可以加入的直接贪心添加。
要求2强调若一个子字符串包含c,则s中所有的c都应该包含于该字串。

# 先创建segment类
class segment():
	def __init__(self,left=-1,right=-1):
		self.left = left
		self.right = right
	
	# 增加富比较
	def __lt__(self,other):
		if self.right == other.right:
			return self.left > other.left
		else:
			return self.right < other.right

seg = [segment() for _ in range(26)]
# 预处理左右端点
lens = len(s)
for i in range(lens):
	cur_ind = ord(i)-ord('a')
	if seg[cur_ind].left == -1:
		seg[cur_ind].left = seg[cur_ind].right = i
	else:
		seg[cur_ind].right = i

# 处理每个片段,使之满足条件2
for i in range(26):
	if seg[i].left != -1:
		# 处理当前片段的每个字符
		j = seg[i].left
		while j <= seg[i].right:
			cur_ind = ord(j)-ord('a')
			if seg[cur_ind].left >= seg[i].left and seg[cur_ind].right <= seg[i].right:
				pass
			else:
				seg[i].left = min(seg[i].left,seg[cur_ind].left)
				seg[i].right = max(seg[i].right,seg[cur_ind].right)
				j = seg[i].left
			j += 1

# 贪心算法,此时需要先根据右端点进行排序,随后按照字符串长度排序,返回类中定义排序
seg.sort()
res = []
end = -1
for i in seg:
	left, right = i.left, i.right
	if left == -1:
		continue
	# 此时已经完成排序,只需满足条件1:无重叠(严格无重叠)
	elif end == -1 or left > end:
		end = right
		res.append(s[left:right+1])
return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值