3083. 字符串及其反转中是否存在同一子字符串
难度:731
给你一个字符串
s
,请你判断字符串s
是否存在一个长度为2
的子字符串,在其反转后的字符串中也出现。如果存在这样的子字符串,返回
true
;如果不存在,返回false
。示例 1:
输入:s = "leetcode"
输出:true
解释:子字符串
"ee"
的长度为2
,它也出现在reverse(s) == "edocteel"
中。示例 2:
输入:s = "abcba"
输出:true
解释:所有长度为
2
的子字符串"ab"
、"bc"
、"cb"
、"ba"
也都出现在reverse(s) == "abcba"
中。示例 3:
输入:s = "abcd"
输出:false
解释:字符串
s
中不存在满足「在其反转后的字符串中也出现」且长度为2
的子字符串。提示:
1 <= s.length <= 100
- 字符串
s
仅由小写英文字母组成。
状态:完成,但是方法不好,看了灵山的代码确实可以
思路:构建一个26*26的二维数组arr,arr[i][j]表示下标‘ij’是否在原来的s中出现过。这样子遍历一遍数组就可以得出字符串中是否存在相邻可以倒置的两个字符串。
class Solution {
public boolean isSubstringPresent(String s) {
char[] arr=s.toCharArray();
boolean[][] list=new boolean[26][26];
if(arr.length==1) return false;
for(int i=0;i<arr.length-1;i++){
char a=arr[i];
char b=arr[i+1];
list[a-'a'][b-'a']=true;
if(list[b-'a'][a-'a']){
return true;
}
}
return false;
}
}
3084. 统计以给定字符开头和结尾的子字符串总数
难度:1210
给你一个字符串
s
和一个字符c
。返回在字符串s
中并且以c
字符开头和结尾的非空子字符串
的总数。示例 1:
输入:s = "abada", c = "a"
输出:6
解释:以
"a"
开头和结尾的子字符串有:"abada"
、"abada"
、"abada"
、"abada"
、"abada"
、"abada"
。示例 2:
输入:s = "zzz", c = "z"
输出:6
解释:字符串
s
中总共有6
个子字符串,并且它们都以"z"
开头和结尾。提示:
1 <= s.length <= 105
s
和c
均由小写英文字母组成。
状态:完成
思路:数学问题,关键是找到字符串中有多少个字符c,算出c的阶乘。
class Solution {
public long countSubstrings(String s, char c) {
ArrayList<Character> list = new ArrayList();
for(int i=0;i<s.length();i++){
if(c==s.charAt(i)) list.add(s.charAt(i));
}
if(list.size()==0) return 0;
long sum=0;
for(int i=list.size();i>0;i--){
sum+=i;
}
return sum;
}
}
3085. 成为 K 特殊字符串需要删除的最少字符数
难度:1773
给你一个字符串
word
和一个整数k
。如果
|freq(word[i]) - freq(word[j])| <= k
对于字符串中所有下标i
和j
都成立,则认为word
是 k 特殊字符串。此处,
freq(x)
表示字符x
在word
中的出现频率
,而|y|
表示y
的绝对值。返回使
word
成为 k 特殊字符串 需要删除的字符的最小数量。示例 1:
输入:word = "aabcaba", k = 0
输出:3
解释:可以删除
2
个"a"
和1
个"c"
使word
成为0
特殊字符串。word
变为"baba"
,此时freq('a') == freq('b') == 2
。示例 2:
输入:word = "dabdcbdcdcd", k = 2
输出:2
解释:可以删除
1
个"a"
和1
个"d"
使word
成为2
特殊字符串。word
变为"bdcbdcdcd"
,此时freq('b') == 2
,freq('c') == 3
,freq('d') == 4
。示例 3:
输入:word = "aaabaaa", k = 2
输出:1
解释:可以删除 1 个
"b"
使word
成为2
特殊字符串。因此,word
变为"aaaaaa"
,此时每个字母的频率都是6
。提示:
1 <= word.length <= 105
0 <= k <= 105
word
仅由小写英文字母组成。
状态:做不出来
思路:题目要求的是任意的下标之间两个字符出现的频率之差的绝对值是要小于k,那我们可以换个思路,把任意的字符作为出现频率最小的字符,然后把他之前的所有字符都去掉因为他是最小的,然后在把出现频率最高的字符都离这个最小的字符出现次数-k的次数加上去,然后不断对比各个最小的值需要移动的次数,找到最小的。
class Solution {
public int minimumDeletions(String word, int k) {
int[] arr =new int[26];
for(int i=0;i<word.length();i++){
arr[word.charAt(i)-'a']++;
}
Arrays.sort(arr);
int min=Integer.MAX_VALUE;
for(int i=0;i<26;i++){
int temp=0;
if(arr[i]==0) continue;
//arr[i]作为最小出现次数的字母
for(int j=i-1;j>=0;j--){
if(arr[j]==0) break;
temp+=arr[j];
}
for(int o=i+1;o<26;o++){
temp+=Math.max(arr[o]-arr[i]-k,0);
}
min=Math.min(temp,min);
}
return min;
}
}
感想:最后一题还没涉及,以后再考虑。