1. 哈希/映射/散列表

1.1 两数之和(1)

  1. public static void main(String[][] args) {
  2. new Main().twoSum(new int[]{2, 7, 11, 15}, 9)
  3. }
  4. public int[] twoSum(int[] nums, int target) {
  5. Map<Integer, Integer> numIndexMap = new HashMap<>(nums.length + (nums.length >> 1));
  6. for (int i = 0; i < nums.length; ++i) {
  7. if (numIndexMap.containsKey(target - nums[i])) {
  8. return new int[]{numIndexMap.get(target - nums[i]), i};
  9. }
  10. numIndexMap.put(nums[i], i);
  11. }
  12. return new int[0];
  13. }

1.2 字母异位词分组(49)

  • 解法一:排序后作为key 使用map来判断重复 O(mnlogn)

    1. public List<List<String>> groupAnagrams(String[] strs) {
    2. //判断是否为空字符串数组
    3. if(strs == null || strs.length == 0){
    4. return new ArrayList<>();
    5. }
    6. //1.创建一个哈希表
    7. Map<String,List<String>> map = new HashMap<>();
    8. for (String s: strs) {
    9. //将字符串转化为字符数组
    10. char[] chars = s.toCharArray();
    11. //对字符数组按照字母顺序排序 O(k Log k)
    12. Arrays.sort(chars);
    13. //将排序后的字符串作为哈希表中的key值 O(n)
    14. String key = String.valueOf(chars);
    15. //2.判读哈希表中是否有该key值
    16. map.computeIfAbsent(key, temp -> new ArrayList<>()).add(s);
    17. }
    18. //返回map中所有键值对象构成的list
    19. return new ArrayList<>(map.values());
    20. }
  • 解法二:优化Key的获取方式:但是会浪费O(26n)的空间 时间复杂度降低到O(mn)

    1. public List<List<String>> groupAnagrams(String[] strs) {
    2. Map<String, List<String>> map = new HashMap<>();
    3. for (String str : strs) {
    4. int[] counts = new int[26];
    5. int length = str.length();
    6. for (int i = 0; i < length; i++) {
    7. counts[str.charAt(i) - 'a']++;
    8. }
    9. // 将每个出现次数大于 0 的字母和出现次数按顺序拼接成字符串,作为哈希表的键
    10. StringBuilder stringBuilder = new StringBuilder();
    11. for (int i = 0; i < 26; i++) {
    12. if (counts[i] != 0) {
    13. stringBuilder.append((char) ('a' + i));
    14. stringBuilder.append(counts[i]);
    15. }
    16. }
    17. String key = stringBuilder.toString();
    18. map.computeIfAbsent(key, temp -> new ArrayList<>()).add(key);
    19. }
    20. return new ArrayList<List<String>>(map.values());
    21. }

1.3 有效的字母异位词(242)

  • 解法一:利用两个数组统计26个字母的出现频次;比较字符串出现次数即可。 O(n)

    1. public boolean isAnagram(String s, String t) {
    2. if (s.length() != t.length()) {
    3. return false;
    4. }
    5. int[] intArr = new int[26];
    6. for (int i = 0; i < s.length(); i++) {
    7. intArr[s.charAt(i) - 'a']++;
    8. }
    9. for (int i = 0; i < t.length(); i++) {
    10. intArr[t.charAt(i) - 'a']--;
    11. if (intArr[t.charAt(i) - 'a'] < 0) {
    12. return false;
    13. }
    14. }
    15. return true;
    16. }