第一题:
分析:该题非常简单,拼接起来检查即可,不做分析
class Solution {
public boolean arrayStringsAreEqual(String[] word1, String[] word2) {
String str1 ="";
for(String str:word1){
str1 += str;
}
String str2 ="";
for(String str:word2){
str2 += str;
}
StringBuilder s1 = new StringBuilder(str1);
StringBuilder s2 = new StringBuilder(str2);
int length1 = s1.length();
int length2 = s2.length();
if(length1 != length2){
return false;
}
int i = 0 ;
boolean falg = true;
while(i < length1){
if(s1.charAt(i) != s2.charAt(i)){
return false;
}
i++;
}
return true;
}
}
第二题:
5606. 具有给定数值的最小字符串
小写字符 的 数值 是它在字母表中的位置(从 1 开始),因此 a 的数值为 1 ,b 的数值为 2 ,c 的数值为 3 ,以此类推。
字符串由若干小写字符组成,字符串的数值 为各字符的数值之和。例如,字符串 “abe” 的数值等于 1 + 2 + 5 = 8 。
给你两个整数 n 和 k 。返回 长度 等于 n 且 数值 等于 k 的 字典序最小 的字符串。
注意,如果字符串 x 在字典排序中位于 y 之前,就认为 x 字典序比 y 小,有以下两种情况:
x 是 y 的一个前缀;
如果 i 是 x[i] != y[i] 的第一个位置,且 x[i] 在字母表中的位置比 y[i] 靠前。
示例 1:
输入:n = 3, k = 27
输出:“aay”
解释:字符串的数值为 1 + 1 + 25 = 27,它是数值满足要求且长度等于 3 字典序最小的字符串。
示例 2:
输入:n = 5, k = 73
输出:“aaszz”
提示:
1 <= n <= 105
n <= k <= 26 * n
分析:看数据范围,10的五次方,因此最多只能用nlogn的复杂度进行解答。
在做该题时,有点思路,本来想用递归做,后来发现,深搜每次都要搜索26个字符,好像不太行。
该题的正解思路是贪心做法,在满足条件的情况下,每次尽量选择小的字符,那么这里的满足的条件是什么条件呢? 具体的分析出该条件是解答本题的关键。我们先来明确一个问题,如果有m位代填字符,那么m位最多填的字符和是多少呢,显而易见位 m1~m26,如果需要和大于这个 或者小于这个的话,那么就无法找到一个合适的字符串满足条件,而题目中给的n <= k <= 26 * n,因此我们知道题目是一定有解的。
所以经过我们上面的分析,我们可知对于每个位置,我们都可以从a-z进行枚举,如果填入a剩下的m位的和满足上面分析的条件,就可以填入a,否则依次向后寻找合适的字符即可。
好了,说了这么多,直接贴代码
注意:这里的ans如果用String存储,超时,因为要频繁用到拼接,所以能用StringBuilder就尽量使用StringBuilder
class Solution {
public String getSmallestString(int n, int k) {
//还剩m位代填的字符,那么他的能填的数的和为 m <= sum <= 26*m
StringBuilder ans = new StringBuilder();
//s表示前面已经填的和
int s = 0;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= 26;j++){
//分别尝试a-z 依次尝试 如果剩下的和是合理的 那么就添加该字符
s = s+j;
char ch = (char)('a' +j-1);
if(k-s >= (n-i) && k-s <= 26*(n-i)){
ans.append(ch);
break;
}
//到这里说明添加的这个字符不行,但是之前已经加入到s中,需要减掉
s = s-j;
}
}
return ans.toString();
}
}
第三题:
- 生成平衡数组的方案数
给你一个整数数组 nums 。你需要选择 恰好 一个下标(下标从 0 开始)并删除对应的元素。请注意剩下元素的下标可能会因为删除操作而发生改变。
比方说,如果 nums = [6,1,7,4,1] ,那么:
选择删除下标 1 ,剩下的数组为 nums = [6,7,4,1] 。
选择删除下标 2 ,剩下的数组为 nums = [6,1,4,1] 。
选择删除下标 4 ,剩下的数组为 nums = [6,1,7,4] 。
如果一个数组满足奇数下标元素的和与偶数下标元素的和相等,该数组就是一个 平衡数组 。
请你返回删除操作后,剩下的数组 nums 是 平衡数组 的 方案数 。
示例 1:
输入:nums = [2,1,6,4]
输出:1
解释:
删除下标 0 :[1,6,4] -> 偶数元素下标为:1 + 4 = 5 。奇数元素下标为:6 。不平衡。
删除下标 1 :[2,6,4] -> 偶数元素下标为:2 + 4 = 6 。奇数元素下标为:6 。平衡。
删除下标 2 :[2,1,4] -> 偶数元素下标为:2 + 4 = 6 。奇数元素下标为:1 。不平衡。
删除下标 3 :[2,1,6] -> 偶数元素下标为:2 + 6 = 8 。奇数元素下标为:1 。不平衡。
只有一种让剩余数组成为平衡数组的方案。
示例 2:
输入:nums = [1,1,1]
输出:3
解释:你可以删除任意元素,剩余数组都是平衡数组。
示例 3:
输入:nums = [1,2,3]
输出:0
解释:不管删除哪个元素,剩下数组都不是平衡数组。
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 104
分析:该题思路其实较为简单,但是其数据量位10^5,因此用O(n2)的时间复杂度会超时,本来我的写法是 判断一个数组是不是平衡数组的操作复杂度位O(n),同时又需要依次删除n中的每个元素,又需要O(n)的复杂度,这样就是平方的复杂度,会超时。
因此我们需要想办法进行优化,这里分析依次删除n中的每个元素是没法进行优化的,因此我们需要对判断一个数组是不是平衡数组的方法进行优化,在这里我们可以前缀和的方法进行优化,可以将其降为常数的时间复杂度。
我们分别建立一个奇数和偶数的前缀和数组。