我有一个大小为N的字符串(小写字母),基于1的索引
现在我给了Q查询,每个查询由两个整数x,y组成。
对于每个查询,我必须从子串(x,y)(包括x,y)打印最小删除数,使得子串具有相同频率的不同字符。
例如:考虑一个形成子串abbccd的查询,
现在最少没有。它的缺失是2(1b,1c)。
1 <= N,Q <= 10 ^ 5
1·; = X&LT; = Y&LT; = N
我尝试了蛮力方法,对于每个查询,我计算字符的频率,然后通过将所有频率等于最小频率来计算删除。
但我知道这种做法是错误的,也会导致TLE。任何人都可以帮助我。
我的代码:
import java.util.Arrays;
import java.util.Scanner;
public class q1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int q = in.nextInt();
in.nextLine();
String s = in.nextLine();
int x,y;
while(q>0){
x = in.nextInt();
y = in.nextInt();
String temp = s.substring(x-1, y);
char c[] = temp.toCharArray();
int count[] = new int[26];
//calculating the frequencies.
for (int i = 0; i < c.length; i++) {
count[c[i]-'a']++;
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < count.length; i++) {
if(count[i]!=0 && count[i]<min){
min = count[i];
}
}
int deletions = 0;
for (int i = 0; i < count.length; i++) {
if(count[i]!=0){
deletions += (count[i]-min);
}
}
System.out.println(deletions);
q--;
}
}
}
答案 0 :(得分:0)
这是我的解决方案,每个查询的步骤为 O(26*26)。 制作了一个累积频率数组来存储每个字符的频率,直到字符串中的“第 i 个”位置。
dp[i][0]
是字符串中从索引 1 到 i 包含“a”的频率。
dp[i][1]
是“b”在字符串中从索引 1 到 i 包含的频率。
依此类推,直到 25 为“z”。
现在在每个查询中,我们可以计算子串 x 到 y 中每个字符的频率,通过从相同字符的频率中减去字符“i” up-til “x-1”的频率-直到“y”即
freq[i] = dp[x-1][i] - dp[y][i];
现在一旦我们获得了子字符串中每个字符的频率,我们就可以迭代这些频率并计算每个唯一字符的删除次数。
例如,如果我们有一个子字符串“ddddbbacc”
"a" 的频率为 1
“b”的频率为 2
"c" 的频率为 2
"d" 的频率是 4
frequencies = [1, 2, 2, 4]
在第一次迭代时,我们尝试使所有频率都等于 freq[0]
,即 1.
为此,我们从具有 freq = 2
的字符中删除一个字符,并从具有 freq = 4
的字符中删除 3 个字符。
这给了我们1+1+3 = 5
的答案。
在第二次迭代中,我们尝试使所有频率等于 freq[1]
,即 2.
为此,我们从具有 freq = 4
的字符中删除 3 个字符。
我们还删除了所有 freq < 2
这给了我们1+2 = 3
的答案。
在最坏的情况下,每个查询需要 26*26
步。
发现问题
here
import java.util.Arrays;
import java.util.Scanner;
import java.util.Collections;
import java.util.ArrayList;
class q1 {
static int[][] dp = new int[100005][27];
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int q = in.nextInt();
in.nextLine();
String s = in.nextLine();
for (int i = 0; i < s.length(); i++){ //O(N*26)
for (int j = 0; j < 26; j++)
dp[i+1][j] = dp[i][j];
dp[i+1][(int)(s.charAt(i))-(int)('a')]++;
}
int x,y;
while(q>0){ //O(Q*700)
x = in.nextInt();
y = in.nextInt();
int freq[] = new int[27];
for(int i = 0; i < 26; i++) //O(1)
freq[i] = dp[y][i] - dp[x-1][i];
ArrayList<Integer> f = new ArrayList<Integer>();
for(int i = 0; i < 26; i++) //O(1)
if(freq[i] != 0)
f.add(freq[i]);
Collections.sort(f); //O(26*log26)
int ans = s.length() + 1;
int drop = 0;
for(int i = 0; i < f.size(); i++){ //O(26*26)
int currans = drop;
for(int j = i+1; j < f.size(); j++)
currans += (f.get(j)-f.get(i));
if (ans > currans)
ans = currans;
drop += f.get(i);
}
if (drop < ans)
ans = drop;
System.out.println(ans);
q--;
}
}
}