5701. 仅执行一次字符串交换能否使两个字符串相等(3分,通过率:3610/8247)
给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。
如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 true ;否则,返回 false 。
思路:遍历,如果不同的位数不为0或2,则返回false,如果有两位不同,再判断是否两个交换后可以使字符串相等
class Solution:
def areAlmostEqual(self, s1: str, s2: str) -> bool:
n = len(s1)
save = [i for i in range(n) if s1[i]!=s2[i]]
if len(save)!=2:
return False if save else True
else:
i,j = save[0],save[1]
return True if s1[i]==s2[j] and s1[j]==s2[i] else False
时间复杂度O(n)
5702. 找出星型图的中心节点(3分,通过率:3636/4499)
有一个无向的 星型 图,由 n 个编号从 1 到 n 的节点组成。星型图有一个 中心 节点,并且恰有 n - 1 条边将中心节点与其他每个节点连接起来。
给你一个二维整数数组 edges ,其中 edges[i] = [ui, vi] 表示在节点 ui 和 vi 之间存在一条边。请你找出并返回 edges 所表示星型图的中心节点。
思路:一共n个节点(n>=3),输入给n-1条边,其中每条边都包括中心节点,因此只需比较前两个边,找出众数即可
class Solution:
def findCenter(self, edges: List[List[int]]) -> int:
return edges[0][0] if edges[0][0] in edges[1] else edges[0][1]
时间复杂度O(1)
5703. 最大平均通过率(5分,通过率:1126/4122)
一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes ,其中 classes[i] = [passi, totali] ,表示你提前知道了第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。
给你一个整数 extraStudents ,表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考。你需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大 。
一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。
请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。与标准答案误差范围在 10-5 以内的结果都会视为正确结果。
假设:A班[b,a] B班[d,c] 有一个extraStudent,如何选择?
如果插入A班,则总通过率的提升为(b+1)/(a+1) - b/a = (a-b)/(a+1)a
如果插入B班,同理为(c-d)/(c+1)c
那么只需维护一个大顶堆,每次从中取出一个(b,a),使上式最大即可
思路:python中使用heapq维护一个小顶堆(取负号变成大顶堆)
class Solution:
def maxAverageRatio(self, classes: List[List[int]], extraStudents: int) -> float:
def f(a,b):
return -(a-b)/(a+1)/a
n = len(classes)
clas = [ [f(classes[i][1],classes[i][0]),classes[i][0],classes[i][1]] for i in range(n)]
heapq.heapify(clas)
for i in range(extraStudents):
a = heapq.heappop(clas)
a[1],a[2] = a[1]+1,a[2]+1
a[0] = f(a[2],a[1])
heapq.heappush(clas,a)
return sum([clas[i][1]/clas[i][2] for i in range(n)])/n
时间复杂度O(mlogn),n为classes长度,m=extrastudents
5704. 好子数组的最大分数(6分,通过率:826/3251)
给你一个整数数组 nums (下标从 0 开始)和一个整数 k 。
一个子数组 (i, j) 的 分数 定义为 min(nums[i], nums[i+1], …, nums[j]) * (j - i + 1) 。一个 好 子数组的两个端点下标需要满足 i <= k <= j 。
请你返回 好 子数组的最大可能 分数 。
思路:将nums以k为中心,处理成前驱/后继数组(降序),再调用【12月打卡~Leetcode每日一题前置知识点】84. 柱状图中最大的矩形(难度:困难)的api,即:两次遍历,使用单调栈得出该高度的左右边界,然后求最大面积
class Solution:
def maximumScore(self, nums: List[int], k: int) -> int:
n = len(nums)
cnt = [0]*n #前驱/后继 最小值数组
min_ = nums[k]
for i in range(k,-1,-1):
cnt[i] = min_ = min(min_,nums[i])
min_ = nums[k]
for i in range(k+1,n):
cnt[i] = min_ = min(min_,nums[i])
def largestRectangleArea(heights):
if not heights:
return 0
n = len(heights)
stack,left = [],[0]*n
for i in range(0,n):
while(stack and heights[stack[-1]]>=heights[i]):
stack.pop()
stack.append(i)
left[i] = 0 if len(stack)==1 else stack[-2]+1
stack,right = [],[0]*n
for i in range(n-1,-1,-1):
while(stack!=[] and heights[stack[-1]]>=heights[i]):
stack.pop()
stack.append(i)
right[i] = n-1 if len(stack)==1 else stack[-2]-1
ans = 0
for i in range(n):
ans = max(ans,(right[i]-left[i]+1)*heights[i])
return ans
return largestRectangleArea(cnt)
时间复杂度O(n)