Java8流删除重复字母

ecfsfe2w  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(200)

我想把我对流的知识应用到一些leetcode算法的问题上。以下是问题的概要:
给定一个只包含小写字母的字符串,请删除重复的字母,以便每个字母只出现一次。你必须确保你的结果是所有可能结果中最小的。
例子:

Input: "bcabc"
Output: "abc"

另一个例子:

Input: "cbacdcbc"
Output: "acdb"

这似乎是一个简单的问题,只需将值从字符串流到一个新的列表中,对值进行排序,找到不同的值,然后将其扔回到列表中,并将列表的值附加到字符串中。下面是我想到的:

public String removeDuplicateLetters(String s)
{
    char[] c = s.toCharArray();
    List<Character> list = new ArrayList<>();
    for(char ch : c) 
    {
        list.add(ch);
    }

    List<Character> newVal = list.stream().distinct().collect(Collectors.toList()); 
    String newStr = "";
    for(char ch : newVal) 
    {
        newStr += ch;
    }

    return newStr;
}

第一个例子工作得很好,但是第二个输出不是“acdb”,而是“d”。为什么d不是最不符合词典编纂顺序的呢?谢谢!

dsekswqp

dsekswqp1#

public static void main(String[] args) {
    String string = "cbacdcbc";
    string.chars()
            .mapToObj(item -> (char) item)
            .collect(Collectors.toSet()).forEach(System.out::print);

}

输出:d,希望对您有所帮助!

zujrkrfu

zujrkrfu2#

正如我在评论中指出的,使用 LinkedHashSet 在这里最好不过了 Stream 我们的做法是你可以这样做:

public static String removeDuplicateLetters(String s) {
    return s.chars().sorted().distinct().collect(
        StringBuilder::new,
        StringBuilder::appendCodePoint,
        StringBuilder::append
    ).toString();
}

注: distinct() 紧随其后 sorted() 为了优化流程,请参阅评论中的霍尔格解释以及此答案。
这里有很多不同的东西,所以我会给它们编号:
您可以流式处理 String 使用 String#chars() 而不是 List 添加所有字符。
为了确保得到的字符串按字母顺序最小,我们可以对 IntStream .
我们可以把 IntStream 回到a String 通过使用 StringBuilder . 然后我们把这个 StringBuilder 我们想要的字符串。
可变缩减是 Stream 类似于这样做的方式:

for (char ch : newVal) {
    newStr += ch;
}

但是,使用 StringBuilder 用于连接而不是 String . 看看这个答案,为什么这更有效。
关于预期产出与观察产出之间的冲突,你的实际问题是:我相信 d 是第二个输出的正确答案,因为它是按字母顺序排列的最小的。

相关问题