01:哈希-启动!

两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

class Solution{
  public int[] two_sum(int[] nums,int target){
    Map<Integer,Integer> map = new HashMap<>();
    for(int i=0;i<nums.length,++i){
      diff = target - nums[i];
      if(map.containKey(diff)) {
        return new int[]{i,map.get(diff)}
      }
      map.put(nums[i],i);
    }
    return null;
  }  
}

字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

  • 方法1
    异位词按照字母顺序做排序后一定相等,所以对每一个词利用Array.sort进行排序,结果作为key,value为一个列表,存放排序后为当前key的所有词
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for (String str : strs) {
            char[] chars = str.toCharArray();
            Arrays.sort(chars);
            String sort_str = new String(chars);
            if(map.containsKey(sort_str)){
                map.get(sort_str).add(str);
            }else{
                List list = new ArrayList<>();
                list.add(str);
                map.put(sort_str,list);
            }
        }
        return new ArrayList<>(map.values());
    }
}
  • 方法2
    字母异位词的原料一定相同,所以可以利用一个类来描述该词,即利用一个数组来存储该词的每一个字母的个数。该类可以替代方法1的key。
    注意:一定要要重写equals和hashcode方法!
    此方法无需对字符串进行排序,而是遍历累加,所以时间复杂度上会更优秀。
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<Word, List<String>> map = new HashMap<>();
        for (String str : strs) {
            Word word = new Word(str);
            if(map.containsKey(word)){
                map.get(word).add(str);
            }else{
                List list = new ArrayList<>();
                list.add(str);
                map.put(word,list);
            }
        }
        return new ArrayList<>(map.values());
    }
    class Word{
        private char[] chars = new char[26];
        Word(String s){
            char[] chars1 = s.toCharArray();
            for (char c: chars1) {
                chars[c-'a']++;
            }
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Word word = (Word) o;
            return Arrays.equals(chars, word.chars);
        }

        @Override
        public int hashCode() {
            return Arrays.hashCode(chars);
        }
    }
}

最长连续序列

给定一个未排序的整数数组 nums(数据可重复)找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
方法:将所有元素都放进哈希表中,key是唯一标识即可(所以用hashset即可),value即为元素值,然后遍历该哈希表,假如当前遍历值为v,若哈希表中不存在v-1,则证明它是连续序列的开头,则从它开始循环查找是否存在v+1,v+2....,若存在则将当前的序列长度+1,否则跳出循环,继续遍历哈希表。

class Solution {
    public int longestConsecutive(int[] nums) {
        HashSet<Integer> hashset = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            hashset.add(nums[i]);
        }
        int count = 0;
        int res = 0;
        for (int v: hashset) {
            if(!hashset.contains(v-1)){
                count = 1;
                int current = v;
                while(hashset.contains(current+1)){
                    count++;
                    current++;
                }
                res = Math.max(count,res);
            }
            
        }
        return res;
    }
}

总结

哈希表主要利用空间换时间的思想
在题目中也要注意数据规模的提示

posted @   直来直往1  阅读(1)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示