Java 字符串操作|竞争编程

Java 字符串操作|竞争编程,java,string,algorithm,data-structures,time-complexity,Java,String,Algorithm,Data Structures,Time Complexity,我有一个大小为N的字符串(小写字母),索引为1。 现在我得到了Q个查询,每个查询由两个整数x,y组成。 对于每个查询,我必须打印从子字符串(x,y)(包括x,y)删除的最小数量,以便子字符串具有相同频率的不同字符 例如:考虑一个形成子字符串abbCCD的查询, 现在它的最小删除数是2(1b,1c) 1这是我的解决方案,每个查询有O(26*26)个步骤。 制作一个累积频率数组来存储每个字符的频率,直到字符串中的“第i个”位置 dp[i][0]是从索引1到i(含索引1)的字符串中“a”的频率。 dp

我有一个大小为N的字符串(小写字母),索引为1。
现在我得到了Q个查询,每个查询由两个整数x,y组成。
对于每个查询,我必须打印从子字符串(x,y)(包括x,y)删除的最小数量,以便子字符串具有相同频率的不同字符

例如:考虑一个形成子字符串abbCCD的查询,
现在它的最小删除数是2(1b,1c)

1这是我的解决方案,每个查询有O(26*26)个步骤。 制作一个累积频率数组来存储每个字符的频率,直到字符串中的“第i个”位置

dp[i][0]
是从索引1到i(含索引1)的字符串中“a”的频率。
dp[i][1]
是从索引1到i(含索引1)的字符串中“b”的频率。
以此类推,直到“z”为25

现在,在每个查询中,我们可以计算子字符串x到y中每个字符的频率,方法是从相同字符到y的频率减去字符“i”到“x-1”的频率,即

freq[i]=dp[x-1][i]-dp[y][i]

现在,一旦我们得到子字符串中每个字符的频率,我们就可以迭代这些频率,并计算每个唯一字符的删除次数

例如,如果我们有一个子字符串“ddbbacc”
“a”的频率为1
“b”的频率为2
“c”的频率为2
“d”的频率为4

频率=[1,2,2,4]

在第一次迭代中,我们尝试使所有频率等于
freq[0]
即1。
为此,我们从
freq=2的字符中删除一个字符,从
freq=4的字符中删除三个字符
这给了我们一个
1+1+3=5
的答案

在第二次迭代中,我们试图使所有频率等于
freq[1]
2.
为此,我们从具有
freq=4
的字符中删除3个字符
我们还删除了
freq<2

的所有字符 这给了我们一个
1+2=3
的答案

在最坏的情况下,每个查询需要
26*26
个步骤

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--;
    }
}

}
导入java.util.array;
导入java.util.Scanner;
导入java.util.Collections;
导入java.util.ArrayList;
q1类{
静态int[]dp=新int[100005][27];
公共静态void main(字符串[]args){
扫描仪输入=新扫描仪(系统输入);
int n=in.nextInt();
int q=in.nextInt();
in.nextLine();
字符串s=in.nextLine();
对于(inti=0;i0){//O(q*700)
x=in.nextInt();
y=in.nextInt();
int freq[]=新int[27];
for(inti=0;i<26;i++)/O(1)
频率[i]=dp[y][i]-dp[x-1][i];
ArrayList f=新的ArrayList();
for(inti=0;i<26;i++)/O(1)
如果(频率[i]!=0)
f、 添加(频率[i]);
Collections.sort(f);//O(26*log26)
int ans=s.长度()+1;
int-drop=0;
对于(inti=0;icurrans)
ans=咖喱;
下降+=f.get(i);
}
如果(下降
我的每个查询都是O(n),我们几乎有n个查询。总的来说是O(n2)。这种方法导致了TLE。这个问题似乎与Java无关。我更喜欢任何提供问题解决方案的人,都用Java提供,这样我就可以完全理解它。这就是标记。@weston我已经添加了代码。这是一个代码阻塞示例还是什么?我想看看原始拼图,如果你能链接到它?或者,如果没有,我在哪里可以获得样本数据来尝试它?
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--;
    }
}

}