目录
第一题 移除指定数字得到的最大结果
自己做题的问题简单记录: 用时26分AC
简单题,一开始我的思路错了不知道为什么要把字符串转成int比较
由于移除一位数字之后字符串长度相同,所以可以直接用string比较
由于CompareTo()这个函数不熟悉导致一次WA
compareTo() 的返回值是int, 它是先比较对应字符的大小(ASCII码顺序)
1、如果字符串相等返回值0
2、如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值(ascii码值)
(负值前字符串的值小于后字符串,正值前字符串大于后字符串)
3、如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,
直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.
思路
暴力枚举,枚举可能的所有情况,遇见较大的情况更新结果字符串。
时间复杂度O(n)
代码
优化修改后的代码如下:
class Solution {
public String removeDigit(String number, char digit) {
int n = number.length();
String res = "";
for(int i=0;i<n;i++){
char c = number.charAt(i);
String t ="";
if(c == digit){
t = number.substring(0,i)+number.substring(i+1);
}
if(t.compareTo(res)>0){ //t>res
res = t;
}
}
return res;
}
}
第二题 必须拿起的最小连续卡牌数
自己做题的问题简单记录: 用时10分AC
思路
本题题目可以转换为找两个最近的相同数字,答案即为这两个数字的距离。
所以可以用一个hashMap维护数字->idx,遍历一遍即可。
时间复杂度O(n),空间O(n)
代码
class Solution {
public int minimumCardPickup(int[] cards) {
int res = Integer.MAX_VALUE;
Map<Integer,Integer> map = new HashMap<>();
for(int i=0;i<cards.length;i++){
if(map.containsKey(cards[i])){
int idx = map.get(cards[i]);
res = Math.min(res,i-idx+1);
}
map.put(cards[i],i);
}
return res==Integer.MAX_VALUE?-1:res;
}
}
第三题 含最多 K 个可整除元素的子数组
自己做题的问题简单记录: 用时32分 WA一次后AC
一开始一直在想子数组有没有什么不枚举的方法,好像思路跑偏了。
然后考虑如何去重,想到了把子数组拼成字符串用set去重,中间WA一次因为拼接需要加一个分符不然会出现问题,如{1,9}和{19}会生成相同的字符串最终导致错误。
思路
暴力枚举所有的子数组(考虑到题目的数据范围可以暴力),然后判断是否符合条件,拼接放入set去重,最后返回set的大小。
时间复杂度O(n^3) //toString()时间复杂度可能是O(n) 一个不确定的地方(
代码
class Solution {
public int countDistinct(int[] nums, int k, int p) {
Set<String> st = new HashSet<>();
int n = nums.length;
for(int i=0;i<n;i++){
int count = 0;
StringBuilder sb = new StringBuilder();
for(int j=i;j<n;j++){
if(nums[j]%p==0){
count++;
}
if(count>k){
break;
}
sb.append(nums[j]).append('&');
st.add(sb.toString());
}
}
return st.size();
}
}
第四题 字符串的总引力
自己做题的问题简单记录:
看下数据范围显然这题暴力做会超时,想一下dp没有想出来,感觉这思路真的不是太能想到,学习一下学习一下。
思路
参考理解思路
对于一些以s[i]结尾的字符串,计算这些字符串的总引力值 =
SUM(分别计算26个字母对于这些字符串引力值的贡献)
如何计算每个字母c对以s[i]结尾的字符串的贡献,就是记录每个字母c出现的idx
每个字母c对以s[i]结尾的字符串的贡献 = 以s[i]结尾的字符串且包含c的字符串个数 =字母c出现的idx + 1
如
例如 字符串abca
0 a
1 b
2 c
当i=2时,考虑字母b对以s[2]结尾的所有字符串的贡献,即考虑以s[i]结尾的字符串且包含b的字符串个数 枚举出符合条件的字符串为:abc、bc 观察可知符合条件的字符串数量为idx(b)+1=1+1=2
3 a
代码1
class Solution {
public long appealSum(String s) {
int[] index = new int[26]; //26个字母出现的idx
long sum = 0;
for(int i=0;i<s.length();i++){ //枚举以s[i]结尾的字符串集合
index[s.charAt(i)-'a'] = i+1;
for(int j=0;j<26;j++){
sum += index[j];//枚举26个字母
}
}
return sum;
}
}
代码2
将所有子串按照其末尾字符的下标分类。
考虑两类相邻的子串:以 s[i-1]结尾的子串、以 s[i]结尾的子串,以 s[i]结尾的子串,可以看成是以s[i−1] 结尾的子串,在末尾添加上 s[i] 组成。添加后,这些子串的引力值会增加多少?
分类讨论:
1、如果 s[i]之前没有遇到过,那么每个子串的引力值都会增加 1,引力值之和会增加 i+1;
2、如果 s[i]之前遇到过,设其上次出现的下标为 j,那么向子串 s[0..i-1]、s[1..i-1]、s[2..i-1],⋯,s[j..i−1] 的末尾添加 s[i] 后,引力值是不会变化的,因为 s[i]已经在s[j] 处出现过了;而子串 s[j+1..i−1], s[j+2..i−1],⋯,s[i−1..i−1] 由于不包含字符 s[i],这些子串的引力值都会增加 1,因此有 i-j-1 个子串的引力值会增加 1,引力值之和会增加 i−j。 【(i+1)-(j+1)】
作者:endlesscheng
链接:https://leetcode-cn.com/problems/total-appeal-of-a-string/solution/by-endlesscheng-g405/
来源:力扣(LeetCode)
class Solution {
public long appealSum(String s) {
int[] index = new int[26]; //26个字母出现的idx
long sum = 0;
long total = 0;
for(int i=0;i<s.length();i++){ //枚举以s[i]结尾的字符串集合
total += i+1-index[s.charAt(i)-'a'];
index[s.charAt(i)-'a'] = i+1;
sum += total;
}
return sum;
}
}