Day7代码随想录(1刷) 哈希表

这篇具有很好参考价值的文章主要介绍了Day7代码随想录(1刷) 哈希表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

454. 四数相加 II

 383. 赎金信

15. 三数之和

 18. 四数之和


 

454. 四数相加 II

给你四个整数数组 nums1nums2nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

示例 1:

输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0

示例 2:

输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]
输出:1

  提示:

  • n == nums1.length
  • n == nums2.length
  • n == nums3.length
  • n == nums4.length
  • 1 <= n <= 200
  • -228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228

状态:看了答案思路完成,一开始定nums1的值,然后遍历剩下三个数组的方式超时

思路: 把nums1和nums2的和有多少种情况用map存起来,然后在nums3和nums4中遍历并查看map里有无与其相加为0的数字若有则把val加到sum中。map.getOrDefault(key,val)这个方法可以指定默认值然后存取。

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int sum=0;
        HashMap<Integer,Integer> map = new HashMap<>();
            for(int j=0;j<nums1.length;j++){
                for(int k=0;k<nums2.length;k++){
                    if(map.containsKey(nums1[j]+nums2[k])){
                        map.put(Integer.valueOf(nums1[j]+nums2[k]),Integer.valueOf(map.get(nums1[j]+nums2[k])+1));
                    }else{
                        map.put(Integer.valueOf(nums1[j]+nums2[k]),Integer.valueOf(1));
                    }
                }
            }
        for(int i=0;i<nums3.length;i++){
            for(int j=0;j<nums4.length;j++){
                if(map.containsKey(0-nums3[i]-nums4[j])){
                    sum+=map.get(0-nums3[i]-nums4[j]);
                }
            }
        }
        return sum;
    }
}

 383. 赎金信

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

示例 1:

输入:ransomNote = "a", magazine = "b"
输出:false

示例 2:

输入:ransomNote = "aa", magazine = "ab"
输出:false

示例 3:

输入:ransomNote = "aa", magazine = "aab"
输出:true

提示:

  • 1 <= ransomNote.length, magazine.length <= 105
  • ransomNote 和 magazine 由小写英文字母组成

状态:完成

思路:因为只有小写字母,所以直接构建长度为26的int数组arr用于存放magzine中的字符出现次数,字符-'a'则可以得到数组的下标。存放完magzine中出现次数后,遍历ransomNote,如果arr里该值大于0则arr中该下标-1,如果等于0则返回false。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        if(ransomNote.length()>magazine.length()) return false;
        int[] arr = new int[26];
        char[] ransomNotes=ransomNote.toCharArray();
        char[] magazines=magazine.toCharArray();
        for(int i=0;i<magazines.length;i++){
            arr[magazines[i]-'a']++;
        }
        for(int i=0;i<ransomNotes.length;i++){
            if(arr[ransomNotes[i]-'a']>0){
                arr[ransomNotes[i]-'a']--;
            }else{ 
                return false;
            }
        }
        return true;
        
    }
}

15. 三数之和

 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

状态:完成

思路:使用双指针的方式去解题更好,不用建立哈希表节约空间与时间。我先对数组采用升序排序,因为是要找到三个数和为0的,我们先指定一个数i,将他的值固定,以不变找变,left的初始值是i+1,right初始值是最后一个,如图一所示。

Day7代码随想录(1刷) 哈希表,leetcode(一刷),散列表,java,算法
                                                        图1

-4是小于0,若i所对应的值大于0则不可能相加为0了,因为采用升序排。如果三个数相加如图一小于0,则left++,将结果变大。若大于0,则right--将结果变小,若等于0则将i,left,right写入数组,java可以用Arrays.asList(int,int,int,...)来快速创建数组,然后left++,right--,因为这两个值肯定不能选择了。这时注意结果数组不能有重复,如果left++/right--之后对应的值等于原先的值则一直+/-到不同样为止。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> arr = new ArrayList<>();
        if(nums[0]>0) return arr;
        for(int i=0;i<nums.length;i++){
            while(i>0&&i<nums.length-1&&nums[i]==nums[i-1]) i++; 
            if(nums[i]>0) break;
            int left=i+1;
            int right=nums.length-1;
            if(right==i) break;
            while(left<right){
                int sum=nums[left]+nums[right]+nums[i];
                if(sum==0){
                    arr.add(Arrays.asList(nums[left],nums[right],nums[i]));
                    left++;
                    right--;
                    while(left<nums.length-1&&nums[left]==nums[left-1]) left++; 
                    while(right>i&&nums[right]==nums[right+1]) right--; 
                }else if(sum>0){
                    right--;
                }else if(sum<0){
                    left++;
                }
            }
        }
        return arr;
    }
}

 18. 四数之和

状态:缝缝补补写出来的,有两个点没注意。一是剪枝的时候把nums[a]>0的值给删了,但是这个target可以是正可以是负,导致错误。二是sum的结果溢出,要用long类型。

思路:一看到就知道是三数之和多嵌套了一层,但是实际写起来没有这么简单,问题主要就在剪枝和去重以及结果溢出。我的代码太乱了,还是要想清楚再做题,下面给出正确的思路及代码。

