tim*_*ket 5 java string lexicographic-ordering
我正在尝试解决 Java 中字符串操作的编码问题。问题是
给定两个由数字和小写字母组成的字符串 S 和 T,您只能从任一字符串中删除一位数字,计算有多少种删除方式可以使 S 按字典顺序小于 T。
我自己想出了这个测试用例。如果 s = '3ab' 且 t = 'cd',则返回 1。如果 s = '123ab' 且 t = '423cd',则返回 6。
我的想法是使用 2 个 for 循环并通过检查字符是否为数字来遍历每个字符串,将其删除并与其他字符串进行比较。
private static int numSmaller(String s, String t){
int ways = 0;
for(int i = 0; i < s.length(); i++){
StringBuilder sbs = new StringBuilder(s);
if(Character.isDigit(s.charAt(i))){
sbs.deleteCharAt(i);
String sub = sbs.toString();
if(sub.compareTo(t) < 0) {
ways++;
}
}
}
for(int i = 0; i < t.length(); i++){
StringBuilder sbt = new StringBuilder(t);
if(Character.isDigit(t.charAt(i))){
sbt.deleteCharAt(i);
String sub = sbt.toString();
if(s.compareTo(sub) < 0){
ways++;
}
}
}
return ways;
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,空间复杂度非常糟糕,而且代码也显得多余。有没有办法优化这段代码?有没有人找到一种不使用字符串生成器或每次创建新字符串的方法?任何意见表示赞赏!
我使用streams
长度为 10 的随机字符串将其与您的方法进行了比较。我运行了1 million
这些字符串的测试用例,这两种方法提供了相同的结果。
流部分相当简单。我使用索引来根据数字位置IntStream
构建字符串。substrings
然后,我根据传递的BiFunction
lambda 进行过滤,该 lambda 充当两个参数谓词。对此进行筛选,我计算出成功的次数。
我这样做了两次,颠倒了参数和谓词逻辑,并对两个计数求和。
long count = count(s1, t1, (a, b) -> a.compareTo(b) < 0);
count += count(t1, s1, (a, b) -> b.compareTo(a) < 0);
public static long count(String s, String t, BiFunction<String, String, Boolean> comp) {
return IntStream.range(0, s.length()).filter(
i -> Character.isDigit(s.charAt(i))).mapToObj(
i -> s.substring(0, i) + s.substring(i + 1)).filter(
ss -> comp.apply(ss, t)).count();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12253 次 |
最近记录: |