模拟
当n==0或1时,不用判断。n-(n&1)的目的是为了区分奇偶数,奇数减一,偶数不变。并且当n==2时,range(2,2,2)为空,index不会超。运用变量存储前两个元素的和,避免多次求和运算。代码如下:
class Solution:
def maxOperations(self, nums: List[int]) -> int:
# 模拟
n = len(nums)
cnt = 1
target = nums[0] + nums[1]
for i in range(2,n-(n&1),2):
# if nums[i] + nums[i+1] != nums[0] + nums[1]:
if nums[i] + nums[i+1] != target:
break
cnt += 1
return cnt
1.排序。当然其实排序可能用处不是很大,后面统计个数还是要遍历。
class Solution:
def countElements(self, nums: List[int]) -> int:
# 满足条件的元素个数即为除去最小值和最大值的元素的数目
# 值得注意的是,最大值和最小值可能有多个
# 排序
n = len(nums)
nums.sort()
if nums[0] == nums[n-1]:
return 0
return n - nums.count(nums[0]) - nums.count(nums[n-1])
2.遍历+函数。下面为简便写法,但是相当于两次遍历。代码如下:
class Solution:
def countElements(self, nums: List[int]) -> int:
# 满足条件的元素个数即为除去最小值和最大值的元素的数目
# 值得注意的是,最大值和最小值可能有多个
# 遍历
min_,max_ = min(nums),max(nums)
if min_ == max_:
return 0
return len(nums) - nums.count(min_) - nums.count(max_)
3.一次遍历。之前有想到边求最大小值边计数,但是由于最大小值数值在变,就放弃了,没有想到可以在最大小值发生改变时,同时将个数清为1。方法参考灵神题解(. - 力扣(LeetCode)),代码如下:
class Solution:
def countElements(self, nums: List[int]) -> int:
# 满足条件的元素个数即为除去最小值和最大值的元素的数目
# 值得注意的是,最大值和最小值可能有多个
# 一次遍历
min_,cntmin,max_,cntmax = inf,0,-inf,0
for x in nums:
if x > max_:
max_,cntmax = x,1
elif x == max_:
cntmax += 1
if x < min_:
min_,cntmin = x,1
elif x == min_:
cntmin += 1
if min_ == max_:
return 0
return len(nums) - cntmax - cntmin
1.遍历,时复O(n^3)。
class Solution:
def arithmeticTriplets(self, nums: List[int], diff: int) -> int:
# 严格递增,无重复数字,寻找范围在[i+1,i+diff]闭区间
# 注意右端点别出界
# 遍历 时复O(n^3)
n = len(nums)
ans = 0
for i in range(n-2):
for j in range(i+1,min(i+diff+1,n-1)):
if nums[j] - nums[i] > diff: #后面不会再有,跳出循环
break
elif nums[j] - nums[i] == diff:
for k in range(j+1,min(j+diff+1,n)):
if nums[k] - nums[j] > diff:
break
elif nums[k] - nums[j] == diff:
ans += 1
return ans
2.哈希表,时复O(n)。方法来自灵神题解(. - 力扣(LeetCode))。代码如下:
class Solution:
def arithmeticTriplets(self, nums: List[int], diff: int) -> int:
# 哈希表 时复O(n)
# 等差三元组
s = set(nums)
return sum(x - diff in s and x + diff in s for x in nums)
优化,来自灵神题解。代码如下:
class Solution:
def arithmeticTriplets(self, nums: List[int], diff: int) -> int:
# 哈希表优化
# 数组严格递增 i,j一定在k前面
ans,s = 0,set()
for x in nums:
if x - diff in s and x - 2*diff in s:
ans += 1
s.add(x)
return ans
3.同向双指针(滑动窗口),时复O(n)。有想到使用滑动窗口,但是没写出来。方法来自灵神题解。代码如下:
class Solution:
def arithmeticTriplets(self, nums: List[int], diff: int) -> int:
# 同向双指针(滑动窗口)
ans,i,j = 0,0,1
for x in nums:
while nums[j] + diff < x:
#j一定小于k,等于时上式>=
j += 1
if nums[j] + diff > x:
continue
# nums[j] + diff == x
while nums[i] + diff < nums[j]:
i += 1
if nums[i] + diff == nums[j]:
ans += 1
return ans
1.模拟
class Solution:
def numberOfMatches(self, n: int) -> int:
# 模拟
ans = 0
while n > 1:
flag = n&1
ans += (n - flag) // 2
n = (n - flag) // 2 + flag
return ans
2.数学(真服了哈哈哈哈,还真没想到)。方法来自宫水三叶题解(. - 力扣(LeetCode))。代码如下:
class Solution:
def numberOfMatches(self, n: int) -> int:
# 数学
# n个队伍淘汰n-1个,每次配对淘汰一个,一共n-1次
return n-1
宫水三叶题解中的引申题目练习:
(1)题目:747. 至少是其他数字两倍的最大数
解题:
遍历
class Solution:
def dominantIndex(self, nums: List[int]) -> int:
# 遍历
# 找出最大值和次大值
# 如果最大值是次大值的两倍则其他满足条件
a,b = -1,-1 #最大,次大
idx = 0
for i,x in enumerate(nums):
if x > a:
a,b = x,a
idx = i
elif x > b:
b = x
return idx if a >= b*2 else -1
(2)题目:1716. 计算力扣银行的钱
解题:
数学
class Solution:
def totalMoney(self, n: int) -> int:
# 第i周 i ... i+6(整周)
# 和为 7i+21
# 然后j周又求和,再加上多余的天数(i==j)
# 7*(1+2+...+j) + 21*j
# 剩余的天数 j+1 ... j+n%7
j = n // 7
# return (j + 1)*j // 2 * 7 + j*21 + sum(range(j+1,j+n%7+1))
mod = n%7
return (j + 1)*j // 2 * 7 + j*21 + (2*j+mod+1)*mod // 2
完
感谢你看到这里!一起加油吧!