算法笔记|Day6哈希表基础II

☆☆☆☆☆leetcode 454.四数相加II

题目链接:leetcode 454.四数相加II

题目分析

1.采用哈希map,遍历前两个数组的每个元素并求和存到map中,key来存元素的和sum,value来存出现次数,考虑后两个数组中每个元素的和的相反数是否在map出现过及出现次数;
2.时间复杂度为O(n2),空间复杂度为O(n2)。

代码

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int res=0;
        Map<Integer,Integer>map=new HashMap<>();
        for(int i:nums1){
            for(int j:nums2){
                int sum=i+j;
                map.put(sum,map.getOrDefault(sum,0)+1);
            }
        }
        for(int i:nums3){
            for(int j:nums4){
                res+=map.getOrDefault(-i-j,0);
            }
        }
        return res;
    }
}

提示:map.getOrDefault(key, defaultValue) 用于从Map中获取与给定键(key)相关联的值(value),如果Map中包含给定的键,则返回该键对应的值;如果Map中不包含该键,则返回提供的默认值defaultValue。

☆☆☆☆☆leetcode 383.赎金信

题目链接:leetcode 383. 赎金信

题目分析

1.定义一个数组record记录字符串ransomNote里字符出现的次数,并分别减去各个字符在字符串magazine中出现的次数,若record中有元素大于0返回false,否则返回true;
2.时间复杂度O(n) ,空间复杂度O(1)。

代码

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int record[]=new int[26];
        for(char c:ransomNote.toCharArray()){
            record[c-'a']++;
        }
        for(char c:magazine.toCharArray()){
            record[c-'a']--;
        }
        for(int i:record){
            if(i>0){
                return false;
            }
        }
        return true;
    }
}

提示:toCharArray() 是 Java 中的一个字符串(String)方法,它用于将字符串转换为字符数组(char array),转换后的字符数组包含了字符串中所有的字符,包括空格和特殊字符,但不包括字符串的结尾标记。

☆☆☆☆☆leetcode 15.三数之和

题目链接:leetcode 15.三数之和

题目分析

  1. 本题使用哈希法并不十分合适,因为在去重的操作中有很多细节需要注意较繁琐,故使用双指针法要比哈希法高效一些,首先对数组排序,一层for循环遍历元素,另外两个元素采用双指针法,还需注意此过程中nums[i]、nums[left]、nums[right]三个元素的去重问题;
  2. 时间复杂度O(n2) ,空间复杂度O(1)。

代码

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

提示:
1.Arrays.sort() 方法用于对数组进行排序;
2.Arrays.asList() 方法是一个静态方法,它可以将一个数组(无论是对象数组还是基本类型数组的包装类数组)转换成一个固定大小的列表(List),且它的大小是固定的,并且列表的任何非结构性修改都会反映到原数组上。由于列表的大小是固定的,不能通过列表的 add 或 remove 方法来添加或删除元素,否则将会抛出 ConcurrentModificationException 异常。

☆☆☆☆☆leetcode 18.四数之和

题目链接:leetcode 18.四数之和

题目分析

  1. 本题仍使用双指针法,首先对数组排序,两层for循环遍历元素,另外两个元素采用双指针法,还需注意此过程中nums[i]、nums[j]、nums[left]、nums[right]四个元素的去重问题;
  2. 时间复杂度O(n3) ,空间复杂度O(1)。

代码

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

提示:本题数字范围较大,应采用long数据类型。

  • 28
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值