首页 > 其他分享 >代码随想录哈希表第二天:四数相加2、三数之和、四数之和、赎金信

代码随想录哈希表第二天:四数相加2、三数之和、四数之和、赎金信

时间:2024-07-23 21:59:00浏览次数:18  
标签:四数 nums int 三数 sum 随想录 ++ right left

详细可移步个人代码随想录打卡

四数相加

使用2次,2层for循环。即可确定和值,然后使用一个map来记录第一个for循环的值,再第二次for循环中找,并记录次数即可。

代码如下:

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int count = 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 c : nums3){
            for(int d : nums4){
                int temp = 0 - c - d;
                if(map.containsKey(temp)){
                    count += map.get(temp);
                }
            }
        }
        return count;
    }
}

赎金信

该题的思路与字母的有效移位词非常像。可以创建一个数组作为哈希表,存储字母数量,然后遍历另一个字符串,对应字母数-1,如果有小于0的情况就返回false,否则就返回true。

代码如下:

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

三数之和

本题的思路使用双指针,首先第一个for循环遍历整个数组,然后在循环中设置两个指针,通过i和两个指针对应的值求和,如果是0就放入result中,然后对左右指针进行去重,大于小于则移动左右指针。遍历前要对数组进行排序。

本题我写的时候有以下问题:

重复的去重逻辑问题:在发现一个合法的三元组后,左右指针都会移动,并再次进行去重操作。其实,只需要在左右指针移动后,进行一次去重操作。

指针移动位置错误:在发现一个合法的三元组后,应该在左右指针去重之后,再移动指针到新的位置。

代码如下:

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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(nums[i] > 0) return result;
            if(i != 0 && nums[i] == nums[i - 1]){
                continue;
            }
            int left = i + 1;
            int right = nums.length - 1;
            while(right > left){
                int sum = nums[i] + nums[left] + nums[right];
                if(sum == 0){
                    result.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    while(right > left && nums[right] == nums[right - 1]) right--;
                    while(right > left && nums[left] == nums[left + 1]) left++;
                    left++;
                    right--;
                }else if(sum > 0){
                    right--;
                }else if(sum < 0){
                    left++;
                }
            }
        }
        return result;
    }
}

四数之和

该题思路与三数之和一样,但是需要注意需要多加一层for循环。其次是剪枝处理需要注意target可能是负数。

此外需要注意的是在循环中注意范围以及左右指针的去重。还有一点,和需要long格式,不然有两个例子通过不了。

代码如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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-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] == nums[j - 1]) {
                    continue;
                }
                int left = j + 1;
                int right = nums.length - 1;
                while(right > left){
                    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(right > left && nums[left] == nums[left + 1]){
                            left++;
                        }
                        while(right > left && nums[right] == nums[right - 1]){
                            right--;
                        }
                        left++;
                        right--;
                    }
                }
            }
        }
        return result;
    }
}

今日八股

  1. 一条查询SQL的语句是如何执行的?
  2. 事物的四大特性有哪些?
  3. 数据库的事物隔离级别有哪些?

标签:四数,nums,int,三数,sum,随想录,++,right,left
From: https://blog.csdn.net/weixin_51363613/article/details/140647185

相关文章

  • 代码随想录算法训练营Day7 | Leetcode 454 四数相加Ⅱ Leetcode 383 赎金信 Leetcode
    前言今天的四道题目稍稍有点难度,需要理解和反复记忆才行。四数相加类比于两数之和,赎金信类比于异位词,三数之和和四数之和自成体系,可以推广到n数之和。Leetcode454四数相加Ⅱ题目链接:454.四数相加II-力扣(LeetCode)代码随想录题解:代码随想录(programmercarl.com)思路:......
  • 代码随想录算法训练营Day5、6 | Leetcode 242 有效字母的异位词 Leetcode 349 两个数
    前言因为昨天休息所以把两天合并成一天来写,昨天把上周的题又重写了一遍,发现一些细节还是要注意。今天的题目都是查找,也涉及到了最近正在学的STL。Leetcode242有效字母的异位词 题目链接:https://leetcode.cn/problems/valid-anagram/description/代码随想录题解:代码随想......
  • 代码随想录算法训练营第四天 | Leetcode 24 两两交换链表中的节点 Leetcode 19 删除链
    前言今天链表的内容突出一个注意细节,判空条件,头节点是否为空等等。采用虚拟头节点可以方便链表进行更改,还需要学会使用临时变量。 Leetcode24两两交换链表中的节点题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/代码随想录题解:代码随想录(programmercarl.......
  • 代码随想录算法训练营第三天 | Leetcode 203 移除链表元素 Leetcode 206 翻转链表
    前言今天的两道题目都不难,但细节需要注意。如移除链表元素用到的虚拟头节点,翻转链表的思路。翻转链表真是写了忘,忘了写,希望这次能记住。除此之外我决定每天的记录里面增加一个总结八股的部分,将来二刷再翻看文章的时候顺便也能复习八股知识点。Leetcode203移除链表元素题目......
  • 代码随想录算法训练营第20天 | 二叉搜索树中级
    2024年7月22日题235.二叉搜索树的最近公共祖先普通解法还是和普通的祖先一样求即可,再依据搜索树特性进行剪枝即可加速。importjava.util.*;classSolution{Vector<TreeNode>vec1;Vector<TreeNode>vec2;intflag1=0;intflag2=0;publicT......
  • 代码随想录算法训练营第18天 | 二叉搜索树进阶
    2024年7月20日题530.二叉搜索树的最小绝对差使用递归获取中序遍历,然后遍历一遍vector即可得到结果。importjava.util.*;classSolution{Vector<Integer>vec;publicintgetMinimumDifference(TreeNoderoot){//首先得到中序遍历的结果vec......
  • # 代码随想录算法训练营第38天 | 01背包问题:1049.最后一块石头的重量II(最多能装多少)、
    1049.最后一块石头的重量IIhttps://leetcode.cn/problems/last-stone-weight-ii/代码随想录https://programmercarl.com/1049.最后一块石头的重量II.html#算法公开课494.目标和https://leetcode.cn/problems/target-sum/description/代码随想录https://programmercarl.com......
  • 代码随想录day7 | 454 四数相加|| 383 赎金信 15 三数之和 18 四数之和
    454四个数相加==0funcfourSumCount(nums1[]int,nums2[]int,nums3[]int,nums4[]int)int{ //1.用哈希表存储nums1和nums2两者之和的所有可能情况 //2.遍历nums3和nums4两者之和的相反数,如果在哈希表中存在,则结果加上哈希表中的值 //3.返回结果 sum1:......
  • 算法-代码随想录-哈希表
    有效的字母异位词思路:数组作为一个简单的哈希表,可以用来记录字符串中每个字符出现的次数。可以设置一个数组,第一轮遍历s中的字符,字符每出现一次,在数组对应位置+1。第二轮遍历t中的字符,字符每出现一次,在数组对应位置-1。最后遍历作为哈希表的数组,如果都为0,则说明每个字符出现的......
  • 「代码随想录算法训练营」第十八天 | 二叉树 part8
    669.修剪二叉搜索树题目链接:https://leetcode.cn/problems/trim-a-binary-search-tree/题目难度:中等文章讲解:https://programmercarl.com/0669.修剪二叉搜索树.html视频讲解:https://www.bilibili.com/video/BV17P41177ud?share_source=copy_web题目状态:没有思路,看题解过......