LeetCode Hot 100题 笔记 哈希

30 阅读3分钟

题目:1、两数之和

如果不要求返回索引可以使用排序 + 双指针的方法找到两个元素

但是本题要求返回索引,就不能排序了,因为排序完之后索引会发生变化

参照题解,可以使用HashMap解决

具体思路为:构造一个Map<Integer,Integer>,key是数组值,value是数组索引

在将数组元素加入到map的同时检查是否存在target - 当前元素的key

如果存在则说明存在一个和当前元素相加等于target的元素,就是我们要找的另一个数

所以可以直接将当前索引和目标元素索引构造成数组并返回,AC

public int[] twoSum(int[] nums, int target) {
      Map<Integer,Integer> map = new HashMap<>();
      for (int i = 0; i < nums.length; i++) {
         if(map.containsKey(target - nums[i])){
            return new int[]{map.get(target - nums[i]),i};
         }
         map.put(nums[i],i);
      }
      return new int[]{0};
    }

题目:49、字母异位词分组

首先明确题目中字母异位词的概念:

以测试用例为例:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]

输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

这里的第二组 ["nat","tan"] 都是由n,a,t这三个字母组成

同理 ["ate","eat","tea"] 也都是由a,t,e这三个字母组成

所以可以得出字母异位词就是具备相同的字母,但是字母排列顺序不一样的字符串

解法一:

我们可以把字符串转化为char数组,然后将char数组进行排序

由上面得出的概念可知,所有的字母异位词在经过排序后,得到的字符串都是相同的

这样就我们可以使用一个Map<String,List>的结构,以排序后的字符串作为key,记录下该字符串组成的所有字母异位词

public List<List<String>> groupAnagrams(String[] strs) {
      Map<String,List<String>> map = new HashMap<>();
      for (String str : strs) {
         char[] s = str.toCharArray();
         Arrays.sort(s);
         //如果存在该字母序列,则将当前字符串添加到列表中
         String key = new String(s);
         if (map.containsKey(key)){
            List<String> strList = map.get(key);
            strList.add(str);
         }
         else{
            List<String> strList = new ArrayList<>();
            strList.add(str);
            map.put(key,strList);
         }
      }

      return new ArrayList(map.values());
    }

题目:128、最长连续序列

本题思路参考labuladong题解

本题的关键在于如何找连续序列,这个问题又可以转化为如何找连续序列的开头元素

当找不出比当前元素小1的元素时,就说明当前元素是一个连续序列的开头元素

问题又转变成了如何找到数组中的元素,我们可以借助Java中的HashSet来进行快速查找

所以问题可解

解法一:

public int longestConsecutive(int[] nums) {
      //转换成HashSet,方便查找元素是否存在
      HashSet<Integer> set = new HashSet<>();
      for (int num : nums) {
         set.add(num);
      }

      int res = 0;

      //开始找连续序列
      for(int num : set){
         //先找连续序列的开头元素
         //当找不出比当前元素还小1的元素时,就说明这个元素是连续序列的开头元素
         if(set.contains(num - 1)){
            continue;
         }

         //走到这里说明当前的num是连续序列的第一个元素
         int curNum = num;
         int len = 1;

         //如果存在比当前元素大1的元素,则加长当前连续序列的长度
         while (set.contains(curNum + 1)){
            curNum ++;
            len ++;
         }

         //走出循环则代表已经找完了连续序列,此时的len就是当前连续序列的长度
         res = Math.max(res,len);
      }

      return res;
    }