process_str(StringBuilder copy, List<Integer> idxList) {
for(int i = 0; i < idxList.size(); ++i) {
int pos = idxList.get(i);
copy.setCharAt(pos, '$');
}
StringBuilder output = new StringBuilder();
for(int i = 0; i < copy.length(); ++i) {
char ch = copy.charAt(i);
if(ch != '$')
output.append(ch);
}
return output.toString();
}
约束 - $ 不出现在输入字符串中。 有没有更简单的方法来做到这一点?
您可以像这样删除第一个循环:
process_str(StringBuilder copy, List<Integer> idxList) {
StringBuilder output = new StringBuilder();
for(int i = 0; i < copy.length(); ++i) {
char ch = copy.charAt(i);
if (idxList.contains(i))
output.append(ch);
}
return output.toString();
}
总体时间复杂度可能会有所不同,具体取决于您使用的
List
类型。
解决方案与 rikyeah 类似,但避免了 contains 的复杂性。 在这里,我们首先对输入 idxList 进行排序,以使索引按升序排列,然后创建输出 StringBuilder,其初始容量根据输入 StringBuilder 的长度和要删除的索引数计算得出。最后,我们浏览输入 StringBuilder 并在到达下一个要删除的索引时避免复制。
public String process_str(StringBuilder copy, List<Integer> idxList) {
List<Integer> sortedIndices = new ArrayList<>(idxList);
Collections.sort(sortedIndices);
Iterator<Integer> idxIterator = sortedIndices.iterator();
int currIdx;
if (idxIterator.hasNext()) {
currIdx = idxIterator.next();
} else {
currIdx = copy.length();
}
StringBuilder output = new StringBuilder(copy.length() - idxList.size());
for(int i = 0; i < copy.length(); ++i) {
char ch = copy.charAt(i);
if (i != currIdx) {
output.append(ch);
} else if (idxIterator.hasNext()) {
currIdx = idxIterator.next();
}
}
return output.toString();
}
由于标题说:“删除字符的最佳方法”,所以不清楚你的意思是最有效还是最简洁。但是,在后一种情况下,您可以使用 java 流。
String str = "Hello my new world!";
List<Integer> idxList = new ArrayList<>(List.of(3, 5, 6));
StringBuilder strBld = new StringBuilder();
IntStream.range(0, str.length()).boxed().forEach(i -> {
if (!idxList.contains(i)) strBld.append(str.charAt(i));
});