题意整理。

  • 输入一个字符串数组以及一个待查找的单词。
  • 求该单词的所有兄弟单词中的第k个。
  • 定义一个单词的“兄弟单词”为:交换该单词字母顺序,而不添加、删除、修改原有的字母就能生成的单词。

方法一(计数+排序)

1.解题思路

  • 首先定义一个方法,用于检查是否是兄弟单词。该方法需要定义一个计数数组,字符串s1中对应字符出现次数加1,字符串s2中对应字符出现次数减1,然后遍历整个计数数组,如果某个位置的值不为0,说明不是兄弟单词。
  • 根据定义的检查方法,遍历输入的字符串数组,将所有的兄弟单词加入到一个list容器。list容器的大小即是兄弟单词的个数。
  • 最后对list容器进行排序,输出索引位置k对应的值即是第k个兄弟单词。

图解展示: alt

2.代码实现

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;

public class Main{
    public static void main(String[] args){
        //标准输入
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            //单词的个数n
            int n=sc.nextInt();
            //存储输入的n个单词
            String[] arr=new String[n];
            for(int i=0;i<n;i++){
                arr[i]=sc.next();
            }
            //待查找的单词x
            String s=sc.next();
            //数字k
            int k=sc.nextInt();
            //新建list,用于存储兄弟单词
            ArrayList<String> list=new ArrayList<>();
            for(int i=0;i<arr.length;i++){
                if(!arr[i].equals(s)){
                    if(match(arr[i],s)){
                        list.add(arr[i]);
                    }                   
                }
            }
            //对兄弟单词进行排序
            Collections.sort(list);
            //打印兄弟单词个数
            System.out.println(list.size());
            if(list.size()>=k){
                //打印第k个兄弟单词
                System.out.println(list.get(k-1));
            }
            
        }
        
    }
    //检查是否是兄弟单词
    public static boolean match(String s1,String s2){
        //计数数组
        int[] count=new int[26];
        for(int i=0;i<s1.length();i++){
            //s1字符在对应位置计数加1
            count[s1.charAt(i)-'a']++;
        }
        for(int i=0;i<s2.length();i++){
            //s2字符在对应位置计数减1
            count[s2.charAt(i)-'a']--;
        }
        for(int i=0;i<26;i++){
            //如果不为0,说明两字符串中有某个字符出现次数不相等,不是兄弟单词
            if(count[i]!=0){
                return false;
            }
        }
        return true;
    }
}

3.复杂度分析

  • 时间复杂度:输入的字符串长度为常数级别,所以检查方法的时间复杂度为O(1)O(1),需要遍历整个字符串数组,假设数组长度为n,遍历的时间复杂度为O(n)O(n)。最坏情况下,兄弟单词的个数为n,对其进行排序的时间复杂度为O(nlog2n)O(n*log_2n),所以时间复杂度为O(nlog2n)O(n*log_2n)
  • 空间复杂度:最坏情况下,需要额外大小为n的list容器,所以空间复杂度为O(n)O(n)

方法二(利用io流)

1.解题思路

思路和方法一基本一致,不同的是通过io流操作来处理输入的数据。

2.代码实现

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;

public class Main{
    public static void main(String[] args) throws Exception{
        //io输入
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s;
        while((s=br.readLine())!=null){
            String[] str=s.split(" ");
            //单词的个数n
            int n=Integer.parseInt(str[0]);
            //存储输入的n个单词
            String[] arr=new String[n];
            for(int i=0;i<n;i++){
                arr[i]=str[i+1];
            }
            //待查找的单词x
            String x=str[n+1];
            //数字k
            int k=Integer.parseInt(str[n+2]);
            //新建list,用于存储兄弟单词
            ArrayList<String> list=new ArrayList<>();
            for(int i=0;i<arr.length;i++){
                if(!arr[i].equals(x)){
                    if(match(arr[i],x)){
                        list.add(arr[i]);
                    }                   
                }
            }
            //对兄弟单词进行排序
            Collections.sort(list);
            //打印兄弟单词个数
            System.out.println(list.size());
            if(list.size()>=k){
                //打印第k个兄弟单词
                System.out.println(list.get(k-1));
            }
            
        }
        
    }
    //检查是否是兄弟单词
    public static boolean match(String s1,String s2){
        //计数数组
        int[] count=new int[26];
        for(int i=0;i<s1.length();i++){
            //s1字符在对应位置计数加1
            count[s1.charAt(i)-'a']++;
        }
        for(int i=0;i<s2.length();i++){
            //s2字符在对应位置计数减1
            count[s2.charAt(i)-'a']--;
        }
        for(int i=0;i<26;i++){
            //如果不为0,说明两字符串中有某个字符出现次数不相等,不是兄弟单词
            if(count[i]!=0){
                return false;
            }
        }
        return true;
    }
}

3.复杂度分析

  • 时间复杂度:输入的字符串长度为常数级别,所以检查方法的时间复杂度为O(1)O(1),需要遍历整个字符串数组,假设数组长度为n,遍历的时间复杂度为O(n)O(n)。最坏情况下,兄弟单词的个数为n,对其进行排序的时间复杂度为O(nlog2n)O(n*log_2n),所以时间复杂度为O(nlog2n)O(n*log_2n)
  • 空间复杂度:最坏情况下,需要额外大小为n的list容器,所以空间复杂度为O(n)O(n)