首页 > 其他分享 >[刷题记录Day7]Leetcode哈希表

[刷题记录Day7]Leetcode哈希表

时间:2023-08-25 22:35:11浏览次数:42  
标签:right nums int Day7 ++ length 哈希 Leetcode left

No.1

题目

四数相加 II

思路

  • 很妙的办法:有四个数组A、B、C、D,用hashMap记录【A、B中数字之和】+【这些和出现的次数】,再遍历C、D中数字组合,寻找【0-C、D中数字之和】在hashMap中出现的次数,并累加
  • 本质上,这是把4个数组简化成了2个数组

代码

public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {  
    // 记录A、B中元素之和+出现次数  
    Map<Integer, Integer> ABhash = new HashMap<>();  
    int targetCount = 0;  
  
    for (int i = 0; i < nums1.length; i++) {  
        for (int j = 0; j < nums2.length; j++) {  
            // 取出“和”+1,统计“和”出现次数  
            ABhash.put(nums1[i] + nums2[j], ABhash.getOrDefault(nums1[i] + nums2[j], 0) + 1);  
        }  
    }  
  
    for (int i = 0; i < nums3.length; i++) {  
        for (int j = 0; j < nums4.length; j++) {  
            if (ABhash.containsKey(-nums3[i] - nums4[j]))  
                targetCount += ABhash.get(-nums3[i] - nums4[j]);  
        }  
    }  
  
    return targetCount;  
}

No.2

题目

赎金信

思路

  • 用一个int[]记录magazine中字母出现次数
  • 遍历ransomNote,消耗可用字母数
  • 出现负值,就是不够用,可以返回false

代码

public boolean canConstruct(String ransomNote, String magazine) {  
    // 记录26个字母的出现次数  
    int[] alphabet = new int[26];  
  
    // 统计可用字母数量  
    for (int i = 0; i < magazine.length(); i++) {  
        char item = magazine.charAt(i);  
        alphabet[item - 'a']++;  
    }  
  
    // 消耗字母  
    for (int i = 0; i < ransomNote.length(); i++) {  
        char item = ransomNote.charAt(i);  
        // 不够用,false  
        if (--alphabet[item - 'a'] < 0)  
            return false;  
    }  
  
    return true;  
}

No.3

题目

三数之和

思路

  • 先升序排序,因为有序的数组,相同的数字一定靠在一起,这样就可以跳过重复的数字,从而去重
  • 升序排序后,第一个数字大于target,就不用找了,返回空数组
  • 升序排序后,最后一个数字小于target,就不用找了,返回空数组
  • 双指针法
  • 对数字a、b、c都要去重
  • 参看去重逻辑的思考

代码

public List<List<Integer>> threeSum(int[] nums) {  
    List<List<Integer>> result = new ArrayList<>(); // 存结果  
    Arrays.sort(nums); // 先排序  
  
    // 升序数组,最小元素大于0或者最大元素小于0,都没有必要再找了  
    if (nums[0] > 0 || nums[nums.length - 1] < 0)  
        return result;  
  
    for (int i = 0; i < nums.length - 2; i++) {  
        // 去重  
        if (i > 0 && nums[i] == nums[i - 1])  
            continue;  
        int left = i + 1, right = nums.length - 1;  
        while (left < right) {  
            int sum = nums[i] + nums[left] + nums[right];  
            if (sum < 0) {  
                left++;  
            } else if (sum > 0) {  
                right--;  
            } else {  
                result.add(new ArrayList<>(Arrays.asList(nums[i], nums[left], nums[right])));  
                // 去重  
                while (left < right && nums[left] == nums[left + 1]) left++;  
                while (left < right && nums[right] == nums[right - 1]) right--;  
  
                // 找到答案,双指针同时变化  
                left++;  
                right--;  
            }  
        }  
    }  
  
    return result;  
}

No.4

题目

四数之和

思路

  • 相比三数之和,和从0变成了target,思路还是类似
  • 去重的细节要特别注意
  • 需要仔细考虑双指针去重逻辑

代码

