这次的题都还蛮简单的,大概讲一下做法吧
给你一个整数数组 arr ,以及 a、b 、c 三个整数。请你统计其中好三元组的数量。
如果三元组 (arr[i], arr[j], arr[k]) 满足下列全部条件,则认为它是一个 好三元组 。
0 <= i < j < k < arr.length |arr[i] - arr[j]| <= a |arr[j] - arr[k]| <= b |arr[i] - arr[k]| <= c
其中 |x| 表示 x 的绝对值。
返回 好三元组的数量 。
示例 1:
输入:arr = [3,0,1,1,9,7], a = 7, b = 2, c = 3 输出:4 解释:一共有 4
个好三元组:[(3,0,1), (3,0,1), (3,1,1), (0,1,1)] 。示例 2:
输入:arr = [1,1,2,2,3], a = 0, b = 0, c = 1 输出:0 解释:不存在满足所有条件的三元组。
提示:
3 <= arr.length <= 100 0 <= arr[i] <= 1000 0 <= a, b, c <= 1000
给的 arr.length 是 100 我开始还以为是 1000,想了一下觉得 1 0 9 10^9 109 不太能过,又觉得没什么好办法不如硬碰一下暴力做法23333.
class Solution:
def countGoodTriplets(self, arr: List[int], a: int, b: int, c: int) -> int:
n = len(arr)
ans = 0
for i in range(n):
for j in range(i+1,n):
for k in range(j+1,n):
if abs(arr[i]-arr[j])<=a and abs(arr[j]-arr[k])<=b and abs(arr[i]-arr[k])<=c:
ans += 1
return ans
给你一个由 不同 整数组成的整数数组 arr 和一个整数 k 。
每回合游戏都在数组的前两个元素(即 arr[0] 和 arr[1] )之间进行。比较 arr[0] 与 arr[1]
的大小,较大的整数将会取得这一回合的胜利并保留在位置 0 ,较小的整数移至数组的末尾。当一个整数赢得 k
个连续回合时,游戏结束,该整数就是比赛的 赢家 。返回赢得比赛的整数。
题目数据 保证 游戏存在赢家。
示例 1:
输入:arr = [2,1,3,5,4,6,7], k = 2 输出:5 解释:一起看一下本场游戏每回合的情况:
因此将进行 4 回合比赛,其中 5 是赢家,因为它连胜 2 回合。
示例 2:
输入:arr = [3,2,1], k = 10 输出:3 解释:3 将会在前 10 个回合中连续获胜。
示例 3:
输入:arr = [1,9,8,2,3,7,6,4,5], k = 7 输出:9
示例 4:
输入:arr = [1,11,22,33,44,55,66,77,88,99], k = 1000000000 输出:99
提示:
2 <= arr.length <= 10^5
1 <= arr[i] <= 10^6
arr 所含的整数 各不相同 。
1 <= k <= 10^9
对题目的直观思路是,如果获胜条件太低,那么可能到不了最大数就能获胜,如果获胜条件高,就肯定是最大数,因此这个问题被压缩进了 1 0 5 10^5 105 。然后本来想着要直接模拟,但很快意识到,如果一个数想要获得胜利,那么必须打败周围的k个人,那么只需要考虑局部最高点即可,“ a z b c d e …… ” ,除了第一个数,每个数都是打败前一个数上位的,那么只需要他比后 k-1 个数大即可,因此得到了遍历做法。
class Solution:
def getWinner(self, arr: List[int], k: int) -> int:
if k >= len(arr)-1:
return max(arr)
local = arr[0]
cnt = 0
for i in range(1,len(arr)):
if cnt == k:
break
if arr[i]>local:
local = arr[i]
cnt = 1
else:
cnt += 1
return local
给你一个 n x n 的二进制网格 grid,每一次操作中,你可以选择网格的 相邻两行 进行交换。
一个符合要求的网格需要满足主对角线以上的格子全部都是 0 。
请你返回使网格满足要求的最少操作次数,如果无法使网格符合要求,请你返回 -1 。
主对角线指的是从 (1, 1) 到 (n, n) 的这些格子。
示例 1:
输入:grid = [[0,0,1],[1,1,0],[1,0,0]] 输出:3
示例 2:
输入:grid = [[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]] 输出:-1
解释:所有行都是一样的,交换相邻行无法使网格符合要求。示例 3:
输入:grid = [[1,0,0],[1,1,0],[1,1,1]] 输出:0
提示:
n == grid.length n == grid[i].length 1 <= n <= 200 grid[i][j] 要么是 0 要么是 1 。
这个题也不是很难,首先统计每一行最后 0 的个数,只要保证找到 最近的 足够多零的 行逐行填充即可。这里需要一点简单的证明:如果第 k 行是最近的能满足第 i 行需求的行,那么前 i+1 到 k-1 行一定拥有更少的 0 ,因此他们满足的行在 i 之后,因此无论如何提前整理这些行都无法规避第 k 行的交换需求,因此可以放心大胆的计算第 k 行的交换次数而无需考虑是否会影响前面 i+1 到 k-1 行的排列情况。
class Solution:
def calzero(self, grid):
n = len(grid)
zero = [0]*n
for i in range(n):
cnt = 0
for j in range(n-1,0,-1):
if grid[i][j] == 0:
cnt += 1
else:
break
zero[i] = cnt
return zero
def cal(self,a):
if not a:
return
n = len(a)
for i in range(n):
if a[i] >= n-1:
self.ans += i
self.cal(a[:i]+a[i+1:])
break
else:
self.flag = 1
def minSwaps(self, grid: List[List[int]]) -> int:
zero = self.calzero(grid)
self.ans = 0
self.flag = 0
self.cal(zero)
return -1 if self.flag else self.ans
你有两个 有序 且数组内元素互不相同的数组 nums1 和 nums2 。
一条 合法路径 定义如下:
选择数组 nums1 或者 nums2 开始遍历(从下标 0 处开始)。 从左到右遍历当前数组。 如果你遇到了 nums1 和 nums2 中都存在的值,那么你可以切换路径到另一个数组对应数字处继续遍历(但在合法路径中重复数字只会被统计一次)。
得分定义为合法路径中不同数字的和。
请你返回所有可能合法路径中的最大得分。
由于答案可能很大,请你将它对 10^9 + 7 取余后返回。
示例 1:
输入:nums1 = [2,4,5,8,10], nums2 = [4,6,8,9] 输出:30 解释:合法路径包括:
[2,4,5,8,10], [2,4,5,8,9], [2,4,6,8,9], [2,4,6,8,10],(从 nums1 开始遍历)
[4,6,8,9], [4,5,8,10], [4,5,8,9], [4,6,8,10] (从 nums2 开始遍历)
最大得分为上图中的绿色路径 [2,4,6,8,10] 。示例 2:
输入:nums1 = [1,3,5,7,9], nums2 = [3,5,100] 输出:109 解释:最大得分由路径
[1,3,5,100] 得到。示例 3:
输入:nums1 = [1,2,3,4,5], nums2 = [6,7,8,9,10] 输出:40 解释:nums1 和 nums2
之间无相同数字。 最大得分由路径 [6,7,8,9,10] 得到。示例 4:
输入:nums1 = [1,4,5,8,9,11,19], nums2 = [2,3,4,11,12] 输出:61
提示:
1 <= nums1.length <= 10^5 1 <= nums2.length <= 10^5 1 <= nums1[i], nums2[i] <= 10^7 nums1 和 nums2 都是严格递增的数组。
虽然号称是 Hard 题,但是没有感觉到 Hard 的威力,题目其实非常清楚,按照连接点将链表分段之后,在每个连接点有两个选择,因此只需要贪心选择就够了。问题被分解为几个部分:1.如何用不超时的时间找到连接点:这里用了双指针 O(M+N);2.如何贪心选择:这里直接分段前缀和选最大即可
class Solution:
def calnode(self,nums1,nums2):
i, j = 0, 0
m, n = len(nums1), len(nums2)
node = {}
while i<m and j<n:
#print(i,j)
if nums1[i] < nums2[j]:
i+=1
elif nums1[i] > nums2[j]:
j+=1
else:
node[i] = j
i += 1
j += 1
return node
def calsum(self,node,nums1,nums2):
cnt = 0
cnt1 = []
cnt2 = []
for i in range(m):
cnt += nums1[i]
if i in node:
cnt1.append(cnt)
cnt = 0
cnt1.append(cnt)
cnt = 0
for i in range(n):
cnt += nums2[i]
if i in list(node.values()):
cnt2.append(cnt)
cnt = 0
cnt2.append(cnt)
return cnt1,cnt2
def maxSum(self, nums1: List[int], nums2: List[int]) -> int:
debug = 0
mod = 1e9 + 7
node = self.calnode(nums1,nums2)
if debug:
print(node)
cnt1,cnt2 = self.calsum(node,nums1,nums2)
if debug:
print(cnt1,cnt2)
ans = 0
for i in range(len(cnt1)):
ans += max(cnt1[i],cnt2[i])%mod
return int(ans%mod)