相关链接可点击:
目录
1790_仅执行一次字符串交换能否使两个字符串相等
一、题目
给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。
如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 true ;否则,返回 false 。
二、示例
示例 1:
输入:s1 = "bank", s2 = "kanb"
输出:true
解释:例如,交换 s2 中的第一个和最后一个字符可以得到 "bank"
示例 2:
输入:s1 = "attack", s2 = "defend"
输出:false
解释:一次字符串交换无法使两个字符串相等
示例 3:
输入:s1 = "kelb", s2 = "kelb"
输出:true
解释:两个字符串已经相等,所以不需要进行字符串交换
示例 4:
输入:s1 = "abcd", s2 = "dcba"
输出:false
提示:
- 1 <= s1.length, s2.length <= 100
- s1.length == s2.length
- s1 和 s2 仅由小写英文字母组成
三、思路
题意:
字符串交换:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符;
返回:对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 true ;否则,返回 false 。
根据题意可知,字符交换只有 0 次或 1 次,即不同字符的个数只能有 0 个或 2 个。
因此,思路为:
- 循环遍历两个字符串,找出两个字符串中不同字符的下标,并用变量 index1 和 index2 存储
- 如果两字符串中的字符超过两个,则返回 False
- 如果不同字符只有 2 个,则需要判断:
- 字符串s1的第一个不同字符 与 字符串s2 的第二个不同字符 是否相等;
- 字符串s1的第二个不同字符 与 字符串s2 的第一个不同字符 是否相等;
- 若满足以上两点,返回 True;否则,返回 False。
例如:s1 = "bank", s2 = "kanb"
s1[0] == s2[3] == b 且 s1[3] == s2[0] == k,返回True
例如:s1 = "bank", s2 = "kanc"
s1[0] != s2[3] ,返回False
四、代码
class Solution:
def areAlmostEqual(self, s1: str, s2: str) -> bool:
index1, index2 = -1, -1
for i in range(len(s1)):
if s1[i] != s2[i]:
if index1 == -1:
index1 = i
elif index1 != -1 and index2 == -1:
index2 = i
else:
return False
return s1[index1] == s2[index2] and s1[index2] == s2[index1]
if __name__ == '__main__':
s1 = "bank"
s2 = "kanb"
s = Solution()
ans = s.areAlmostEqual(s1, s2)
print(ans)
1791_找出星型图的中心节点
一、题目
有一个无向的 星型 图,由 n 个编号从 1 到 n 的节点组成。星型图有一个 中心 节点,并且恰有 n - 1 条边将中心节点与其他每个节点连接起来。
给你一个二维整数数组 edges ,其中 edges[i] = [ui, vi] 表示在节点 ui 和 vi 之间存在一条边。请你找出并返回 edges 所表示星型图的中心节点。
二、示例
示例 1:
输入:edges = [[1,2],[2,3],[4,2]]
输出:2
解释:如上图所示,节点 2 与其他每个节点都相连,所以节点 2 是中心节点。
示例 2:
输入:edges = [[1,2],[5,1],[1,3],[1,4]]
输出:1
提示:
- 3 <= n <= 105
- edges.length == n - 1
- edges[i].length == 2
- 1 <= ui, vi <= n
- ui != vi
- 题目数据给出的 edges 表示一个有效的星型图
三、思路
题意:
无向的 星型 图:由 n 个编号从 1 到 n 的节点组成,例如:
中心节点:恰有 n - 1 条边将中心节点与其他每个节点连接起来,如上图中的数字2
edges[i] = [ui, vi] 表示在节点 ui 和 vi 之间存在一条边
例如:edges = [[1,2],[2,3],[4,2]] 中的中心节点 2 在每一个edges[i] 均出现。
因此,思路为:
- 求出每个节点出现的次数,利用dict字典记录
- 返回出现次数最大且次数等于 n - 1 的节点,否则,返回 -1
四、代码
class Solution:
def findCenter(self, edges) -> int:
"""
:param edges: List[List[int]]
:return: int
"""
nums = dict()
for edge in edges:
if edge[0] not in nums:
nums[edge[0]] = 1
else:
nums[edge[0]] += 1
if edge[1] not in nums:
nums[edge[1]] = 1
else:
nums[edge[1]] += 1
# print(nums)
max_value = max(nums.values())
if max_value == len(nums) - 1:
return [k for k, v in nums.items() if v == max_value][0]
if __name__ == '__main__':
s = Solution()
edges = [[1, 2], [2, 3], [4, 2]]
ans = s.findCenter(edges)
print(ans)
1792_最大平均通过率
一、题目
一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes ,其中 classes[i] = [passi, totali] ,表示你提前知道了第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。
给你一个整数 extraStudents ,表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考。你需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大 。
一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。
请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。与标准答案误差范围在 10-5 以内的结果都会视为正确结果。
二、示例
示例 1:
输入:classes = [[1,2],[3,5],[2,2]], extraStudents = 2
输出:0.78333
解释:你可以将额外的两个学生都安排到第一个班级,平均通过率为 (3/4 + 3/5 + 2/2) / 3 = 0.78333 。
示例 2:
输入:classes = [[2,4],[3,9],[4,5],[2,10]], extraStudents = 4
输出:0.53485
提示:
- 1 <= classes.length <= 10 ^ 5
- classes[i].length == 2
- 1 <= passi <= totali <= 10 ^ 5
- 1 <= extraStudents <= 10 ^ 5
三、思路
题意:
二维数组 classes: classes[i] = [passi, totali], 表示第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试
整数 extraStudents:表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考
通过率:等于这个班级通过考试的学生人数除以这个班级的总人数,即 通过率 = pass / total
平均通过率:所有班级的通过率之和除以班级数目,即 平均通过率 = (通过率1 + 通过率2 + ... + 通过率n) / n
需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大
返回:最大平均通过率
因此,思路为:
- 在安排一个聪明学生进班级前,需求出放入后与放入前该班级的通过率之差,即 通过率之差 = (pass + 1) / (total + 1) - pass / total
- 将一个聪明学生放入通过率差值最大的班级
- 重复步骤1,2,直至所有聪明的学生均已安排完毕
在这里,由于每次都需要对各班级的通过率之差进行排序,时间复杂度较高, 因此这里采用了堆排序对通过率之差进行排序。
python 中有内置函数,可直接调用,非常方便!
补充知识:
- import heapq:导入库函数,这里指的是小堆
- heapq.heappush(heap, item):heap堆中添加元素item
- heapq.heappop(heap):删除heap堆中的最小元素
- heapq.heapreplace(heap, item):删除heap堆中的最小元素,并添加元素item
四、代码
import heapq
class Solution:
def maxAverageRatio(self, classes, extraStudents: int) -> float:
"""
:param classes: List[List[int]]
:param extraStudents: int
:return: float
"""
heap = [] # 堆
for singleclass in classes:
tmp = (singleclass[0] + 1) / (singleclass[1] + 1) - (singleclass[0]) / (singleclass[1])
heapq.heappush(heap, [-tmp] + singleclass)
while extraStudents > 0:
first = heap[0]
first[1] += 1
first[2] += 1
tmp = ((first[1] + 1) / (first[2] + 1)) - (first[1] / first[2])
first[0] = -tmp
heapq.heapreplace(heap, first)
extraStudents -= 1
ans = 0.0
while len(heap):
node = heapq.heappop(heap)
ans += node[1] / node[2]
return ans / len(classes)
if __name__ == '__main__':
classes = [[2, 4], [3, 9], [4, 5], [2, 10]]
extraStudents = 4
s = Solution()
ans = s.maxAverageRatio(classes, extraStudents)
# ans = 0.53485
print(ans)
1793_好子数组的最大分数
一、题目
给你一个整数数组 nums (下标从 0 开始)和一个整数 k 。
一个子数组 (i, j) 的 分数 定义为 min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1) 。
一个 好 子数组的两个端点下标需要满足 i <= k <= j 。
请你返回 好 子数组的最大可能 分数 。
二、示例
示例 1:
输入:nums = [1,4,3,7,4,5], k = 3
输出:15
解释:最优子数组的左右端点下标是 (1, 5) ,分数为 min(4,3,7,4,5) * (5-1+1) = 3 * 5 = 15 。
示例 2:
输入:nums = [5,5,4,5,4,1,1,1], k = 0
输出:20
解释:最优子数组的左右端点下标是 (0, 4) ,分数为 min(5,5,4,5,4) * (4-0+1) = 4 * 5 = 20 。
提示:
- 1 <= nums.length <= 10 ^ 5
- 1 <= nums[i] <= 2 * 10 ^ 4
- 0 <= k < nums.length
三、思路
题意:
子数组 (i, j) 的 分数:min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1)
好子数组(i, j):满足 i <= k <= j
返回:好子数组的最大可能分数
因此,思路为:
以下标k为中心,向左,向右进行滑动
- nums[right] >= nums[k] : right + 1
- nums[left] >= nums[k] : left - 1
直到左右边界都出现比nums[k]小的数,计算最大可能分数 ans = (right - left - 1) * nums[k]
四、代码
class Solution:
def maximumScore(self, nums, k: int) -> int:
"""
:param nums: List[int]
:param k: int
:return: int
"""
ans = 0
n = len(nums)
left, right = k, k
for i in range(nums[k], 0, -1):
while left >= 0 and nums[left] >= i:
left -= 1
while right < n and nums[right] >= i:
right += 1
ans = max(ans, (right - left - 1) * i)
if left < 0 and right == n:
break
return ans
if __name__ == '__main__':
nums = [1, 4, 3, 7, 4, 5]
k = 3
s = Solution()
ans = s.maximumScore(nums, k)
print(ans)