暑期练习
0705
494. 目标和
首先考虑了使用dfs但是结果超时
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
def dfs(nums,target,index,n):
if n==index:
if target==0:
return 1
else :
return 0
return dfs(nums,target-nums[index],index+1,n)+dfs(nums,target+nums[index],index+1,n)
return dfs(nums,target,0,len(nums))
接着使用dp得到结果
遍历[-1000,1000]的所有可能性
j + 1000是为了变量的映射
dp[i-1][j + 1000]可以直接跳到dp[i][j + nums[i] + 1000]和dp[i][j - nums[i] + 1000],理由是i-1 \(\rightarrow\) i只需要\(\pm\) nums[i]+1000,原因是dp[i][j]是i个数组成数字j的方案数。
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
n = len(nums)
dp = [[0] * 2001 for _ in range(n)]
dp[0][nums[0] + 1000] += 1
dp[0][-nums[0] + 1000] += 1
for i in range(1, n):
for j in range(-1000, 1001):
if dp[i-1][j + 1000] > 0:
dp[i][j + nums[i] + 1000] += dp[i-1][j + 1000]
dp[i][j - nums[i] + 1000] += dp[i-1][j + 1000]
return dp[n-1][target + 1000]
3115. 质数的最大距离
"""
简单的判断,双指针左右同时搜索,遇到第一个质数就停下,如果两个指针都停下就结束返回结果
需要注意的重点是continue不要忘记,遇到了质数之后指针不需要继续向前,以及while f or r:,应该是两个指针都查找到才停止,只要有一个没有找到就应该继续,所以需要使用or而不是and。
"""
class Solution:
def maximumPrimeDifference(self, nums: List[int]) -> int:
def is_prime(num):
if num <= 1:
return False
for i in range(2, int(num**0.5) + 1):
if num % i == 0:
return False
return True
n=len(nums)
left=0
right=n-1
f,r=True,True
while f or r:
if f:
if is_prime(nums[left]):
f=False
continue
left+=1
if r:
if is_prime(nums[right]):
r=False
continue
right-=1
return right-left
//Java
class Solution {
public int maximumPrimeDifference(int[] nums) {
int n=nums.length;
int left=0;
int right=n-1;
boolean f = true;
boolean r = true;
while (f || r) {
if (f) {
if (isPrime(nums[left])) {
f = false;
continue;
}
left++;
}
if (r) {
if (isPrime(nums[right])) {
r = false;
continue;
}
right--;
}
}
return right - left;
}
private boolean isPrime(int num) {
if (num <= 1) {
return false;
}
for (int i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
}
3099. 哈沙德数
#非常基础
class Solution {
public int sumOfTheDigitsOfHarshadNumber(int x) {
int sum=0;
int temp=x;
while (temp>0){
sum += temp % 10;
temp /= 10;
}
if (x%sum==0){
return sum;
}
else{
return -1;
}
}
}
3033. 修改矩阵
#基础题
class Solution:
def modifiedMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
m=len(matrix)
n=len(matrix[0])
record=[]
ma=[0]*n
for i in range(n):
for j in range(m):
if matrix[j][i]==-1:
record.append([j,i])
ma[i]=max(ma[i],matrix[j][i])
for j,i in record:
matrix[j][i]=ma[i]
return matrix
0706
3101. 交替子数组计数
"""
本题重点是理解,dp[i]的状态,我这里假设的是以nums[i]为结尾的子数组为交替子数组的数量,所以结尾需要sum(dp)
装填转移方程为1.
$$
dp[i]=dp[i-1]+1 if nums[i] != nums[i-1]
dp[i]=1 if nums[i] = nums[i-1]
$$
举[1,2,2,1]作为例子
i=0时显然dp[0]=1,i=1的时候dp[1]=1+1=2{[2],[1,2]两种[1]不算在内,因为假设的是以nums[i]为结尾的子数组为交替子数组的数量)}
dp[2]=1,dp[3]=2
return 1+2+2+1=6
"""
class Solution:
def countAlternatingSubarrays(self, nums: List[int]) -> int:
n = len(nums)
if n == 1:
return 1
dp= [1] * n
dp[1]= 2 if nums[0] != nums[1] else 1
for i in range(2,n):
if nums[i] != nums[i-1]:
dp[i] = dp[i-1]+1
else:
dp[i] = 1
return sum(dp)
接下来是用时和内存的改进,使用滚动数组,因为我们注意到状态只和前一个状态有关也就是dp[i]只会和dp[i-1]有关,因此我们只需要一个参数last记录前一状态即可
class Solution:
def countAlternatingSubarrays(self, nums: List[int]) -> int:
n = len(nums)
res=1
if n == 1:
return res
last=2 if nums[0]!=nums[1] else 1
res+=last
for i in range(2,n):
if nums[i] != nums[i-1]:
last = last+1
else:
last = 1
res+=last
return res
0707
1958. 检查操作是否合法
#纯纯折磨人,枚举
class Solution:
def checkMove(self, board: List[List[str]], rMove: int, cMove: int, color: str) -> bool:
# 判断每个方向是否存在以操作位置为起点的好线段
def check(dx: int, dy: int) -> bool:
x, y = rMove + dx, cMove + dy
step = 1 # 当前遍历到的节点序号
while 0 <= x < 8 and 0 <= y < 8:
if step == 1:
# 第一个点必须为相反颜色
if board[x][y] == "." or board[x][y] == color:
return False
else:
# 好线段中不应存在空格子
if board[x][y] == ".":
return False
# 遍历到好线段的终点,返回 true
if board[x][y] == color:
return True
step += 1
x += dx
y += dy
# 不存在符合要求的好线段
return False
# 从 x 轴正方向开始逆时针枚举 8 个方向
dx = [1, 1, 0, -1, -1, -1, 0, 1] # 行改变量
dy = [0, 1, 1, 1, 0, -1, -1, -1] # 列改变量
for k in range(8):
if check(dx[k], dy[k]):
return True
return False
100339. 找出加密后的字符串
class Solution:
def getEncryptedString(self, s: str, k: int) -> str:
n = len(s)
ret = ""
for i in range(n):
tmp = (i+k)%n
ret += s[tmp]
return ret
100328. 生成不含相邻零的二进制字符串
class Solution:
def validStrings(self, n: int) -> List[str]:
if n == 1:
return ["0", "1"]
queue = deque([["0", "0"]])
queue.append(["1", "1"])
res = []
while queue:
q = queue.popleft()
if len(q[1]) == n:
res.append(q[1])
else:
if q[0] == "0":
queue.append(["1", q[1] + "1"])
if q[0] == "1":
queue.append(["0", q[1] + "0"])
queue.append(["1", q[1] + "1"])
return res
100359. 统计 X 和 Y 频数相等的子矩阵数量
class Solution:
"""
使用prefix_x_count[i][j]记录[0][0] &\rightarrow& [i][j]位置的前缀和x的总数,使用prefix[i][j]记录 [0][0] &\rightarrow& [i][j]位置的 x - y的差值
"""
def numberOfSubmatrices(self, grid: List[List[str]]) -> int:
m, n = len(grid), len(grid[0])
prefix = [[0] * n for _ in range(m)]
prefix_x_count = [[0] * n for _ in range(m)]
res = 0
for i in range(m):
for j in range(n):
x = 1 if grid[i][j] == 'X' else 0
if i > 0:
x += prefix_x_count[i - 1][j]
if j > 0:
x += prefix_x_count[i][j - 1]
if i > 0 and j > 0:
x -= prefix_x_count[i - 1][j - 1]
prefix_x_count[i][j] = x
for i in range(m):
for j in range(n):
x = 1 if grid[i][j] == 'X' else 0
y = 1 if grid[i][j] == 'Y' else 0
if i > 0:
x += prefix[i - 1][j]
if j > 0:
x += prefix[i][j - 1]
if i>0 and j>0:
x -= prefix[i - 1][j - 1]
prefix[i][j] = x - y
if prefix[i][j] == 0 and prefix_x_count[i][j] >0:
res += 1
return res
0708
724. 寻找数组的中心下标
#基础题
class Solution:
def pivotIndex(self, nums: List[int]) -> int:
left=0
Sum=sum(nums)
n=len(nums)
for i in range(n):
right=Sum-left-nums[i]
if left==right:
return i
else:
left+=nums[i]
return -1
class Solution {
public int pivotIndex(int[] nums) {
int left=0;
int Sum = Arrays.stream(nums).sum();
int n=nums.length;
int right;
for (int i=0;i<n;i++){
right=Sum-left-nums[i];
if(right==left){
return i;
}
else{
left+=nums[i];
}
}
return -1;
}
}
0709
2785. 将字符串中的元音字母排序
class Solution:
def sortVowels(self, s: str) -> str:
vowels = 'aeiouAEIOU'
# 提取元音字母并排序
vowel_list = sorted([char for char in s if char in vowels])
# 结果字符串初始化为列表形式
result = list(s)
# 用于跟踪元音字母的插入位置
vowel_index = 0
# 遍历字符串,将元音字母按排序后的顺序插入到对应位置
for i in range(len(s)):
if s[i] in vowels:
result[i] = vowel_list[vowel_index]
vowel_index += 1
# 将列表转换回字符串
return ''.join(result)
2833. 距离原点最远的点
# 等级2
class Solution:
def furthestDistanceFromOrigin(self,moves: str) -> int:
count=Counter(moves)
return count["_"]+abs(count["R"] - count["L"])
0710
2970. 统计移除递增子数组的数目 I
class Solution:
def incremovableSubarrayCount(self, nums: List[int]) -> int:
n = len(nums)
return sum([self.isIncreasing(nums[:i] + nums[j+1:]) for i in range(n) for j in range(i, n)])
def isIncreasing(self, nums):
if len(nums) == 0:
return True
return all(nums[i] < nums[i + 1] for i in range(len(nums) - 1))
0711
2139. 得到目标值的最少行动次数
# 超出内存限制
class Solution:
def minMoves(self, target: int, maxDoubles: int) -> int:
queue = deque([[1, 0, 0]])
res = 10 ** 9
while queue:
num, cnt, d = queue.popleft()
if num>target:
continue
if num == target:
res = min(res, cnt)
continue
if d < maxDoubles:
queue.append([num * 2, cnt + 1, d + 1])
queue.append([num + 1, cnt + 1, d])
return res
"""
这道题目需要用到逆向思维+贪心算法
因此如果当前整数为偶数,并且还有剩余的折半操作次数,我们就执行折半操作,否则执行递减操作。
"""
class Solution:
def minMoves(self, target: int, maxDoubles: int) -> int:
ans = 0
while maxDoubles and target != 1:
ans += 1
if target % 2 == 1:
target -= 1
else:
maxDoubles -= 1
target //= 2
ans += (target - 1)
return ans
0712
2974. 最小数字游戏
# 基础题
class Solution:
def numberGame(self, nums: List[int]) -> List[int]:
nums.sort()
n=len(nums)
for i in range(1, n, 2):
nums[i], nums[i-1] = nums[i-1], nums[i]
return nums
0713
3011. 判断一个数组是否可以变为有序
class Solution:
def canSortArray(self, nums: List[int]) -> bool:
n = len(nums)
i = 0
while i < n:
start = i
ones = nums[i].bit_count()
i += 1
while i < n and nums[i].bit_count() == ones:
i += 1
nums[start:i] = sorted(nums[start:i])
return all(x <= y for x, y in pairwise(nums))
0714
807. 保持城市天际线
class Solution:
def maxIncreaseKeepingSkyline(self, grid: List[List[int]]) -> int:
R=list(map(max,grid))
C=list(map(max,zip(*grid)))
n=len(R)
res=0
for i in range(n):
for j in range(n):
res+=(min(C[j],R[i])-grid[i][j])
return res
//Java
class Solution {
public int maxIncreaseKeepingSkyline(int[][] grid) {
int n=grid.length;
int [] R=new int[n];
int [] C=new int[n];
int res=0;
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
R[i]=Math.max(R[i],grid[i][j]);
C[j]=Math.max(C[j],grid[i][j]);
}
}
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
res+=(Math.min(R[i],C[j])-grid[i][j]);
}
}
return res;
}
}
0715
3216. 交换后字典序最小的字符串
class Solution:
def getSmallestString(self, s: str) -> str:
n=len(s)
ss=list(s)
for i in range(n-1):
if (int(ss[i])%2) == (int(ss[i+1])%2) and (int(ss[i]) > int(ss[i+1])):
ss[i],ss[i+1]=ss[i+1],ss[i]
return "".join(ss)
return s
//Java
class Solution {
public String getSmallestString(String s) {
char [] t=s.toCharArray();
char temp=0;
for (int i=0;i<t.length-1;i++){
if (t[i]>t[i+1] && t[i+1]%2==t[i]%2){
temp=t[i];
t[i]=t[i+1];
t[i+1]=temp;
break;
}
}
return new String(t);
}
}
3217. 从链表中移除在数组中存在的节点
"""
应该重点注意
if cur.next.val in st:
cur.next = cur.next.next # 删除
else:
cur = cur.next # 向后移动
而不是
if cur.next.val in st:
cur.next = cur.next.next # 删除
cur = cur.next # 向后移动cur.next.next就是安全的因为我们直接跳到了cur -> cur.next.next的位置然后使用cur.next导致cur.next.next从始至终都被跳过了
而且如果cur.next.next为NULL还会发生"Nonetype".next/val的错误。
这是因为如果是下者我们就以为
"""
class Solution:
def modifiedList(self, nums: List[int], head: Optional[ListNode]) -> Optional[ListNode]:
st = set(nums)
cur = dummy = ListNode(next=head)
while cur.next:
if cur.next.val in st:
cur.next = cur.next.next # 删除
else:
cur = cur.next # 向后移动
return dummy.next
0716
2956. 找到两个数组中的公共元素
class Solution:
def findIntersectionValues(self, nums1: List[int], nums2: List[int]) -> List[int]:
res=[0,0]
n=len(nums1)
m=len(nums2)
for i in range(n):
if nums1[i] in nums2:
res[0]+=1
for j in range(m):
if nums2[j] in nums1:
res[1]+=1
return res
//Java
class Solution {
public int[] findIntersectionValues(int[] nums1, int[] nums2) {
int[] res = new int[2];
for (int x1 : nums1) {
for (int x2 : nums2) {
if (x1 == x2) {
res[0]++;
break;
}
}
}
for (int x2 : nums2) {
for (int x1 : nums1) {
if (x2 == x1) {
res[1]++;
break;
}
}
}
return res;
}
}
0719
3096. 得到更多分数的最少关卡数目
"""
本题的重点在于range(n-1)因为每个人至少都要参加一场比赛
"""
class Solution:
def minimumLevels(self, possible: List[int]) -> int:
total=sum(possible)-(len(possible)-sum(possible))
n=len(possible)
last=0
cur=0
for i in range(n-1):
if possible[i]==1:
cur+=1
else:
cur-=1
if cur>total/2:
return i+1
return -1
//Java的需要注意的点是float total 而不是int total
class Solution {
public int minimumLevels(int[] possible) {
float total=0;
int n=possible.length;
int cur=0;
for (int i=0;i<n;i++){
if (possible[i]==1){
total+=1;
}
else{total-=1;}
}
for (int i=0;i<n-1;i++){
if (possible[i]==1){
cur+=1;
}
else{cur-=1;}
if (cur>total/2){
return i+1;
}
}
return -1;
}
}
0721
1186. 删除一次得到子数组最大和
"""
官网题解
dp1表示的是dp[i][1]是以arr[i]为结尾删除一次的最大子数组和
dp0表示的是dp[i][0]是以arr[i]为结尾删除零次的最大子数组和
因此dp[i][1]=max(dp[i-1][0],dp[i-1][1]+arr[i])前者指的是从dp[i-1][0]删除arr[i]直接跳到dp[i][1],后者因为[0,i-1]已经删除过一次,所以直接加上arr[i]
"""
class Solution:
def maximumSum(self, arr: List[int]) -> bool:
dp0, dp1, res = arr[0], 0, arr[0]
for i in range(1, len(arr)):
dp1 = max(dp0, dp1 + arr[i])
dp0 = max(dp0, 0) + arr[i]
res = max(res, max(dp0, dp1))
return res
0722
2101. 引爆最多的炸弹
"""
错误分析
1. 引爆炸弹是单向的,我却单纯的以为是双向的,简要例子,2,3都可以引爆1但是不能说成是1引爆了2,3不答案已经改变了
2. 不需要set去记录,这个是多联通的,例子:1,2,3,4 中 4可以引爆1,3也可以啊如果使用全局visited那么1已经在开始就被我手动引爆了,如果引爆不是单向而是双向的话需要全局visited但是这里不需要因为如果是全局visited那么就是一个求联通块的问题,但是在这里只是单向联通,4->1,3->1 4和3可以是无关的因为不能通过1去引爆他们。
"""
class Solution:
def maximumDetonation(self, bombs: List[List[int]]) -> int:
n=len(bombs)
G=[[0]*n for _ in range(n)]
for i in range(n-1):
for j in range(i+1,n):
if (bombs[i][0]-bombs[j][0])**2+(bombs[i][1]-bombs[j][1])**2 <= (max(bombs[i][2],bombs[j][2]))**2:
G[i][j]=1
G[j][i]=1
visited=set()
def dfs(i):
for j in range(n):
if G[i][j]==1 and j not in visited:
visited.add(j)
dfs(j)
res=0
for i in range(n):
if i in visited:
continue
else:
last=len(visited)
visited.add(i)
dfs(i)
res=max(res,len(visited)-last)
return res
class Solution:
def maximumDetonation(self, bombs: List[List[int]]) -> int:
n=len(bombs)
G=[[0]*n for _ in range(n)]
for i in range(n):
for j in range(n):
if i!=j and (bombs[i][0]-bombs[j][0])**2+(bombs[i][1]-bombs[j][1])**2 <= (bombs[i][2])**2:
G[i][j]=1
def dfs(i):
for j in range(n):
if G[i][j]==1 and j not in visited:
visited.add(j)
dfs(j)
res=0
for i in range(n):
visited=set()
dfs(i)
visited.add(i)
res=max(res,len(visited))
return res
#使用邻接表
def maximumDetonation(self, bombs: List[List[int]]) -> int:
n=len(bombs)
G=defaultdict(list)
for i in range(n):
for j in range(n):
if i!=j and (bombs[i][0]-bombs[j][0])**2+(bombs[i][1]-bombs[j][1])**2 <= (bombs[i][2])**2:
G[i].append(j)
def dfs(i):
for j in G[i]:
if j not in visited:
visited.add(j)
dfs(j)
res=0
for i in range(n):
visited=set()
dfs(i)
visited.add(i)
res=max(res,len(visited))
return res
# 使用enumerate会快一点点
class Solution:
def maximumDetonation(self, bombs: List[List[int]]) -> int:
n=len(bombs)
G=defaultdict(list)
for i, (x, y, r) in enumerate(bombs):
for j, (x2, y2, _) in enumerate(bombs):
dx = x - x2
dy = y - y2
if j != i and dx * dx + dy * dy <= r * r:
G[i].append(j) # i 可以引爆 j
def dfs(i):
for j in G[i]:
if j not in visited:
visited.add(j)
dfs(j)
res=0
for i in range(n):
visited=set()
dfs(i)
visited.add(i)
res=max(res,len(visited))
return res
0722
3226. 使两个整数相等的位更改次数
class Solution:
def minChanges(self, n: int, k: int) -> int:
return -1 if (n & k) != k else (n ^ k).bit_count()
3222. 求出硬币游戏的赢家
class Solution {
public String losingPlayer(int x, int y) {
int turn = 1;
while (x >= 1 && y >= 4) {
turn ^= 1;
x--;
y -= 4;
}
return turn == 0 ? "Alice" : "Bob";
}
}
0724
2765. 最长交替子数组
class Solution:
def alternatingSubarray(self, nums: List[int]) -> int:
ans = -1
i, n = 0, len(nums)
while i < n - 1:
if nums[i + 1] - nums[i] != 1:
i += 1 # 直接跳过
continue
i0 = i # 记录这一组的开始位置
i += 2 # i 和 i+1 已经满足要求,从 i+2 开始判断
while i < n and nums[i] == nums[i - 2]:
i += 1
# 从 i0 到 i-1 是满足题目要求的(并且无法再延长的)子数组
ans = max(ans, i - i0)
i -= 1
return ans
2766. 重新放置石块
class Solution:
def relocateMarbles(self, nums: List[int], moveFrom: List[int], moveTo: List[int]) -> List[int]:
n=len(nums)
block=set()
for i in range(n):
block.add(nums[i])
for mv in zip(moveFrom,moveTo):
if mv[0] in block:
block.remove(mv[0])
block.add(mv[1])
return sorted(list(block))
class Solution:
def relocateMarbles(self, nums: List[int], moveFrom: List[int], moveTo: List[int]) -> List[int]:
st = set(nums)
for f, t in zip(moveFrom, moveTo):
st.remove(f)
st.add(t)
return sorted(st)
class Solution {
public List<Integer> relocateMarbles(int[] nums, int[] moveFrom, int[] moveTo) {
Set<Integer> set= new HashSet<>(nums.length);
for (int x:nums){
set.add(x);
}
for (int i=0;i<moveFrom.length;i++){
set.remove(moveFrom[i]);
set.add(moveTo[i]);
}
List<Integer> res=new ArrayList<>(set);
Collections.sort(res);
return res;
}
}
0725
2844. 生成特殊数字的最少操作
class Solution:
def minimumOperations(self, num: str) -> int:
n = len(num)
def f(tail: str) -> int:
i = num.rfind(tail[1])
if i <= 0:
return n
# 也可以写 num[:i].rfind(tail[0]),但切片需要额外空间
i = num.rfind(tail[0], 0, i)
return n if i < 0 else n - i - 2
return min(n - ('0' in num), f("00"), f("25"), f("50"), f("75"))
0726
2740. 找出分区值
class Solution:
def findValueOfPartition(self, nums: List[int]) -> int:
nums.sort()
res=10**9
n=len(nums)
for i in range(1,n):
res=min(res,nums[i]-nums[i-1])
return res
//Java
class Solution {
public int findValueOfPartition(int[] nums) {
Arrays.sort(nums);
int res=Integer.MAX_VALUE;
for (int i=1;i<nums.length;i++){
res=Math.min(res,nums[i]-nums[i-1]);
}
return res;
}
}
2834. 找出美丽数组的最小和
# 模拟超时
class Solution:
def minimumPossibleSum(self, n: int, target: int) -> int:
l=0
res=0
for i in range(1,10**9):
if l==n:
break
if target-i < i and target - i >0:
continue
else:
res+=i
l+=1
return res%(10**9+7)
# 数学问题
class Solution:
def minimumPossibleSum(self, n: int, target: int) -> int:
mod = 10**9 + 7
m = target // 2
if n <= m:
return ((1 + n) * n // 2) % mod
return ((1 + m) * m // 2 + (target * 2 + (n - m) - 1) * (n - m) // 2) % mod
2580. 统计将重叠区间合并成组的方案数
# 按start_i排序
class Solution:
def countWays(self, ranges: List[List[int]]) -> int:
ranges.sort(key=lambda p: p[0])
m, max_r = 0, -1
for l, r in ranges:
if l > max_r: # 无法合并
m += 1 # 新区间
max_r = max(max_r, r) # 合并
return pow(2, m, 1_000_000_007)
0727
3106. 满足距离约束且字典序最小的字符串
"""
贪心策略
重点:
26-ord(res[i])+ord('a') >k-cnt不是>=
"""
class Solution:
def getSmallestString(self, s: str, k: int) -> str:
n=len(s)
res=list(s)
cnt=0
for i in range(n):
if cnt==k:
return ''.join(res)
if ord(res[i])-ord('a')>13:
if 26-ord(res[i])+ord('a') >k-cnt:
res[i]=chr(ord(res[i])-(k-cnt))
cnt=k
else:
cnt+=26-ord(res[i])+ord('a')
res[i]='a'
else:
if ord(res[i])-ord('a') >k-cnt:
res[i]=chr(ord(res[i])-(k-cnt))
cnt=k
else:
cnt+=ord(res[i])-ord('a')
res[i]='a'
return ''.join(res)
0728
2779. 数组的最大美丽值
# 和2580相近,本质上都是在找存在部分重叠的区间的最大数
class Solution:
def maximumBeauty(self, nums: List[int], k: int) -> int:
nums.sort()
ans = left = 0
for right, x in enumerate(nums):
while x - nums[left] > k * 2:
left += 1
ans = max(ans, right - left + 1)
return ans
//Java
class Solution {
public int maximumBeauty(int[] nums, int k) {
Arrays.sort(nums);
int res=0;
int left=0;
for(int i=0;i<nums.length;i++){
while (nums[i]-nums[left]>2*k){
left+=1;
}
res=Math.max(res,i-left+1);
}
return res;
}
}
0729
682. 棒球比赛
class Solution:
def calPoints(self, operations: List[str]) -> int:
record=[]
def is_number(s):
try: # 如果能运行float(s)语句,返回True(字符串s是浮点数)
float(s)
return True
except ValueError: # ValueError为Python的一种标准异常,表示"传入无效的参数"
pass # 如果引发了ValueError这种异常,不做任何事情(pass:不做任何事情,一般用做占位语句)
try:
import unicodedata # 处理ASCii码的包
unicodedata.numeric(s) # 把一个表示数字的字符串转换为浮点数返回的函数
return True
except (TypeError, ValueError):
pass
return False
for op in operations:
if is_number(op):
record.append(int(op))
if op=="C":
record.pop()
if op=="D":
record.append(2*record[-1])
if op=="+":
record.append(record[-1]+record[-2])
return sum(record)
//Java
class Solution {
public int calPoints(String[] operations) {
List<Integer> st = new ArrayList<>();
for (String op : operations) {
switch (op.charAt(0)) {
case '+':
st.add(st.get(st.size() - 2) + st.get(st.size() - 1));
break;
case 'D':
st.add(st.get(st.size() - 1) * 2);
break;
case 'C':
st.remove(st.size() - 1);
break;
default:
st.add(Integer.parseInt(op));
}
}
int sum = 0;
for (int x : st) {
sum += x;
}
return sum;
}
}
0730
2961. 双模幂运算
//注意这里的重点在于每次计算后都要取模不然会超出限制
class Solution:
def getGoodIndices(self, variables: List[List[int]], target: int) -> List[int]:
ans = []
for i, v in enumerate(variables):
if pow(pow(v[0], v[1], 10), v[2], v[3]) == target:
ans.append(i)
return ans
322. 零钱兑换
# 超出内存限制
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
if amount==0:
return 0
queue=deque([[amount,0]])
res=10**4
while queue:
t,l=queue.popleft()
for c in coins:
if t-c==0:
res=min(res,l+1)
if t<c:
continue
if t>c:
queue.append([t-c,l+1])
if res==10**4:
return -1
else:
return res
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
@cache
def dfs(i,c):
if i<0:
return 0 if c==0 else inf
if c<coins[i]:
return dfs(i-1,c)
return min(dfs(i-1,c),dfs(i,c-coins[i])+1)
res=dfs(len(coins)-1,amount)
return res if res<inf else -1
2129. 将标题首字母大写
class Solution:
def capitalizeTitle(self, title: str) -> str:
word=title.split(' ')
n=len(word)
for i in range(n):
if len(word[i])<=2:
w=word[i]
word[i]=w.lower()
else:
w0=word[i][0]
w=word[i][1:]
word[i]= w0.upper()+w.lower()
return " ".join(word)
18. 零钱兑换 II
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
@cache
def dfs(i,c):
if i<0:
return 1 if c==0 else 0
if c<coins[i]:
return dfs(i-1,c)
return dfs(i,c-coins[i])+dfs(i - 1, c)
res=dfs(len(coins)-1,amount)
return res
2864. 最大二进制奇数
class Solution:
def maximumOddBinaryNumber(self, s: str) -> str:
cnt = Counter(s)
res = ['1'] * (cnt['1'] - 1)
res.extend(['0'] * cnt['0'])
res.append('1')
return "".join(res)
2549. 统计桌面上的不同数字
class Solution:
def distinctIntegers(self, n: int) -> int:
nums = [0] * (n + 1)
nums[n] = 1
for _ in range(0, n):
for x in range(1, n + 1):
if nums[x] == 0:
continue
for i in range(1, n + 1):
if x % i == 1:
nums[i] = 1
return sum(nums)
0802
3128. 直角三角形
class Solution:
def numberOfRightTriangles(self, grid: List[List[int]]) -> int:
n, m = len(grid), len(grid[0])
col = [0] * m
for j in range(m):
for i in range(n):
col[j] += grid[i][j]
res = 0
for i in range(n):
row = sum(grid[i])
for j in range(m):
if grid[i][j] == 1:
res += (row - 1) * (col[j] - 1)
return res
LCP 40. 心算挑战
class Solution:
def maxmiumScore(self, cards: List[int], cnt: int) -> int:
cards.sort()
n=len(cards)
res=0
res+=sum(cards[n-cnt+1:n])
if res%2==0:
Flag=True
else:
Flag=False
for i in range(n-cnt,-1,-1):
if Flag and cards[i]%2==0:
res+=cards[i]
return res
if not Flag and cards[i]%2!=0:
res+=cards[i]
return res
return 0
0803
3143. 正方形中的最多点数
class Solution:
def maxPointsInsideSquare(self, points: List[List[int]], s: str) -> int:
min1 = [inf] * 26
min2 = inf
n = len(s)
for i in range(n):
x, y = points[i]
j = ord(s[i]) - ord('a')
d = max(abs(x), abs(y))
if d < min1[j]:
min2 = min(min2, min1[j])
min1[j] = d
elif d < min2:
min2 = d
return sum(d < min2 for d in min1)
0814
3152. 特殊数组 II
class Solution:
def isArraySpecial(self, nums: List[int], queries: List[List[int]]) -> List[bool]:
n = len(nums)
dp = [1] * n
for i in range(1, n):
if (nums[i] ^ nums[i - 1]) & 1 == 1:
dp[i] = dp[i - 1] + 1
return [dp[y] >= y - x + 1 for x, y in queries]
3132. 找出与数组相加的整数 II
# 官方题解
class Solution:
def minimumAddedInteger(self, nums1: List[int], nums2: List[int]) -> int:
nums1.sort()
nums2.sort()
# 枚举保留 nums1[2] 或者 nums1[1] 或者 nums1[0]
# 倒着枚举是因为 nums1[i] 越大答案越小,第一个满足的就是答案
for i in range(2, 0, -1):
x = nums2[0] - nums1[i]
# 在 {nums1[i] + x} 中找子序列 nums2
j = 0
for v in nums1[i:]:
if nums2[j] == v + x:
j += 1
# nums2 是 {nums1[i] + x} 的子序列
if j == len(nums2):
return x
# 题目保证答案一定存在
return nums2[0] - nums1[0]
0817
3137. K 周期字符串需要的最少操作次数
class Solution:
def minimumOperationsToMakeKPeriodic(self, word: str, k: int) -> int:
n = len(word)
count = Counter(word[i: i + k] for i in range(0, n, k))
return n // k - max(count.values())
0818
551. 学生出勤记录 I
class Solution:
def checkRecord(self, s: str) -> bool:
n=len(s)
cnt_A=0
cnt_L=0
for i in range(n):
if s[i]=="P":
cnt_L=0
continue
elif s[i]=="A":
cnt_A+=1
if cnt_A==2:
return False
cnt_L=0
else:
cnt_L+=1
if cnt_L==3:
return False
return True