查找-01-查找兄弟单词

1. 题目描述

定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。

兄弟单词要求和原来的单词不同。例如: ab 和 ba 是兄弟单词。 ab 和 ab 则不是兄弟单词。
现在给定你 n 个单词,另外再给你一个单词 x ,让你寻找 x 的兄弟单词里,按字典序排列后的第 k 个单词是什么?

注意:字典中可能有重复单词。

数据范围: 1 ≤ n ≤ 1000 1≤n≤1000 1n1000 ,输入的字符串长度满足 1 ≤ l e n ( s t r ) ≤ 10 , 1 ≤ k < n 1≤len(str)≤10 , 1≤k<n 1len(str)101k<n

输入描述: 输入只有一行。 先输入字典中单词的个数n,再输入n个单词作为字典单词。 然后输入一个单词x 最后后输入一个整数k。

输出描述: 第一行输出查找到x的兄弟单词的个数m 第二行输出查找到的按照字典顺序排序后的第k个兄弟单词,没有符合第k个的话则不用输出。

示例1:

输入:3 abc bca cab abc 1

输出:2
           \space\space\space\space\space\space\space\space\space\space           bca

示例2:

输入:6 cab ad abcd cba abc bca abc 1

输出:3
           \space\space\space\space\space\space\space\space\space\space           bca

说明:
abc的兄弟单词有cab cba bca,所以输出3
经字典序排列后,变为bca cab cba,所以第1个字典序兄弟单词为bca

2. 思路

  • 暴力遍历法:逐个判断两个单词之间长度相等、总的ASCII码相等、去重后字母的总数相等。
  • 优化后:根据题意,兄弟单词指的是:不删减、不修改的情况下,只通过调换字母顺序就可以转换。那么判断两个单词是否是兄弟单词,只需要判断两者重新排序后是否相等即可(注意排序后还要还原原先的值,不要存排序后的单词;或者存一个副本进行排序)。

注意:

  1. 在 Java 中,使用迭代器遍历集合时,不能直接修改集合的结构,否则就会抛出异常ConcurrentModificationException
  2. 注意toString()的使用,与String.valueOf()的不同之处。
  3. char[]是基本类型,默认使用的是Object类的equals方法,比较的是对象的地址值。如果要比较两个数组的内容,可以使用方法Arrays.equals(a,b)

3. 代码

代码1:

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);

    // 存储所有数据
    List<String> allDataList = new ArrayList<>();
    
    while (in.hasNext()) {
        allDataList.add(in.next());
    }
    
    Integer n = Integer.valueOf(allDataList.get(0));
    int k = Integer.parseInt(allDataList.get(allDataList.size() - 1));
    String x = allDataList.get(allDataList.size() - 2);

    List<String> verifyWordList = new ArrayList<>();

    List<String> waitVerifyWordsList = allDataList.subList(1, n + 1);
    for (String word : waitVerifyWordsList) {
        List<Character> wordList = str2CharList(word);
        int wordInt = getAscii(word);
        int xInt = getAscii(x);
        List<Character> xList = str2CharList(x);

        if (!word.equals(x) && word.length() == x.length() && xList.containsAll(wordList)
        && wordInt == xInt && wordList.stream().distinct().count() ==
                xList.stream().distinct().count()) {
            verifyWordList.add(word);
        }
    }


    verifyWordList = verifyWordList.stream().distinct().collect(Collectors.toList());

    Collections.sort(verifyWordList);

    if (k > verifyWordList.size()){
        System.out.println();
    }
    System.out.println(verifyWordList.size());
    System.out.println(verifyWordList.get(k - 1));
}

private static List<Character> str2CharList(String s){
    List<Character> targetList = new ArrayList<>();

    for (char c : s.toCharArray()) {
        targetList.add(c);
    }

    return targetList;
}


private static int getAscii(String s){
    int res = 0;

    for (char c : s.toCharArray()) {
        res += c;
    }

    return res;
}

代码2(优化后):

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);

    String s = in.nextLine();
    String[] split = s.split(" ");

    int n = Integer.parseInt(split[0]);
    String x = split[split.length - 2];
    int k = Integer.parseInt(split[split.length - 1]);

    ArrayList<String> result = new ArrayList<>();
    for (int i = 1; i <= n; i++) {
        if (split[i].equals(x) || split[i].length() != x.length()){
            continue;
        }

        if (isBrotherWord(split[i],x)){
            result.add(split[i]);
        }
    }

    Collections.sort(result);
    System.out.println(result.size());
    if (k <= result.size()){
        System.out.println(result.get(k-1));
    }

}

public static boolean isBrotherWord(String a, String b){
    char[] aList = a.toCharArray();
    char[] bList = b.toCharArray();
    Arrays.sort(aList);
    Arrays.sort(bList);
    if (Arrays.equals(aList,bList)){
        return true;
    }else {
        return false;
    }
}

以上为个人学习分享,如有问题,欢迎指出:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值