zoukankan      html  css  js  c++  java
  • 一道面试题

      给定一个字符串的集合,格式如:{aaabbbccc},{bbbddd},{eeefff},{ggg},{dddhhh}要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例应输出{aaabbbcccdddhhh},{eeefff},{ggg}。
      (1)请描述你解决这个问题的思路;
      (2)请给出主要的处理流程,算法,以及算法的复杂度
      (3)请描述可能的改进。
    回答:
      集合使用hash_set来表示,这样合并时间复杂度比较低。
      1、给每个集合编号为0,1,2,3...
      2、创建一个hash_map,key为字符串,value为一个链表,链表节点为字符串所在集合的编号。遍历所有的集合,将字符串和对应的集合编号插入到hash_map中去。
      3、创建一个长度等于集合个数的int数组,表示集合间的合并关系。例如,下标为5的元素值为3,表示将下标为5的集合合并到下标为3的集合中去。开始时将所有值都初始化为-1,表示集合间没有互相合并。在集合合并的过程中,我们将所有的字符串都合并到编号较小的集合中去。
       遍历第二步中生成的hash_map,对于每个value中的链表,首先找到最小的集合编号(有些集合已经被合并过,需要顺着合并关系数组找到合并后的集合编号),然后将链表中所有编号的集合都合并到编号最小的集合中(通过更改合并关系数组)。
      4、现在合并关系数组中值为-1的集合即为最终的集合,它的元素来源于所有直接或间接指向它的集合。
      算法的复杂度为O(n),其中n为所有集合中的元素个数。

      1 package test;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.File;
      5 import java.io.FileNotFoundException;
      6 import java.io.FileReader;
      7 import java.io.IOException;
      8 import java.util.HashSet;
      9 import java.util.Iterator;
     10 import java.util.TreeMap;
     11 import java.util.Vector;
     12 
     13 public class StringSet {
     14 public static int findRoot(int [] arr,int index){
     15 while(arr[index]>=0){
     16 index=arr[index];
     17 }
     18 return index;
     19 }
     20 public static HashSet<String> mergeSet(HashSet<String> hashSet1,HashSet<String> hashSet2){
     21 Iterator<String> iterator=hashSet2.iterator();
     22 while(iterator.hasNext()){
     23 String string=iterator.next();
     24 if(!hashSet1.contains(string)){
     25 hashSet1.add(string);
     26 }
     27 }
     28 return hashSet1;
     29 }
     30 public static void printSet(HashSet<String> hashSet){
     31 Iterator<String> iterator=hashSet.iterator();
     32 System.out.print("[ ");
     33 while(iterator.hasNext()){
     34 String  string=iterator.next();
     35 System.out.print(string+" ,");
     36 }
     37 System.out.println(" ]");
     38 }
     39 public static void main(String[] args) throws FileNotFoundException {
     40 TreeMap<Integer, HashSet<String>> hashMap=new TreeMap<Integer, HashSet<String>>();
     41 BufferedReader br=new BufferedReader(new FileReader(new File("E:\\input.txt")));
     42 HashSet<String> hashSet=null;
     43 TreeMap<String, Vector<Integer>> hm=new TreeMap<String, Vector<Integer>>();
     44 String line=null;
     45 int nindex=0;
     46 try {
     47 while((line=br.readLine())!=null){
     48 String[] str=line.split(" ");
     49 hashSet=new HashSet<String>();
     50 for(int i=0;i<str.length;i++){
     51 System.out.print(str[i]+" ");
     52 if(!hm.containsKey(str[i])){
     53 Vector<Integer> v=new Vector<Integer>();
     54 v.add(nindex);
     55 hm.put(str[i], v);
     56 }else{
     57 hm.get(str[i]).add(nindex);
     58 }
     59 hashSet.add(str[i]);
     60 }
     61 System.out.println();
     62 hashMap.put(nindex++, hashSet);
     63 }
     64 } catch (IOException e) {
     65 e.printStackTrace();
     66 }
     67 System.out.println("合并后--------------------------------------------------");
     68 int k=nindex;
     69 int []flag=new int[k];
     70 for(int i=0;i<k;i++){
     71 flag[i]=-1;
     72 }
     73 Iterator<String> it=hm.keySet().iterator();
     74 while (it.hasNext()) {
     75 String s=it.next();
     76 Vector<Integer> vv=hm.get(s);
     77 if(vv.size()>1){
     78 int root=findRoot(flag, vv.get(0));
     79 for(int p=1;p<vv.size();p++){
     80 flag[vv.get(p)]=root;
     81 }
     82 }
     83 }
     84 int resSetNum=0;
     85 for(int j=0;j<k;j++){
     86 if(flag[j]==-1){
     87 resSetNum++;
     88 }
     89 }
     90 for(int j=0;j<k;j++){
     91 if(flag[j]!=-1){
     92 mergeSet(hashMap.get(flag[j]), hashMap.get(j));
     93 hashMap.remove(j);
     94 }
     95 }
     96 Iterator<Integer> its=hashMap.keySet().iterator();
     97 while(its.hasNext()){
     98 int key=its.next();
     99 printSet(hashMap.get(key));
    100 }
    101 }
    102 
    103 }

     

  • 相关阅读:
    实现雨滴的效果
    rainyday.js
    XHTML1.0版本你知道么,跟html5版本有什么区别
    背景图合并用在什么地方最适合,有什么优点
    什么是css hack
    用一两句话说一下你对“盒模型”这个概念的理解,和它都涉及到哪些css属性
    块属性标签和行内属性标签及样式优先级
    【Loadrunner】Loadrunner 手动关联技术
    【黑盒测试】测试用例的常用方法
    【Linux】阿里云服务器部署--禅道
  • 原文地址:https://www.cnblogs.com/waka401/p/2627338.html
Copyright © 2011-2022 走看看