- 仅执行一次字符串交换能否使两个字符串相等
class Solution:
def areAlmostEqual(self, s1: str, s2: str) -> bool:
count = 0
dic1 = defaultdict(int)
dic2 = defaultdict(int)
for i in range(len(s1)):
if s1[i] != s2[i]:
count += 1
dic1[s1[i]] += 1
dic2[s2[i]] += 1
if (count == 0 or count == 2) and dic1 == dic2:
return True
else:
return False
- 找出星型图的中心节点
class Solution:
def findCenter(self, edges: List[List[int]]) -> int:
dic = defaultdict(int)
for edge in edges:
dic[edge[0]] += 1
dic[edge[1]] += 1
for key,value in dic.items():
if value == len(edges):
return key
- 最大平均通过率
1.双重循环(超时)
class Solution:
def maxAverageRatio(self, classes: List[List[int]], extraStudents: int) -> float:
classes.sort(key = lambda x:x[0]/x[1])
while extraStudents:
tmpMax = float("-inf")
tmpIndex = -1
for i in range(len(classes)):
if (classes[i][0] + 1) / (classes[i][1] + 1) - (classes[i][0]) / (classes[i][1]) > tmpMax:
tmpMax = (classes[i][0] + 1) / (classes[i][1] + 1) - (classes[i][0]) / (classes[i][1])
tmpIndex = i
classes[tmpIndex][0] += 1
classes[tmpIndex][1] += 1
extraStudents -= 1
res = 0
for c in classes:
res += (c[0]/c[1]) / len(classes)
return res
复杂度分析
-
时间复杂度:O(mn),其中 m=extraStudents,n是数组classes 的长度。
-
空间复杂度:O(1)。
2.优先队列
class Solution:
def maxAverageRatio(self, classes: List[List[int]], extraStudents: int) -> float:
ans = 0
q = []
diff = lambda x, y: (x + 1) / (y + 1) - x / y
for x, y in classes:
ans += x / y
q.append((-diff(x,y), x ,y ))
heapq.heapify(q)
for _ in range(extraStudents):
d, x, y = heapq.heappop(q)
ans += -d
heapq.heappush(q, (-diff(x+1,y+1), x+1, y+1))
return ans / len(classes)
复杂度分析
- 时间复杂度:O(mlogn),其中 m=extraStudents,n是数组classes 的长度。
- 空间复杂度:O(m),即为优先队列需要使用的空间。
5704.好子数组的最大分数
1.双重循环(超时)
class Solution:
def maximumScore(self, nums: List[int], k: int) -> int:
res = 0
for i in range(len(nums)):
if k >= i:
for j in range(k,len(nums)):
if min(nums[i:j+1]) * (j-i+1) > res:
res = min(nums[i:j+1]) * (j-i+1)
return res
复杂度分析:
- 时间复杂度:O(n2)
- 空间复杂度:O(1)
2.双指针+贪心
思路 :
区间必须得包含下标k
那么可以从k开始向左向右寻找以 nums[k] 为最小值的好子数组:
-
1.nums[r] >= nums[k] : r++
-
2.nums[l] >= nums[k] : l–
直到左右边界都出现比nums[k]小的数,此时计算最大可能分数 res = (r - l - 1) * nums[k]
同时更新 nums[k] 为左右边界中的较大者,继续寻找以 nums[k] 为最小值的好子数组
直到 l < 0 && r == n
class Solution:
def maximumScore(self, nums: List[int], k: int) -> int:
# 定义左右边界l r,最大可能分数res
l = k
r = k
res = 0
while True:
# 左寻找以nums[k]为最小值的好子数组
while l >= 0 and nums[l] >= nums[k]:
l -= 1
# 向右寻找以nums[k]为最小值的好子数组
while r < len(nums) and nums[r] >= nums[k]:
r += 1
# 更新最大可能分数
res = max(res, ((r-l-1) * nums[k]))
# 遍历完数组,直接退出循环新
if l < 0 and r == len(nums):
break
# 更新nums[k] 为左右边界中的较大者
elif l >= 0 and r < len(nums):
nums[k] = max(nums[l], nums[r])
# 左边遍历完了,更新nums[k]为右边界
elif l < 0:
nums[k] = nums[r]
# 右边遍历完了,更新nums[k]为左边界
else:
nums[k] = nums[l]
return res
复杂度分析:
-
时间复杂度:O(n)
-
空间复杂度:O(1)