public List<List<Integer>> fourSum(int[] nums, int target) {  
    Arrays.sort(nums); // 排序  
    List<List<Integer>> result = new ArrayList<>(); // 存结果  
  
    // 最小的数字大于target,不能找到和为target的数  
    if (nums[0] > target)  
        return result;  
  
    for (int i = 0; i < nums.length - 3; i++) {  
        // 剪枝,访问过nums[0]之后再判重  
        if (i > 0 && nums[i] == nums[i - 1]) continue;  
        for (int j = i + 1; j < nums.length - 2; j++) {  
            // 剪枝,访问过nums[i+1]之后再判重  
            if (j > i + 1 && nums[j] == nums[j - 1]) continue;  
            int left = j + 1, right = nums.length - 1;  
  
            while (left < right) {  
                int sum = nums[i] + nums[j] + nums[left] + nums[right];  
                if (sum > target) right--;  
                else if (sum < target) left++;  
                else {  
                    result.add(new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[left], nums[right])));  
                    // 去重  
                    while (left < right && nums[left] == nums[left + 1]) left++;  
                    while (left < right && nums[right] == nums[right - 1]) right--;  
  
                    right--;  
                    left++;  
                }  
            }  
        }  
    }  
  
    return result;  
}

标签:right,nums,int,Day7,++,length,哈希,Leetcode,left
From: https://www.cnblogs.com/tomatoQt/p/17658083.html

相关文章

  • VSCode使用JavaScript刷LeetCode配置教程(亲试可以!)
    账号秘密都对,但是缺登录不成功的问题诀窍可能是:在属性设置中把LeetCode版本改成cn。点击LeetCode配置,修改Endpoint配置项,改成leetcode-cn,再次尝试登陆即可。  大家可移步原博文:https://blog.csdn.net/qq_37263248/article/details/124304402......
  • leetcode1260
    这是一道模拟题刚开始准备纯模拟,而后在题解看到一维压缩,才发现其实是将矩阵按行展开后进行k次右移操作。转换成一维后,难点就在转换坐标:行号=idx/列数;列号=idx%列数; ......
  • leetcode236求最近公共祖先
    递归TreeNode*dfs(TreeNode*root,TreeNode*p,TreeNode*q){if(!root)returnroot;//当发现这个节点已经是叶节点时,要告诉上层if(root==p||root==q)returnroot;//当发现是p节点或者q时也要告诉上层TreeNode*left=dfs(root->left,p,q);//左子树是否有p或者q......
  • Leetcode1636——按照频率将数组升序排序
    给你一个整数数组 nums ,请你将数组按照每个值的频率 升序 排序。如果有多个值的频率相同,请你按照数值本身将它们 降序 排序。 请你返回排序后的数组。 示例1:输入:nums=[1,1,2,2,2,3]输出:[3,1,1,2,2,2]解释:'3'频率为1,'1'频率为2,'2'频率为3。示例2:输入:nu......
  • 哈希表 part 1
    相关阅读:https://docs.qq.com/doc/DUEtFSGdreWRuR2p4当遇到了要快速判断一个元素是否出现集合里的时候,就需要考虑哈希法。1.两数之和deftwoSum(self,nums,target):""":typenums:List[int]:typetarget:int:rtype:List[int]......
  • 【LeetCode动态规划#16】矩阵的最小路径和、三角形的最小路径和
    矩阵的最小路径和给定一个包含非负整数的*m*x*n*网格grid,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:一个机器人每次只能向下或者向右移动一步。示例1:输入:grid=[[1,3,1],[1,5,1],[4,2,1]]输出:7解释:因为路径1→3→1→1→1的总和最小。......
  • LeetCode-21. 合并两个有序链表(Java)
    这是我在51CTO博客开启的写作之路,第一次正式写博客记录我在LeetCode的刷题日,希望能帮助更多的小伙伴攻面自己心仪的公司offer。如下对于 LeetCode-21.合并两个有序链表,进行全面解析并小结解题思路,同学们请参考:1.题目描述将两个升序链表合并为一个新的 升序 链表并返回。新链表......
  • LeetCode-24. 两两交换链表中的节点(Golang)
    一、前言作者:bug菌博客:CSDN、掘金、infoQ、51CTO等简介:CSDN/阿里云/华为云/51CTO博客专家,博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者,全网粉丝合计10w+,硬核微信公众号「猿圈奇妙屋」,免费领取简历模板/学习资料/大厂面试真题/职业规划......
  • [LeetCode][198]house-robber
    ContentYouareaprofessionalrobberplanningtorobhousesalongastreet.Eachhousehasacertainamountofmoneystashed,theonlyconstraintstoppingyoufromrobbingeachofthemisthatadjacenthouseshavesecuritysystemsconnectedanditwilla......
  • 【LeetCode动态规划#15】最长公共子序列II
    最长公共子序列(二)描述给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如果最长公共子序列为空,则返回"-1"。目前给出的数据,仅仅会存在一个最长的公共子序列数据范围:0≤∣���1∣,∣���2∣≤20000≤∣str1∣,∣str2∣≤2000要求:空间复杂度�(�2)O(n2),时间复杂度�(�2)O(n2)......