两个面经问题
来源:3-6 对撞指针 Two Sum II - Input Array is Sorted
讲武德的年轻人
2023-09-26
bobo老师好。最近在复习面经的算法题目,遇到两个不确定的题目想请教您。
第一个题目:给定一个字符串word和最大操作数max_operations。可以进行最多max_operations次的如下操作:
- 从a - z中选定一个字符
- 把word中出现的该字符全部改成其上一个字符,比如把所有的d变成c,把所有的a变成z等
题目要求是:要求改变后的字符应该是字典序中最小的。举例:word="cba"
, max_operations = 2
, 则第1次操作把c变成b得到bba
, 第二次操作把b变成a得到aaa
.
限制:word的长度范围为[1, 2* 10^5]
, max_operation的范围为[1, 10^9]
这个题目不太确定。我的理解是要尽量首先使得左边的字符变得更小。但不太确定有效率的方式为何?
第二个题目:给定字符串密码password(小写字母组成)和最大操作数max_operations。 可以对password进行的操作:把password中任意字符改成另一个小写字母,且最多操作max_operations次。要求是,求得最长的substring使得其中所有字符相同,返回这个长度。比如,password = “ababc”, max_operations = 1。 password可以变成"aaabc"或者"abbbc",最大的相同字符的substring长度为3.
限制:password长度[1, 2*10^5]
, max_operations的长度限制 [0, 2*10^5]
这个题目类似像LC 424 Longest Repeating Character Replacement,用滑动窗口解决。但是我看网上讨论中,有人用滑动窗口会超时,导致有些case不能通过。以下是我的LC 424的解法,我记得当时做这个题目时,纠结于当左指针l向左滑动时(while循环中),是否更新滑动窗口中的maxFrequency,即其中最大频率的字符。后来读了一些文章分析,其实不必更新这个变量。所以我想,网上超时的滑动窗口算法是否在while中重新扫描整个窗口,导致算法超时。谢谢您的指教!
public int characterReplacement(String s, int k) {
int[] lettersMap = new int[26];
int res = 0;
int maxFrequency = 0;
int l = 0;
for (int r = 0; r < s.length(); r++) {
char c = s.charAt(r);
maxFrequency = Math.max(maxFrequency, ++lettersMap[c - 'A']);
while (l <= r && r - l + 1 - maxFrequency > k) {
char deletedChar = s.charAt(l);
lettersMap[deletedChar - 'A']--;
l++;
}
res = Math.max(res, r - l + 1);
}
return res;
}
}
1回答
-
liuyubobobo
2023-09-26
我只是粗略看了一遍问题,没有细究你的描述中可能的细节,但应该问题不大。
问题 1 是贪心,让最左边尽量小即可。只需要考虑每个字母第一次出现的位置即可。
问题 2 是二分。以每一个位置作起点,遍历从这个位置开始,子串全都是 a-z,二分长度,是否可以在 max_operation 的操作内把他们变得全部相等。预处理一个 presum 的表,可以在 O(1) 的时间里求出任何一个区间里本身字母是 x 的数量。复杂度 O(26 * nlogn) = O(nlogn)
继续加油!:)
022023-09-27
相似问题