第153场双周赛
还没想好以什么形式记录周赛的题目,暂时每场周赛一个文件吧。
记录做题过程中的思考的问题。
Q1. 字符串的反转度
给你一个字符串s,计算其反转度。
反转度的计算方法如下:
1.对每个字符,将其在反转字母表中的位置('a'=26, 'b'=25...'z'=1),与其字符串中的位置(下标从1开始)相乘。
2.将这些乘积加起来,就得到了字符串中所有字符的和。
返回反转度。
就是用反转字母表中字符的位置 * 字符的位置之和。
在解题的时候,想不到如何维护字母表,就用map来维护了,但是后更好的方式,就是 26 - (s.charAt(i)-'a')
就是字符在字母表中的位置。
class Solution {
public int reverseDegree(String s) {
// 主要是维护字母表
int res = 0;
for (int i = 0; i < s.length(); i++) {
int reverse = 26 - (s.charAt(i) - 'a');
res += reverse * (i + 1);
}
return res;
}
}©leetcode
class Solution {
public int reverseDegree(String s) {
// 主要是维护字母表
int ans = 0;
for (int i = 0; i < s.length(); i++) {
int cnt = (('z' - s.charAt(i)) + 1) * (i + 1);
ans += cnt;
}
return ans;
}
}
遇到的问题:
1、a z的ascll码是多少?
- a 97, z 122, A 65, Z 90
2、java中如何将ascll与字符进行转换?
// 将数字转成字符 int num = 97; char x = (char) num; // sout -> x = a // 将字符转成数字 int s = x; // sout -> s = 97
3、java中将的api
- s.toCharArray(), s.charAt(idx)
Q2. 操作后最大活跃区段数 I
给你一个长度为 n
的二进制字符串 s
,其中:
'1'
表示一个 活跃 区段。'0'
表示一个 非活跃 区段。
你可以执行 最多一次操作 来最大化 s
中的活跃区段数量。在一次操作中,你可以:
- 将一个被
'0'
包围的连续'1'
区块转换为全'0'
。 - 然后,将一个被
'1'
包围的连续'0'
区块转换为全'1'
。
返回在执行最优操作后,s
中的 最大 活跃区段数。
**注意:**处理时需要在 s
的两侧加上 '1'
,即 t = '1' + s + '1'
。这些加上的 '1'
不会影响最终的计数。
class Solution:
def maxActiveSectionsAfterTrade(self, s: str) -> int:
ans = mx = cnt = 0
pre0 = -inf
for i, b in enumerate(s):
cnt += 1
if i == len(s) - 1 or b != s[i + 1]:
if b == "1":
ans += cnt
else:
mx = max(mx, pre0 + cnt)
pre0 = cnt
cnt = 0
return ans + mx
Q4. 操作后最大活跃区段数 II
给你一个长度为 n
的二进制字符串 s
,其中:
'1'
表示一个 活跃 区域。'0'
表示一个 非活跃 区域。
你最多可以进行一次 操作 来最大化 s
中活跃区间的数量。在一次操作中,你可以:
- 将一个被
'0'
包围的连续'1'
区域转换为全'0'
。 - 然后,将一个被
'1'
包围的连续'0'
区域转换为全'1'
。
此外,你还有一个 二维数组 queries
,其中 queries[i] = [li, ri]
表示子字符串 s[li...ri]
。
对于每个查询,确定在对子字符串 s[li...ri]
进行最优交换后,字符串 s
中 可能的最大 活跃区间数。
返回一个数组 answer
,其中 answer[i]
是 queries[i]
的结果。
注意
- 对于每个查询,仅对
s[li...ri]
处理时,将其看作是在两端都加上一个'1'
后的字符串,形成t = '1' + s[li...ri] + '1'
。这些额外的'1'
不会对最终的活跃区间数有贡献。 - 各个查询相互独立。