力扣hot100—哈希 3题

两数之和

常规方法,遍历两次,复杂度是0n²的,无法接受。用哈希表, Map<Integer, Integer> hash = new HashMap<>(),HashMap可以做到O(1)复杂度查数字。

// 常规方法 遍历两次
class Solution {
    public int[] twoSum(int[] nums, int target) {
        for(int i = 0; i < nums.length; i++){
            for(int j = 0; j < nums.length; j++){
                if(i == j) continue;
                if(nums[i] + nums[j] == target){
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}

注意,先检查后存入​​:确保不会匹配到自己。

// 哈希表解法
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> hash = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            int needed = target - nums[i];
            if(hash.get(needed) != null && hash.get(needed) != i){
                return new int[]{hash.get(needed), i};
            }
            hash.put(nums[i], i);  // 先检查 再放入hash 确保不会匹配到自己
        }
        return new int[0];
    }
}

字母异位词分组

用字符串排序+哈希,字符串排序要转换成字符数组。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> list = new ArrayList<>();
        HashMap<String, List<String>> hash = new HashMap<>();  // key为sort后的字符串 value为异位词的list
        // 直观思路 字符串排序对比
        for(int i = 0; i < strs.length; ++i){
            String temp = strs[i];
            char[] s = temp.toCharArray();
            Arrays.sort(s); // 转化成char才能sort
            String stemp = new String(s); // 转化回String

            if(hash.containsKey(stemp) == false){ // 为空 创建
                List<String> keyString = new ArrayList<>();
                keyString.add(temp);
                hash.put(stemp, keyString);
            }else{
                List<String> keyString = hash.get(stemp);
                keyString.add(temp);
                hash.put(stemp, keyString);
            }
        }
        // 最后把hash中所有的元素取出来放到list里
        for(List<String> value : hash.values()){
            list.add(value);
        }
        return list;
    }
}

最长连续序列

用HashSet,所有的数装入set,然后一个个遍历,如果当前数n,set中存在n-1就continue,否则就循环判断是否存在n+1,n+2…

版本1,超时,10个用例没过:

//  版本1 有10个用例超时 最坏情况下会On²
class Solution {
    public int longestConsecutive(int[] nums) {
        if(nums.length == 0) return 0;
        HashSet<Integer> set = new HashSet<>();
        int res = 0;
        for(int i = 0; i < nums.length; i++){
            set.add(nums[i]);
        }
        for(int i = 0; i < nums.length; i++){
            int cnt = 1;
            int temp = nums[i];
            while(set.contains(temp + 1)){
                cnt++;
                temp++;
            }
            res = Math.max(res, cnt);
        }
        return res;
    }
}

上述代码对每个数字都尝试向后查找连续序列,有很多重复查找。需要剪掉一些无用的计算,加一句if (!set.contains(num - 1)) ,保证序列从最小值开始技术。

版本2, 还是有4个用例没过,需要再优化。

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

版本3,不遍历nums数组而是遍历哈希集合(已去重),这样可以避免重复元素遍历!

class Solution {
    public int longestConsecutive(int[] nums) {
        if(nums.length == 0) return 0;
        HashSet<Integer> set = new HashSet<>();
        int res = 0;
        for(int i = 0; i < nums.length; i++){
            set.add(nums[i]);
        }
        for(int v : set){ //遍历哈希集合而非数组!
            if(set.contains(v - 1)){
                continue;
            }
            int temp = v;
            int cnt = 1;
            while(set.contains(temp + 1)){
                cnt++;
                temp++;
            }
            res = Math.max(cnt, res);
        }
        return res;
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