Anagrams


Given an array of strings, return all groups of strings that are anagrams.

Note: All inputs will be in lower-case.

Have you been asked this question in an interview? 
开始没读懂题目意思,别人解释:

Given an array of strings, return all groups of strings that are anagrams.

Note: All inputs will be in lower-case.

For example:

Input:  ["tea","and","ate","eat","den"]

Output:   ["tea","ate","eat"]

Interface: vector<string>anagrams(vector<string>&strs);

A:

首先简单介绍一下Anagram(回文构词法)。Anagrams是指由颠倒字母顺序组成的单词,比如“dormitory”颠倒字母顺序会变成“dirty room”,“tea”会变成“eat”。

回文构词法有一个特点:单词里的字母的种类和数目没有改变,只是改变了字母的排列顺序。


看了别人这些方法 无论怎么做,都是为了构建hashmap 的key 

假设有n个string,string 最长长度为k

如果用按照字母排序,时间复杂度o(nklogk)

另外两种方法,o(nk)

这道题目除了思路,还要注意对于iterator, collection, map 等 他们的相关方法使用

public class Solution {
    public List<String> anagrams(String[] strs) {
        if (strs == null) {
            return null;
        }
        List<String> result = new ArrayList<String>();
        HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();
        for (int i = 0; i < strs.length; i++) {
            if(!hm.containsKey(sortLetter(strs[i]))) {
                hm.put(sortLetter(strs[i]), new ArrayList<String>());
            }
            hm.get(sortLetter(strs[i])).add(strs[i]);
        }
        // hm.values() 返回的是 a collection of the values in this map
        // 对于collection 结构的数据,都有iterator() 方法
        Iterator iter = hm.values().iterator();
        while(iter.hasNext()) {
            ArrayList<String> item = (ArrayList<String>)iter.next();  
            if(item.size()>1) { 
                result.addAll(item);  
            }
        }
        /* hm.values() 返回的是实现了collection 的一种数据类型叫 Values, 不可以被转化为arraylist
        ArrayList<ArrayList<String>> aa = (ArrayList<ArrayList<String>>)hm.values();
        for (int i = 0; i < aa.size(); i++) {
            if (aa.get(i).size() > 1) {
                result.addAll(aa.get(i));
            }
        }
        */
        return result;
    }
    String sortLetter(String s) {
        //不要忘记考虑空字符串
        if (s == null || s.length() == 0) {
            return s;
        }
        char[] charArr = s.toCharArray();
        Arrays.sort(charArr);
        String str = new String(charArr);//用到String 的构造函数
        return str;
    }

}


网上看到另外一人解法 http://huntfor.iteye.com/blog/2077967:

public List<String> anagrams(String[] strs) {  
        List<String> result = new ArrayList<String>();   
        Map<String,List<String>> map = new HashMap<String,List<String>>();  
        if(strs == null || strs.length == 1){  
            return result;  
        }  
        for(String s : strs){  
            String seq = getSequence(s);  
            if(map.containsKey(seq)){  
                map.get(seq).add(s);  
            }else{  
                List<String> list = new ArrayList<String>();  
                list.add(s);  
                map.put(seq, list);  
            }  
        }  
        for(Map.Entry<String, List<String>> entry : map.entrySet()){  
            if(entry.getValue().size() > 1){  
                for(String s : entry.getValue()){  
                    result.add(s);  
                }  
            }  
        }  
        return result;  
    }     
    private String getSequence(String s){  
        if("".equals(s)){  
            return "";  
        }  
        int[] hash = new int[256];  
        StringBuilder sb = new StringBuilder();  
        for(int i = 0; i < s.length(); i++){  
            hash[s.charAt(i)]++;  
        }  
        for(int i = 97; i < 123; i++){  
            if(hash[i] != 0){  
                sb.append((char)i).append(hash[i]);  
            }  
        }  
        return sb.toString();  
    }  

第二次写出错的地方:

