算法刷题Day7 - 哈希表part2|LC.454 四数相加 II|LC.383 赎金信|LC.15 三数之和|LC.18 四数之和

LeetCode - 454. 4Sum II 四数相加II

解题目标:给定四个数组,返回四个数组中分别找出特定位置元素相加得到0的情况的总数

解题思路:这一题不是求每个元素的下标,只需要统计相加等于零的情况的总数。暴力解法就是找出四个数组元素的所有排列组合,最后统计等于0的情况,这样时间复杂度是n^4。实际上可以在这个思路上进一步优化,把前两个数组A[i]+B[j]的元素相加并放入集合,再遍历后两个数组的元素和来对集合里的数进行判断是否有与集合中的元素相加等于0的情况,这样n^2就可以达到目的。

注意事项:为什么是分为两组?这主要是因为这样是可以得到最优的时间复杂度,如果遍历第一个数组再同时查找后三个数组,那么就是n^3。

还有这题必须要用map来进行统计的原因是A+B数组的元素和可能会有不同的排列组合,比如呀1+4,2+3都是5,因此我们的key保存的是前两个数组元素和的值,value应该要保存两数之和出现的次数,判断中应该每次加的是之前所统计的出现次数而不是单纯的加一。

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        HashMap<Integer, Integer> records = new HashMap<>();
        // record first two arrays' elements sum
        for (int i : nums1) {
            for (int j : nums2) {
                int sum = i + j;
                //getOrDefault() 如果有sum这个key则返回value,没有则返回默认值0
                records.put(sum, records.getOrDefault(sum, 0) + 1);
            }
        }
        //last two arrays
        int count = 0;
        for (int k : nums3) {
            for (int l: nums4) {
                int diff = 0 - (k + l);
                count += records.getOrDefault(diff, 0);
            }
        }
        return count;
    }
}

LeetCode - 383. Ransome Note

解题目标:给定两个字符串,判断第一个字符串ransomeNote能否用第二个字符串magazine来重新组合得到。

解题思路:和242有效字母异位词的思路很像,这里只需检查第一个字符串在数组所对应的元素。

在第一次写的时候检查哈希表的逻辑用了两层循环,实际上不用另写检查逻辑,可以以magazine为基准先遍历存放在哈希表中,在--的过程中就可以一边检查是否正确,如果减之后为负数,则证明ransomeNote所需的字母不够用,那么一定不符合条件。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        if (ransomNote.length() > magazine.length()) return false;
        int[] records = new int[26];
        for (int i = 0; i < magazine.length(); i++) {
            records[magazine.charAt(i) - 'a']++;
        }
        for (int j = 0; j < ransomNote.length(); j++) {
            records[ransomNote.charAt(j) - 'a']--;
            if (records[ransomNote.charAt(j) - 'a'] < 0) return false;
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值