算法训练营Day7

语言

采用的Java语言,一些分析也是用于Java,请注意。

454.四数相加II 

454. 四数相加 II - 力扣(LeetCode)

这道题理解好只是统计数量即可,不需要去重,因此很简单的题目。

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

383. 赎金信

383. 赎金信 - 力扣(LeetCode)

这个题很简单。

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

        return true;
    }
}

15. 三数之和

15. 三数之和 - 力扣(LeetCode)

这道题有三个注意的地方

1、对i去重的时候是要i和i-1, 因为要先把结果拿到,再做去重

2,对于left和right去重的位置也要注意,也是要拿到结果,再去重,所以放后面

3、对于==之后做left++和right--放在while的前面还是后面

这里给出来了例子,应该是放到后面才对,放前面的话就归到剪枝的逻辑去了,结果就会重复。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; i++) {
            if(nums[i]>0){return res;}
            //对i去重

            if(i>0&&nums[i]==nums[i-1]){//i 和 i+1的话,会少情况,比如-1,-1,2
                //意思就是-1,-1 2 的时候要先收集,下一步再跳过去去重
                continue;
            }
            int left = i+1;
            int right = nums.length-1;
            while(right>left){//=的时候不符合条件,因为有三个数
                int sum = nums[i]+nums[left]+nums[right];
                if(sum>0){
                    right--;
                }else if(sum<0){
                    left++;
                }else {
                    List<Integer> subRes = Arrays.asList(nums[i], nums[left], nums[right]);
                    res.add(subRes);
                    //去重 //[-1,-1,0,1 1  1]
                    while(right>left && nums[left]==nums[left+1]) left++;
                    while(right>left && nums[right]==nums[right-1]) right--;
                    //-1,0,1
                    left++;
                    right--;
                }
            }
        }
            return res;
    }
}

18. 四数之和  

18. 四数之和 - 力扣(LeetCode)

注意点1:

第一个剪枝可直接return res,因为数组排序好的,比如

target = -1  nums: -2 -2 0  0 1  2  4 5

k 第一次= -2 然后,下一次循环的时候,-2  continue,=0的时候,发现大于0 了,那么后面的数都大于9,就可以不用算了。再怎么相加都会大于target,因为k=0的时候,后面的i 和left right加起来肯定时大于target的

若刚开始的nums就是 0 1  2 3 4 这样大于=0 的,就更符合剪枝的逻辑了

举这个例子的时候,就是为了解释,为什么这里可以直接return

那么为什么二级减枝不可以直接retrun呢?

这里就需要注意了,第二层循环的时候,比如-2  -1 0 0 1 2的时候,k=-2 i=2>=target的时候,符合条件,并不影响下一次的-1和0<target.这是需要注意的,看这里的模拟

注意点2:

剪枝逻辑里 是nums[k]>target&&nums[k]>0还是nums[k]>target&&target>0

nums[k] > target && nums[k] > 0 这个条件表示的含义是,如果当前值比 target 大,并且后面再加其他值还是比 target 大说明当前这个值不用往后选了,nums[k] > 0 就是用来保证 k 位置后面的值比当前值大的。 但是你写成 target > 0 无形中就把范围收窄了

所以推荐nums[k]>target&&nums[k]>0,可以把条件缩小,剪枝多一点,

这道题用另一种写法的话会报错误,应该是int类型溢出的问题,可以替换代码试一下

注意点3

continue可不可以写成i++、k++

比如-1 -1 -1,0

k在第二个-1的时候,continue下一次到0了,但是认为k++也可以满足到0 ,其实是只会++一次,continue可以做到移动到0 

有人说那改成while不就好了,while和i++,这就需要考虑其他问题,舍本逐末,不要和我一样钻牛角尖。

解题

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for (int k = 0; k < nums.length; k++) {
            //剪枝
            if(nums[k]>target&&nums[k]>=0){
                return res;
            }
            //去重 -1  -1  0
            if(k>0&&nums[k]==nums[k-1]) continue;
            for (int i = k+1; i < nums.length; i++) {
                //剪枝
                int sum1 = nums[k]+nums[i];
                 if(sum1>target&&sum1>=0) break;
                //去重
                if(i>k+1&&nums[i]==nums[i-1]) continue;
                //left和right去重
                int left = i+1;
                int right = nums.length-1;
                while(right>left){

                    long sum = sum1+nums[left]+nums[right];
                    if(sum>target){
                        right--;
                    } else if (sum < target) {
                        left++;
                    }else {
                        List<Integer> subRes = Arrays.asList(nums[k], nums[i], nums[left], nums[right]);
                        res.add(subRes);
                        while (right>left&&nums[right]==nums[right-1])right--;
                        while (right>left&&nums[left]==nums[left+1])left++;
                        left++;
                        right--;
                    }
                }
            }
        }
        return res;
    }
}

