Leetcode刷题 2021.02.07
Leetcode5659 删除字符串两端相同字符后的最短长度
给你一个只包含字符 ‘a’,‘b’ 和 ‘c’ 的字符串 s ,你可以执行下面这个操作(5 个步骤)任意次:
选择字符串 s 一个 非空 的前缀,这个前缀的所有字符都相同。
选择字符串 s 一个 非空 的后缀,这个后缀的所有字符都相同。
前缀和后缀在字符串中任意位置都不能有交集。
前缀和后缀包含的所有字符都要相同。
同时删除前缀和后缀。
请你返回对字符串 s 执行上面操作任意次以后(可能 0 次),能得到的 最短长度 。
今天做的题有点多,主要是跟着b站学的项目好像太多了,过两天会老家过年也没有设备能做了,所以做了一天的力扣。而且昨天晚上参加了双周赛,今天早上本来也想周赛的,结果起床没成功(lll¬ω¬)。记录几道周赛的题目吧,话说这次双周赛还是比较简单的,但是hard题还是做不出来。希望能有哪次周赛起码能把困难题做出来吧。
这道题其实就是双指针模拟,但是参加周赛次数不多,不知道原来提交不通过可能是不给错误的用例的。结果调试半天,还多提交错误了几次,起码多算了十几分钟时间。。
class Solution {
public int minimumLength(String s) {
char[] arr = s.toCharArray();
int i = 0, j = arr.length - 1;
if (arr[i] != arr[j]) return arr.length;
//就是双指针模拟
while (i < j){
if (arr[i] != arr[j]) return j - i + 1;
while (i < j && arr[i] == arr[i + 1]){
i++;
}
//特殊情况,比如"aaaa"
if (i == j) i--;
while (i < j && arr[j] == arr[j - 1]){
j--;
}
if (i == j) j++;;
i++;
j--;
}
return j - i + 1;
}
}
Leetcode5658 任意子数组和的绝对值的最大值
给你一个整数数组 nums 。一个子数组 [numsl, numsl+1, …, numsr-1, numsr] 的 和的绝对值 为 abs(numsl + numsl+1 + … + numsr-1 + numsr) 。
请你找出 nums 中 和的绝对值 最大的任意子数组(可能为空),并返回该 最大值 。
abs(x) 定义如下:
如果 x 是负整数,那么 abs(x) = -x 。
如果 x 是非负整数,那么 abs(x) = x 。
这题周赛的时候还是想了一下的,因为要求绝对值的最大值,又是连续的子数组。那么对于某一个元素来说,只要考虑之前数组的最大和最小值就行了,因为只有这两种情况会对绝对值的最大值产生影响。所以遍历的时候维护最大最小值就行了。
class Solution {
public int maxAbsoluteSum(int[] nums) {
int res = -1, n = nums.length, max = nums[0], min = nums[0];
res = Math.abs(nums[0]);
for(int i = 1; i < n; i++){
//记录以下以该元素结尾的绝对值最大值
int temp = Math.max(Math.abs(max + nums[i]), Math.abs(min + nums[i]));
//更新最大最小值,分情况讨论下
max = max >= 0 ? max + nums[i] : nums[i];
min = min >= 0 ? nums[i]: min + nums[i];
//更新全局的
res = Math.max(res, temp);
}
return res;
}
}
Leetcode5674 构造字典序最大的合并字符串
给你两个字符串 word1 和 word2 。你需要按下述方式构造一个新字符串 merge :如果 word1 或 word2 非空,选择 下面选项之一 继续操作:

如果 word1 非空,将 word1 中的第一个字符附加到 merge 的末尾,并将其从 word1 中移除。
例如,word1 = “abc” 且 merge = “dv” ,在执行此选项操作之后,word1 = “bc” ,同时 merge = “dva” 。
如果 word2 非空,将 word2 中的第一个字符附加到 merge 的末尾,并将其从 word2 中移除。
例如,word2 = “abc” 且 merge = “” ,在执行此选项操作之后,word2 = “bc” ,同时 merge = “a” 。
返回你可以构造的字典序 最大 的合并字符串 merge 。
长度相同的两个字符串 a 和 b 比较字典序大小,如果在 a 和 b 出现不同的第一个位置,a 中字符在字母表中的出现顺序位于 b 中相应字符之后,就认为字符串 a 按字典序比字符串 b 更大。例如,“abcd” 按字典序比 “abcc” 更大,因为两个字符串出现不同的第一个位置是第四个字符,而 d 在字母表中的出现顺序位于 c 之后。
这题要构造字典序最大的字符串,首先是双指针模拟。然后分情况讨论即可,因为字符串的长度不大,所以是O(n^2)的解法。
class Solution {
public String largestMerge(String word1, String word2) {
char[] arr1 = word1.toCharArray();
char[] arr2 = word2.toCharArray();
StringBuilder sb = new StringBuilder();
int i = 0, j = 0;
while (i < arr1.length || j < arr2.length){
//如果一个字符串没了,就一直添加另一个就行了
if (i >= arr1.length){
sb.append(arr2[j++]);
}else if (j >= arr2.length){
sb.append(arr1[i++]);
//如果当前某个字符比较大,就添加那个就行了
}else if (arr1[i] > arr2[j]){
sb.append(arr1[i++]);
}else if (arr2[j] > arr1[i]){
sb.append(arr2[j++]);
}else{
//如果当前字符相等,需要判断一下添加哪个字符,比如"cab", "cac",显然应该添加“cac”的c,因为其后面又字典序比较大的c
//可以写一个辅助函数帮助判断后面字符串的字典序
if (compare(word1.substring(i), word2.substring(j))){
sb.append(arr1[i++]);
}else{
sb.append(arr2[j++]);
}
}
}
return sb.toString();
}
private boolean compare(String a, String b){
return a.compareTo(b) >= 0;
}
}