while (iter.hasNext()) {
            ArrayList<String> items = (ArrayList<String>)iter.next();
            //cannot addAll(iter.next()) directely
            //res.addAll(iter.next());
            //test case:[""], the output should be [ ]
            if (items.size() > 1) {
                res.addAll(items);
            }
        }



/**
 * Copyright: NineChapter
 * - Algorithm Course, Mock Interview, Interview Questions
 * - More details on: http://www.ninechapter.com/
 */

public class Solution {
    private int getHash(int[] count) {
        int hash = 0;
        int a = 378551;
        int b = 63689;
        for (int num : count) {
            hash = hash * a + num;
            a = a * b;
        }
        return hash;
    }
    
    public ArrayList<String> anagrams(String[] strs) {
        ArrayList<String> result = new ArrayList<String>();
        HashMap<Integer, ArrayList<String>> map = new HashMap<Integer, ArrayList<String>>();

        for (String str : strs) {
            int[] count = new int[26];
            for (int i = 0; i < str.length(); i++) {
                count[str.charAt(i) - 'a']++;
            }

            int hash = getHash(count);
            if (!map.containsKey(hash)) {
                map.put(hash, new ArrayList<String>());
            }

            map.get(hash).add(str);
        }

        for (ArrayList<String> tmp : map.values()) {
            if (tmp.size() > 1) {
                result.addAll(tmp);
            }
        }

        return result;
    }
}


方法挺简单就是建立一个int数组来记录一个字符在一个string里面出现的次数 然后对比int[]数组是否相等就好。 不过这里有几个注意点和小技巧。 int数组可以只设为26而不是256, 然后数组这样的Object类型没法直接用来做key首先要写一个函数把它的hash值转换为基本数据类型。 然后就是要存arraylist作为value,因为如果直接把string用来做value最后会少加一次anagrams进rs。用arraylist存只要size大于1 就可以addall.


public class Solution {
    public List<String> anagrams(String[] strs) {
        List<String> rs = new ArrayList<String>();
        if (strs.length < 2) {
            return rs;
        }
        HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();
        for (String i : strs) {
            int len = i.length();
            int[] temp = new int[26];
            for (int j = 0; j < len; j++) {
                temp[i.charAt(j) - 'a']++;
            }
            String t = getString(temp);
            if (!hm.containsKey(t)) {
                hm.put(t, new ArrayList<String>());
            }
            hm.get(t).add(i);
        }
        for (ArrayList<String> i : hm.values()) {
            if (i.size() > 1) {
                rs.addAll(i);
            }
        }
        return rs;
    }
    
    private String getString(int[] a) {
        StringBuilder sb = new StringBuilder();
        for (int i : a) {
            sb.append(i);
        }
        return sb.toString();
    }
}



基于NSGA-III算法求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文围绕基于NSGA-III算法的微电网多目标优化调度展开研究,重点介绍了如何利用该先进多目标进化算法解决微电网系统中多个相互冲突的目标(如运行成本最小化、碳排放最低、供电可靠性最高等)的协同优化问题。文中结合Matlab代码实现,详细阐述了NSGA-III算法的基本原理、在微电网调度模型中的建模过程、约束条件处理、目标函数设计以及仿真结果分析,展示了其相较于传统优化方法在求解高维、非线性、多目标问题上的优越性。同时,文档还提供了丰富的相关研究案例和技术支持背景,涵盖电力系统优化、智能算法应用及Matlab仿真等多个方面。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事能源优化领域的工程技术人员;尤其适合正在进行微电网调度、多目标优化算法研究或撰写相关论文的研究者。; 使用场景及目标:①掌握NSGA-III算法的核心思想及其在复杂能源系统优化中的应用方式;②学习如何构建微电网多目标调度模型并利用Matlab进行仿真求解;③为科研项目、毕业论文或实际工程提供算法实现参考和技术支撑。; 阅读建议:建议读者结合文中提供的Matlab代码实例,逐步调试运行并深入理解算法流程与模型构建细节,同时可参考文档中列出的其他优化案例进行横向对比学习,以提升综合应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值