给出字符串s
和m
查询。对于每个查询,请删除K
次出现的字符x
。
例如:
abcdbcaab
5
2 a
1 c
1 d
3 b
2 a
Ans abbc
我正在使用BIT树进行更新操作。
代码:
for (int i = 0; i < ss.length(); i++) {
char cc = ss.charAt(i);
freq[cc-97] += 1;
if (max < freq[cc-97]) max = freq[cc-97];
dp[cc-97][freq[cc-97]] = i; // Counting the Frequency
}
BIT = new int[27][ss.length()+1];
int[] ans = new int[ss.length()];
int q = in.nextInt();
for (int i = 0; i < q; i++) {
int rmv = in.nextInt();
char c = in.next().charAt(0);
int rr = rmv + value(rmv, BIT[c-97]); // Calculating the original Index Value
ans[dp[c-97][rr]] = Integer.MAX_VALUE;
update(rmv, 1, BIT[c-97], max); // Updating it
}
for (int i = 0; i < ss.length(); i++) {
if (ans[i] != Integer.MAX_VALUE) System.out.print(ss.charAt(i));
}
时间复杂度为O(M log N)
,其中N
是字符串ss
的长度。
我的解决方案为我提供了超出时间限制错误。我该如何改进呢?
public static void update(int i , int value , int[] arr , int xx){
while(i <= xx){
arr[i ]+= value;
i += (i&-i);
}
}
public static int value(int i , int[] arr){
int ans = 0;
while(i > 0){
ans += arr[i];
i -= (i &- i);
}
return ans ;
}
答案 0 :(得分:3)
有些关键操作没有显示,其中一个(很可能是update
方法)的成本与你想象的不同。此外,您声明的复杂性肯定是错误的,因为在某些时候您必须扫描至少为O(N)
的字符串。
但无论如何,这里明显正确的策略是通过查询,按字符分隔它们,然后以相反的顺序查询查询要确定要抑制的字符的初始位置。然后运行一次字符串,仅在适合时发出字符。如果实施得当,此解决方案应该在O(N + M log(M))
中可行。
挑战在于如何有效地表示删除。我正在考虑某种相对偏移的树,这样如果你发现第一个删除是3 a
,你可以有效地将它插入你的树中,然后在那之后移动每一个删除。这是log(M)
位的位置。