代码随想录五刷day3

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


一般来说哈希表都是用来快速判断一个元素是否出现集合里。

一、力扣242. 有效的字母异位词

两个字符串,里面全是小写字母,直接用数组计数之后比较就行

class Solution {
    public boolean isAnagram(String s, String t) {
        int[] arr = new int[27];
        for(char c : s.toCharArray()){
            arr[c - 'a'] ++;
        }
        for(char c : t.toCharArray()){
            arr[c - 'a'] --;
        }
        for(int a : arr){
            if(a != 0){
                return false;
            }
        }
        return true;
    }
}

二、力扣383. 赎金信

两个字符串,都是由小写字母构成的,判断其中一个是否可以由另外一个构成,直接数组一个++计数,一个--计数,最后计数数组里面有小于0的就表示失败,否则成功

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

三、力扣49. 字母异位词分组

一个字符串集合,把里面所有的异位词进行分组,很明显需要哈希表,先重新构建key值,同一组异位词是同一个key,直接用字母拼上字母的个数就行,然后用map收集,最后输出

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> res = new ArrayList<>();
        Map<String,List<String>> map = new HashMap<>();
        for(String str : strs){
            int[] arr = new int[27];
            for(char c : str.toCharArray()){
                arr[c - 'a'] ++;
            }
            String s = "";
            for(int i = 0; i < 26; i ++){
                if(arr[i] != 0){
                    s += ('a' + i);
                    s += arr[i];
                }
            }
            List<String> list = map.getOrDefault(s, new ArrayList<String>());
            list.add(str);
            map.put(s, list);
        }
        return map.values().stream().collect(Collectors.toList());
    }
}

四、力扣438. 找到字符串中所有字母异位词

找到字符串中的所有字母异位词,先把目标异位词收集进数组,之后,被处理字符串,使用双指针滑动窗口进行处理,窗口大小就是目标异位词的长度,每次移动一下,就更新,另外一个收集数组,更新完之后,两个收集数组进行比对,若是一致,就把左指针下标收集进最终返回的list中

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> res = new ArrayList<>();
        if(s.length() < p.length()){
            return res;
        }
        int[] arr1 = new int[26];
        int[] arr2 = new int[26];
        for(int i = 0; i < p.length(); i ++){
            arr1[p.charAt(i) - 'a'] ++;
            arr2[s.charAt(i) - 'a'] ++; 
        }
        int left = 0, right = p.length()-1;
        while(right < s.length()){
            boolean flag = true;
            for(int i = 0; i < 26; i ++){
                if(arr1[i] != arr2[i]){
                    flag = false;
                }
            }
            if(flag){
                res.add(left);
            }
            right ++;
            if(right >= s.length()){
                break;
            }
            arr2[s.charAt(left) - 'a'] --;
            arr2[s.charAt(right) - 'a'] ++;
            left ++;
        }
        return res;
    }
}

五、力扣349. 两个数组的交集

求两个数组的交集,直接创建两个set,先用第一个set收集第一个数组,之后,判断第二个数组中的每一个元素是否存在第一个set中,若是,就收集到第二个set中,最后把第二个set作为最终结果

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> set1 = new HashSet<>();
        for(int a : nums1){
            set1.add(a);
        }
        Set<Integer> set2 = new HashSet<>();
        for(int a : nums2){
            if(set1.contains(a)){
                set2.add(a);
            }
        }
        int[] res = new int[set2.size()];
        int i = 0;
        for(int a : set2){
            res[i ++] = a;
        }
        return res;
    }
}

六、力扣350. 两个数组的交集 II

使用两个map分别收集

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Map<Integer,Integer> map1 = new HashMap<>();
        Map<Integer,Integer> map2 = new HashMap<>();
        for(int a : nums1){
            map1.put(a, map1.getOrDefault(a,0) + 1);
        }
        for(int a : nums2){
            if(map2.getOrDefault(a,0) < map1.getOrDefault(a,0)){
                map2.put(a, map2.getOrDefault(a,0)+1);
            }
        }
        List<Integer> list = new ArrayList<>();
        for(Map.Entry<Integer,Integer> entry : map2.entrySet()){
            for(int a = 0; a < entry.getValue(); a ++){
                list.add(entry.getKey());
            }
        }
        int[] res = new int[list.size()];
        for(int i = 0; i < res.length; i ++){
            res[i] = list.get(i);
        }
        return res;
    }
}

七、力扣202. 快乐数

读题要仔细,快乐数的定义是,一个正整数,对于每一个位置上的数都进行平方,然后求和,得到新的数重复这个过程,最后得到的结果,要么为1,要么无限循环,只有这两个结果,换句话说,一定会出现重复的结果,用一个set判断中条件,最后判断是否为1

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        while(!set.contains(n)){
            set.add(n);
            n = fun(n);
        }
        return n == 1;
    }
    public int fun(int n){
        int sum = 0;
        while(n != 0){
            int t = n % 10;
            n /= 10;
            sum += (t * t);
        }
        return sum;
    }
}

八、力扣1. 两数之和

给定一个数组,从中寻找目标值的下标

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        int[] res = new int[2];
        for(int i = 0; i < nums.length; i ++){
            map.put(nums[i], i);
        }
        for(int i = 0; i < nums.length; i ++){
            int temp = target - nums[i];
            if(map.containsKey(temp) && map.get(temp) != i){
                res[0] = i;
                res[1] = map.get(temp);
                break;
            }
        }
        return res;
    }
}

九、力扣454. 四数相加 II

这道题目是4个数组,不需要考虑重复问题,直接map就能做,累加求和就是

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

十、力扣15. 三数之和

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

十一、力扣18. 四数之和

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        if(nums.length < 4){
            return res;
        }
        Arrays.sort(nums);
        if(target < 0 && nums[0] > 0){
            return res;
        }
        for(int i = 0; i < nums.length-3; i++){
            if(i > 0 && nums[i] == nums[i-1]){
                continue;
            }
            for(int j = i+1; j < nums.length -2; j ++){
                if(j > i+1 && nums[j-1] == nums[j]){
                    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{
                        res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        right --;
                        while(left < right && nums[right+1] == nums[right]){
                            right --;
                        }
                        left ++;
                        while(left < right && nums[left-1] == nums[left]){
                            left ++;
                        }
                    }
                }
            }
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乱世在摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值