【两次过】【2018唯品会】字符串组合

输入一个字符串,输出该字符串中相邻字符的所有组合。
举个例子,如果输入abc,它的组合有a、b、c、ab、bc、abc。(注意:输出的组合需要去重)(40分)

输入描述:

一个字符串

输出描述:

一行,每个组合以空格分隔,相同长度的组合需要以字典序排序,且去重。

示例1

输入

bac

输出

a b c ac ba bac

解题思路1:

类似Lintcode 17. 子集,不过需要注意这里不能先对字符串进行排序然后使用Lintcode 18. 子集 II的方法来去重,因为本题需要保证字符之间的顺序性,所以采用检查res中是否包含当前sb,若包含则return。

对于相邻字符的判断,也通过字符串函数contains,因为只有相邻字符组成的字符串才能在原串中找到结果。

import java.util.*;
 
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        List<String> res = new ArrayList<>();
         
        dfs(str, res, new StringBuilder(), 0);
        
        //先按照长度升序排序,然后再按照字典序升序排序
        Collections.sort(res, new Comparator<String>(){
            public int compare(String s1, String s2){
                if(s1.length() != s2.length())
                    return s1.length() - s2.length();
                else
                    return s1.compareTo(s2);
            } 
        });
         
        for(int i=0; i<res.size(); i++)
            System.out.print(res.get(i) + " ");
    }
     
    private static void dfs(String str, List<String> res, StringBuilder sb, int index){
        //去重
        if (res.contains(sb.toString()))
            return;
        
        //保证是相邻字符
        if (sb.length() > 0 && str.contains(sb.toString()))
            res.add(sb.toString());
         
        for(int i=index; i<str.length(); i++){
            sb.append(str.charAt(i));
            dfs(str, res, sb, i+1);
            sb.deleteCharAt(sb.length()-1);
        }
    }
}

解题思路2:

思路1对于本题太复杂了,由于有相邻的特性,所以可以直接遍历生成不同长度的子串,使用treeSet来进行排序

import java.util.*;
 
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        
        //i代表遍历的字符长度,j代表起始位置,使得生成不同的substring(j, j+1)
        for (int i = 1; i <= str.length(); i++) {
            TreeSet<String> treeSet = new TreeSet<>();
            
            for (int j = 0; j + i <= str.length(); j++)
                treeSet.add(str.substring(j, j + i));
            
            for (String s : treeSet)
                System.out.print(s + " ");
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值