1. 程式人生 > >LeetCode:49. Group Anagrams(相同字元子串問題)

LeetCode:49. Group Anagrams(相同字元子串問題)

Given an array of strings, group anagrams together.

Example:

Input: ["eat", "tea", "tan", "ate", "nat", "bat"],Output:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]
Note:
  • All inputs will be in lowercase.
  • The order of your output does not matter.

方法1:(普通的暴力演算法(brute force))

package leetcode;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author zhangyu
 * @version V1.0
 * @ClassName: GroupAnagrams
 * @Description: TOTO
 * @date 2018/12/14 16:56
 **/

/**
 * 基本思路是迴圈遍歷每個元素,如果已經加入到list當中,那麼就把該元素標記為“1”,下次看到“1”直接跳過
 */
public class GroupAnagrams {
    @Test
    public void fun() {
        String[] strs = {"eat", "tea", "tan", "ate", "nat", "bat"};
        List<List<String>> list = groupAnagrams(strs);
        System.out.println(list);
        System.out.println(Arrays.toString(strs));
    }

    private List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> newList = new ArrayList<>();
        for (int i = 0; i < strs.length; i++) {
            if (strs[i].equals("1"))
                continue;
            List<String> subList = new ArrayList<>();
            if (i < strs.length - 1) {
                subList.add(strs[i]);
                strs[i] = 1 + "";
            } else {
                if (!"1".equals(strs[i])) {
                    subList.add(strs[i]);
                    strs[i] = 1 + "";
                    newList.add(subList);
                    continue;
                }
            }
            for (int j = i + 1; j < strs.length; j++) {
                String test1 = sortString(strs[j]);
                if (sortString(strs[i]).equals(test1)) {
                    subList.add(strs[j]);
                    strs[j] = 1 + "";
                }
            }
            newList.add(subList);
        }
        return newList;
    }

    public String sortString(String s) {
        char chs[] = s.toCharArray();
        Arrays.sort(chs);
        return new String(chs);
    }
}

時間複雜度:O(n^2)

空間複雜度:O(n)


方法2:(利用hashmap的方式)

package leetcode;

import org.junit.Test;

import java.util.*;

/**
 * @author zhangyu
 * @version V1.0
 * @ClassName: GroupAnagrams
 * @Description: TOTO
 * @date 2018/12/14 16:56
 **/

/**
 * 利用字元數的轉換
 */
public class GroupAnagrams3 {
    @Test
    public void fun() {
        String[] strs = {"eat", "tea", "tan", "ate", "nat", "bat"};
        List<List<String>> list = groupAnagrams(strs);
        System.out.println(list);
    }

    private List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for (String str : strs) {
            char[] chs = str.toCharArray();
            Arrays.sort(chs);
            String newStr = new String(chs);
            if (!map.containsKey(newStr)) {
                map.put(newStr, new ArrayList<String>());
            }
            map.get(newStr).add(str);
        }
        return new ArrayList(map.values());
    }
}

時間複雜度:O(n)

空間複雜度:O(n)


方法3:(效率最高 ,最難想到的一種方法)

package leetcode;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * @author zhangyu
 * @version V1.0
 * @ClassName: GroupAnagrams
 * @Description: TOTO
 * @date 2018/12/14 16:56
 **/

/**
 * 利用字元數的轉換
 */
public class GroupAnagrams2 {
    @Test
    public void fun() {
        String[] strs = {"eat", "tea", "tan", "ate", "nat", "bat"};
        List<List<String>> list = groupAnagrams(strs);
        System.out.println(list);
    }

    private List<List<String>> groupAnagrams(String[] strs) {
        int[] prime = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103};//最多10609個z
        System.out.println(prime.length);
        List<List<String>> res = new ArrayList<>();
        HashMap<Integer, Integer> map = new HashMap<>();
        for (String s : strs) {
            int key = 1;
            for (char c : s.toCharArray()) {
                key *= prime[c - 'a'];
            }
            List<String> t;
            if (map.containsKey(key)) {
                t = res.get(map.get(key));
            } else {
                t = new ArrayList<>();
                res.add(t);
                map.put(key, res.size() - 1);
            }
            t.add(s);
        }
        return res;
    }
}

時間複雜度:O(n^2)

空間複雜度:O(n)