思路:链接https://programmercarl.com/0018.%E5%9B%9B%E6%95%B0%E4%B9%8B%E5%92%8C.html#%E6%80%9D%E8%B7%AF

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> list = new ArrayList<>();
        if (nums.length < 4)
            return list;
        Arrays.sort(nums);
        for (int a = 0; a < nums.length - 3; a++) {
            while (a > 0 && nums[a] == nums[a - 1]){
                a++;
                if (a >= nums.length - 3) return list;
            }
            long sum_t = (long)target - nums[a];// b+c+d所要求的总和
            int b = a + 1;
            int c = b + 1;
            int d = nums.length - 1;
            long sum = (long)nums[b] + nums[c] + nums[d];
            for (; b < d - 1; b++) {
                System.out.println(a + " " + b + " " + c + " " + d + " ");
                while(b!=a+1&&b<d&&nums[b]==nums[b-1]) b++;
                c = b + 1;
                while (b < c && c < d) {
                    sum = (long)nums[b] + nums[c] + nums[d];
                    if (sum == sum_t) {
                        list.add(Arrays.asList(nums[a], nums[b], nums[c], nums[d]));
                        c++;
                        d--;
                        while (c < d && nums[c] == nums[c - 1])
                            c++;
                        while (d > c && nums[d] == nums[d + 1])
                            d--;
                    } else if (sum > sum_t) {
                        d--;
                    } else if (sum < sum_t) {
                        c++;
                    }
                }
                d = nums.length - 1;
            }
        }
        return list;
    }
}

感想:今天的题目难度主要都集中于最后一题。没想到最后一题竟然这么多坑,其实就比第三题多一个循环,但是就是要想的点有很多。继续坚持下去。文章来源地址https://www.toymoban.com/news/detail-843203.html

到了这里,关于Day7代码随想录(1刷) 哈希表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【代码随想录 | Leetcode | 第十天】哈希表 | 三数之和 | 四数之和

    欢迎来到小K的Leetcode|代码随想录|专题化专栏,今天将为大家带来哈希法~三数之和 | 四数之和的分享 ✨ ✨题目链接点这里 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为

    2024年02月15日
    浏览(33)
  • 【代码随想录 | Leetcode | 第九天】哈希表 | 快乐数 | 四数相加 II | 赎金信

    欢迎来到小K的Leetcode|代码随想录|专题化专栏,今天将为大家带来哈希法~快乐数 | 四数相加 II | 赎金信的分享 ✨ ✨题目链接点这里 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后

    2024年02月13日
    浏览(39)
  • 代码随想录刷题第6天|哈希表 LeetCode242、LeetCode349、LeetCode202、LeetCode1

    1、LeetCode242 有效的字母异位词 题目链接:242、有效的字母异位词 用哈希表,record[s[i]-\\\'a\\\']++,record[t[i]-\\\'a\\\']--,最后判断record里是否有元素不为0。 2、LeetCode349、两个数组的交集 题目链接:349、两个数组的交集 题目如果没有限制数值的大小,就无法使用数组来做哈希表。如果哈

    2024年02月06日
    浏览(49)
  • 代码随想录Day1 | 数组01- leetcode 704、27

    题目链接:二分查找 关键问题:         - 边界(left、right)、当前查找值(middle)                 - target大于当前查找值 -- 当前查找区域的右边,更改区间left                 - target小于当前查找值 -- 当前查找区域的左边,更改区间right                 - middle的计

    2024年02月16日
    浏览(27)
  • 代码随想录Day20 回溯算法 LeetCode77 组合问题

    以下内容更详细解释来自于:代码随想录 (programmercarl.com) 回溯法也叫回溯搜索法,是搜索法的一种,我们之前在二叉树中也经常使用到回溯来解决问题,其实 有递归就有回溯 ,有的时候回溯隐藏在递归之下,我们不容易发觉,今天我们来详细介绍一下什么是回溯,它能解决哪些问题.

    2024年02月08日
    浏览(33)
  • 代码随想录Day3 | 链表01-leetcode203、707、206

    题目链接:移除链表元素 思路: 链表中元素的添加和删除关键是要 保证不断链且指向关系正确 。对于删除操作,链的修改涉及将待删除元素的前一个元素指向待删除元素的后一个元素,因此在判断当前元素是否需要删除时,要记录当前元素的前后指针。 1.删除头结点时另作

    2024年02月16日
    浏览(43)
  • 代码随想录day6|哈希表理论基础、有效的字母异位词、两个数组的交集、快乐数、两数之和

    当需要判断一个元素是否在一个集合中,哈希表的时间复杂度只有O(1)。 哈希表有一个映射的操作,当映射的元素在同一个索引下标的位置,就会引发 哈希碰撞 。 哈希碰撞的两种解决方法:拉链法 线性探测法   同时,哈希表还有常见的三种数据结构:分别是数组、集合s

    2024年02月06日
    浏览(37)
  • 代码随想录 Day6 哈希表 哈希表理论基础, 242.有效的字母异位词, 349. 两个数组的交集,202. 快乐数,1. 两数之和

    yi  哈希表理论基础 哈希表是采用了牺牲空间换取时间,因为需要存储额外的数据。 需要快速判断一个元素是否出现在一个 数组中的时候就需要哈希法。 er  242.有效的字母异位词 本题一开始想到的是使用map,感觉是字母和数字的组合 问题:  1. 注意给\\\'a\\\'穿衣服 2.想到其实

    2024年03月09日
    浏览(34)
  • 代码随想录day21(2)二叉树:二叉树的所有路径(leetcode257)

    题目要求:按任意顺序返回所有从根节点到叶节点的路径 思路:我们先递归地进行前序遍历,同时要注意回溯的过程,注意一些库的用法即可。 leetcode实战: 代码实现:

    2024年03月18日
    浏览(39)
  • 代码随想录Day33 LeetCode T62不同路径 LeetCode T63 不同路径II

    动规五部曲 1.确定dp数组含义 2.确定递推公式 3.初始化数组 4.确定遍历方式 5.打印dp数组查看分析问题 题目链接:62. 不同路径 - 力扣(LeetCode) 注:n行m列而不是m行n列 1.确定dp数组含义 代表到达此下标有多少条路径 2.确定递推公式 因为只能向右或者向下走,所以到达i,j这个点的

    2024年02月06日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包