总结

hash表这里每个博客都分析了一下,就不做总结了,这个四数之和挺累的,长脑子了,方便我复习,就把卡哥的总结放这里了,方便我和读者回顾。

代码随想录 (programmercarl.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/234491.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SSD基础架构与NAND IO并发问题探讨

在我们的日常生活中&#xff0c;我们经常会遇到一些“快如闪电”的事物&#xff1a;比如那场突如其来的雨、那个突然出现在你眼前的前任、还有就是今天我们要聊的——固态硬盘&#xff08;SSD&#xff09;。 如果你是一个技术宅&#xff0c;或者对速度有着近乎偏执的追求&…

深度学习——第4.1章 深度学习的数学基础

第4章 深度学习的数学基础 目录 4.1 向量 4.2 求和符号 4.3 累乘符号 4.4 导数 4.5 偏导数 4.6 矩阵 4.7 指数函数和对数函数 注意&#xff1a;4.6和4.7位于4.2章 第4章 深度学习的数学基础 本章总结一下机器学习所需的数学知识&#xff0c;同时介绍如何在Python中使用…

Kafka 最佳实践:构建可靠、高性能的分布式消息系统

Apache Kafka 是一个强大的分布式消息系统&#xff0c;被广泛应用于实时数据流处理和事件驱动架构。为了充分发挥 Kafka 的优势&#xff0c;需要遵循一些最佳实践&#xff0c;确保系统在高负载下稳定运行&#xff0c;数据可靠传递。本文将深入探讨 Kafka 的一些最佳实践&#x…

二叉排序树的判断(二叉树的顺序存储):2022年408算法题

对于采用顺序存储方式保存的二叉树&#xff0c;根结点保存在SqBiTNode[0]中&#xff1b;当某结点保存SqBiTNode[i]中时&#xff0c;若有左孩子&#xff0c;则其值保存在SqBiTNode [2i1]中&#xff1b;若有右孩子&#xff0c;则其值保存在SqBiTNode[2i2]中&#xff1b;若有双亲结…

JavaScript中冷门但有用的String.raw

文章梗概 本文讲解的String.raw&#xff0c;作为JavaScript中的静态方法&#xff0c;用来获取模板字符串的原始字符串形式&#xff0c;需要注意的是与字符串模板搭配时候的事项。 介绍 String.raw() 静态方法是模板字符串的标签函数。它的作用类似于 Python 中的 r 前缀或 C#…

linux7安装python3.12.1教程

1.下载tar.gz包 地址&#xff1a;Python Release Python 3.12.1 | Python.org 2.上传包到linux服并解压 cd /home/local/ ll tar -zxvf Python-3.12.1.tgz 3.安装编译python所需环境 yum install -y gcc yum install -y zlib* yum -y install zlib-devel bzip2-devel opens…

组件之间传值

目录 1&#xff1a;组件中的关系 2&#xff1a;父向子传值 3&#xff1a;子组件向父组件共享数据 4&#xff1a;兄弟组件数据共享 1&#xff1a;组件中的关系 在项目中使用到的组件关系最常用两种是&#xff0c;父子关系&#xff0c;兄弟关系 例如A组件使用B组件或者C组件…

Windows 安全基础——Windows WPAD篇

Windows 安全基础——Windows WPAD篇 WPAD全称Web Proxy Auto-Discovery Protocol&#xff0c; 也就是Web代理自动发现协议。&#xff08;这里的代理就是我们在渗透中使用BURP的时候修改的代理设置。&#xff09;它的作用是让局域网浏览器自动发现内网中的代理服务器&#xff…

java接入gpt开发

前情提要 本次文章使用编译器为IDEA2020 使用GPT模型为百度旗下的千帆大模型 如果是个人用或者不流传出去&#xff0c;可以无脑入&#xff0c;因为会免费送20块钱&#xff08;够用上万次&#xff09; 代金卷查看 正式教程&#xff1a; 百度智能云控制台 (baidu.com) 按照步…

c++-定长内存池

文章目录 前言一、定长内存池 前言 一、定长内存池 我们知道申请内存使用的是malloc&#xff0c;malloc其实就是一个通用的申请函数&#xff0c;什么场景下都可以用&#xff0c;但是什么场景下都可以用就意味着什么场景下都不会有很高的性能&#xff0c;下面我们来设计一个定…

Diffusion Models: A Comprehensive Survey of Methods and Applications

摘要 扩散模型作为一个强大的新的深度生成模型系列出现&#xff0c;在许多应用中具有破纪录的性能&#xff0c;包括图像合成、视频生成和分子设计。在这项调查中&#xff0c;我们对迅速扩大的扩散模型的工作进行了概述&#xff0c;将研究分为三个关键领域&#xff1a;有效采样…

HCIP —— BGP 基础 (下)

BGP 的状态机 --- 建立对等体之间的TCP会话&#xff1a;指定建立对等体的对象 六种状态机 Idle状态 Idle 等待状态&#xff08;相当于OSPF的down状态&#xff09;--- 采用TCP单播建邻 Idle 状态下&#xff0c;启动BGP协议后必须指定建立对等体的目标之后&#xff0c;才能进入…

python中getattr

一、getattr的基本概念 getattr是python的一个内置函数&#xff0c;说白了也很简单&#xff0c;就是判断一个方法或者属性是否存在于一个对象中若是存在则运行这个属性或者方法。 getattr(object, name[, default])object&#xff1a;对象名称 name&#xff1a;属性或者方法名…

uniappp框架——初始化vue3项目(搭建ai项目第一步)

文章目录 ⭐前言&#x1f496; 小程序系列文章 ⭐uniapp创建项目&#x1f496; 初始化项目&#x1f496; uni实例生命周期&#x1f496; 组件生命周期&#x1f496; 页面调用&#x1f496; 页面通讯&#x1f496; 路由 ⭐搭建首页⭐form表单校验页面⭐总结⭐结束 ⭐前言 大家好…

6.题目:编号2490 小蓝的括号串1

题目: ### 这道题主要考察stack #include<bits/stdc.h> using namespace std; const int N105; stack<char> stk; char s[N]; int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n;cin>>n;cin>>s1;bool anstrue;for(int i1;i<n;i){…

Verilog基础:$random系统函数的使用

相关阅读 Verilog基础​编辑https://blog.csdn.net/weixin_45791458/category_12263729.html $random系统函数语法的BNF范式如下所示&#xff0c;有关BNF范式相关内容&#xff0c;可以浏览以往文章Verilog基础&#xff1a;巴科斯范式(BNF)。 $random系统函数在每次调用时返回一…

第四节JavaScript 条件语句、循环语句、break与continue语句

一、JavaScript条件语句 在通常的代码中&#xff0c;我们有一些需要决定执行不同动作&#xff0c;这就可以在代码中使用条件语句来完成。 下面是我们常使用的条件语句&#xff1a; if语句&#xff1a;只有当指定条件是true时&#xff0c;执行条件内代码。if…else语句&#…

【Unity动画】什么是任意状态(Any state)

&#xff08;Any state&#xff09;可以从某个状态A直接切换到另一个状态 B\C\D\E\F 比如A到C的过渡&#xff0c;直接设置从Any state 到C的过渡线触发参数即可。而不需要让A到C直接在连接&#xff0c;同样&#xff0c;B到C之间也无需直接链接。 这样设计是在每一个动画之间都…

Redis 持久化 —— 超详细操作演示!

四、Redis 持久化 四、Redis 持久化4.1 持久化基本原理4.2 RDB持久化4.3 AOF持久化4.4 RDB与AOF对比4.5 持久化技术转型 五、Redis 主从集群六、Redis 分布式系统七、Redis 缓存八、Lua脚本详解九、分布式锁 数据库系列文章&#xff1a; 关系型数据库: MySQL —— 基础语法大全…

kotlin - ViewBinding

前言 为什么用ViewBinding&#xff0c;而不用findViewById()&#xff0c;这个有很多优秀的博主都做了讲解&#xff0c;就不再列出了。 可参考下列博主的文章&#xff1a; kotlin ViewBinding的使用 文章里也给出了如何在gradle中做出相应的配置。 &#xff08;我建议先看这位博…