代码随想录算法训练营Day6 | 454.四数相加||、383.赎金信、35.三个之和、18.四数之和

news2024/12/26 0:35:33

LeetCode 454 四数相加 ||

在这里插入图片描述
本题思路

如果使用暴力的话就是 4 层 for 循环,这个时间复杂度就是 O(n^4) 了。

所以我们可以使用 map ,来解决这道题,和之前的两数之和一样,之前是 遍历一个,存进去一个。 如果我们将 nums1 和 nums[2],每一个位置上的和,都存入 map 集合,然后再判断 target - (nums3[i]+nums4[j]) 的值是否存在于 map 中,如果在,就计数器 count = count + map.get(这个值)。 注意:累加的是这个值存在的次数。

下面就利用 示例1 画一个图来更好的理解下这个思路:在这里插入图片描述

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        // 本题思路返回有多少个元素,需要一个计数器 count,碰到符合的条件就 count++
        Map<Integer,Integer> map = new HashMap();
        // 将 nums1 nums2,每个位置都相加 存放到集合 map 中
        for(int i = 0; i < nums1.length; i++){
            for(int j = 0; j < nums2.length; j++){
                map.put(nums1[i] + nums2[j], map.getOrDefault(nums1[i] + nums2[j],0) + 1);
            }
        }
        int count = 0;
        // 利用 0 - (nums3 + nums4) 的值 等于0 的情况,来判断有多个符合条件的四元组
        for(int i = 0; i < nums3.length; i++){
            for(int j = 0; j < nums4.length; j++){
                if(map.containsKey(0 - (nums3[i] + nums4[j]))){
                    count = count + map.get(0 - (nums3[i] + nums4[j]));
                }
            }
        }
        return count;
    }
}

注意点:就是 count 不是 count++;


LeetCode 383 赎金信

在这里插入图片描述
本题思路:判断 ransomNote 是否能由 magazine 组成,说明 magazine 包含 ransomNode,magazine 的范围大一点,所以我们可以很容易想到使用 map , 将 magazine 中的元素全部存入到 map 中,并记录每个元素存在的次数。 然后便利 ransomNode 中的每个元素,判断 magazine 中是否都存在,如果有 一个 不存在就返回 false。如果存在,但是次数已经为 0 ,也返回 false。否则就 次数减 0
下面用一个图来分析下 示例 1,以便更好理解上述思路
在这里插入图片描述

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        Map<Character,Integer> map = new HashMap();
        for(int i = 0; i < magazine.length(); i++){
            map.put(magazine.charAt(i),map.getOrDefault(magazine.charAt(i),0)+1);
        }
        for(int i = 0; i < ransomNote.length(); i++){
            // 如果 magazine 里面没有 ransomNote 或者 这个元素存在此处已经 为 0 ,则返回false
            if( !map.containsKey(ransomNote.charAt(i)) || map.get(ransomNote.charAt(i)) == 0){
                return false;
            }
            map.put(ransomNote.charAt(i),map.get(ransomNote.charAt(i)) -1);
        }
        return true;
    }
}

本题其实用数组的情况下会更好,使用 map 的空间复杂夫会更高于一些(在数量大的时候就能体现出来),因为 map 底层会维护 红黑树 或者 链表等。以下是使用数组的代码。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        // shortcut
        if (ransomNote.length() > magazine.length()) {
            return false;
        }
        // 定义一个哈希映射数组
        int[] record = new int[26];

        // 遍历
        for(char c : magazine.toCharArray()){
            record[c - 'a'] += 1;
        }

        for(char c : ransomNote.toCharArray()){
            record[c - 'a'] -= 1;
        }
        
        // 如果数组中存在负数,说明ransomNote字符串总存在magazine中没有的字符
        for(int i : record){
            if(i < 0){
                return false;
            }
        }

        return true;
    }
}

LeetCode 35 三数之和

在这里插入图片描述

注意点:

  1. 要去重,不能出现重复的三元组。所以在每次 i 遍历的时候,都要先进行去重操作
  2. 进行 nums[left] 和 nums[right] 去重的时候,要先保存记录,再进行去重操作。
  3. 对 nums[left] 和 nums[right] 进行去重的时候,一定要保证 left < right (比如 000000 这种情况就会出现下标越界的情况)

本题思路:使用双指针来解决,一个指针 i 从 数组起始位置开始,如果 nums[i] = nums[i-1] ,i 往后走。然后定义一个 left = i + 1, right = nums.length - 1, 判断 nums[i] + nums[left] + nums[right] == 0 , 如果等于 0 就保存这三个数,并且, 在这判断过程中,有可能 nums[left] = nums[left+1], nums[right] = nums[right-1] , 此时 left 也要往后走一个,直到不等为止,right同理往前。

为了方便理解这个思路,利用示例 1:画个图来分析下代码
在这里插入图片描述

  • 循环 i = 0的时候如下图在这里插入图片描述
  • 循环 i = 1的时候在这里插入图片描述
  • 循环 i = 2的时候, 此时由于 nums[2] = nums[1]了,所以需要跳过这一循环
  • 循环 i = 3的时候在这里插入图片描述
  • 循环 i = 4的时候在这里插入图片描述
  • 循环 i = 5的时候不符合条件,结束。
  • 所以最终结果为 【-1,-1,2】【-1,0,-1】
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList();
        for (int i = 0; i < nums.length; i++) {
            // 如果第一个元素就 大于 > 0, 直接返回 res;
            if (nums[i] > 0) {
                return res;
            }
            // 去重 nums[i],这里不能用 nums[i] == nums[i+1] (-1,-1,0)
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int left = i + 1;
            int 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);
                    // 进行去重 nums[left] 和 nums[right]
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--;
                    }
                    left++;
                    right--;
                } else if (sum < 0) {
                    left++;
                } else {
                    right--;
                }
            }

        }
        return res;
    }

LeetCode 18 四数之和

在这里插入图片描述
本题思路: 延用三数之和的思想。在外层 在套 一个 for 循环。用来遍历第一个数字,里面就和 三数之和的逻辑一样了。

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        // 思路:和三数之和一样,使用双指针,只不过外面套一层 for 循环
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList();
        for(int k = 0; k < nums.length; k++){
            // 先进行剪枝操作
            if(nums[k] > target && nums[k] > 0){
                break;
            }
            // 进行去重操作
            if( k > 0 && nums[k] == nums[k-1]){
                continue;
            }
            for(int i = k+1; i < nums.length; i++){

                int left = i + 1;
                int right = nums.length - 1;
                // 先进行剪枝操作
                if( nums[k] + nums[i] > target &&  nums[k] + nums[i] > 0 ){
                    break;
                }
                // 进行去重操作
                if( i > k + 1 && nums[i] == nums[i-1]){
                    continue;
                }
                while(left < right){
                int sum = nums[k] + nums[i] + nums[left] + nums[right];
                if(sum < target){
                    left++;
                }else if(sum > target){
                    right--;
                }else{
                    // 相同记录下来
                    List<Integer> list = new ArrayList();
                    list.add(nums[k]);
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    res.add(list);
                    // 开始去重 nums[left] 和 nums[right]
                    while(left < right && nums[left] == nums[left+1]){
                        left++;
                    }
                    while(left < right && nums[right] == nums[right-1]){
                        right--;
                    }                    
                    left++;
                    right--;
                }
                }
            }
        }
        return res;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IIC使用方法

IIC模块简介 iic是stm32芯片上的一个外设 有两个外设接口 其中iic1可以重映射 iic2不可以重映射 寄存器组和内部结构 因为iic外设挂载在APB1总线上 所以时钟也是来自于APB1总线 时钟控制寄存器就是控制开关的 发送数据和接收数据都是经过了双缓冲区&#xff08;串行转行 接收 …

蓝桥杯专题-真题版含答案-【扑克牌排列】【取球博弈】【古堡算式】【泊松分酒】

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

南京航空航天大学-高等计算机网络复习

计算机网络复习 计算机网络 通信网络 网络提供信息传递服务&#xff08;端用户角度&#xff09; 通信介质&#xff1a;电子和光子&#xff0c;传输介质&#xff1a;fiber……&#xff0c;交换方式&#xff0c;协议&#xff0c;算法&#xff0c;功能&#xff0c;应用 通信网…

【DOM笔记四】事件高级!(注册/删除事件、DOM事件流、事件对象、事件委托、鼠标 / 键盘事件、相关案例)

文章目录 7 事件高级7.1 注册事件概述7.2 删除事件7.3 DOM事件流7.4 事件对象7.5 事件委托7.6 鼠标事件7.6.1 常用的鼠标事件7.6.2 鼠标事件对象 7.7 键盘事件7.7.1 常用的键盘事件7.7.2 键盘事件对象 7 事件高级 7.1 注册事件概述 给元素添加事件&#xff0c;称为注册事件或…

码住不亏!10家程序员接单平台横向对比

很多程序员都在空闲时间想要尝试接单&#xff0c;其实程序员接单在程序员圈子里非常常见&#xff0c;但想要找到一个合适的程序员接单平台却很难&#xff0c;今天给兄弟们整理了18个程序员接单平台的横向对比&#xff0c;希望可以给还在观望的小伙伴一点参考。 程序员客栈 规…

真一键关闭BitLocker!

网管小贾 / sysadm.cc 同事老莫近日喜提新电脑一台&#xff0c;遂请我周末去他家帮忙给电脑开开光。 我口送佛号欣然应允&#xff0c;心中暗道又能喝到嫂夫人的私人定制绝美养生鸡汤&#xff0c;嘿嘿&#xff0c;阿弥陀佛&#xff0c;善哉善哉&#xff01; 老莫家就租住在市中…

Python---TCP服务端程序开发

1. 开发 TCP 服务端程序开发步骤回顾 创建服务端端套接字对象绑定端口号设置监听等待接受客户端的连接请求接收数据发送数据关闭套接字 2. socket 类的介绍 导入 socket 模块import socket 创建服务端 socket 对象socket.socket(AddressFamily, Type) 参数说明: AddressF…

从0到1打造一款WebStyle串口调试工具

Tip:No Ego Some programmers have a huge problem: their own ego. But there is no time for developing an ego. There is no time for being a rockstar. Who is it who decides about your quality as programmer? You? No. The others? Probably. But can you really…

拥抱鸿蒙 - 在展讯T606平台上的探索与实践

前 言 自OpenHarmony 问世后受到了社会各界的广泛关注&#xff0c;OpenHarmony 的生态系统在如火如荼的发展。 酷派作为一家积极拥抱变化的公司&#xff0c;经过一段时间的探索与实践&#xff0c;成功实现将OpenHarmony 系统接入到展讯平台上&#xff0c;我们相信这是一个重要…

Infant-freesurfer安装和使用,适用于0-2岁婴幼儿大脑自动分割

Infant-freesurfer安装和使用 #Note https://surfer.nmr.mgh.harvard.edu/fswiki/infantFS --官网申请下载infant_recon_all --s SUBJ --age age_in_months--newborn flag (it aut

AVP摄像头与ECU交互需求规范

目录 1 文档范围及控制方法... 5 1.1 目的.... 5 1.2 文档授权... 5 1.3 文档变更管理... 5 1.4 缩写.... 5 1.5 术语.... 5 2 系统组成... 6 2.1 系统框图... 6 2.2 电源供应和时序要求... 7 2.2.1 摄像头供电控制... 7 2.2.2 摄像头上电时序要求…

Linux Centos7 安装NVIDIA 驱动

cat /etc/redhat-release 查看系统版本 服务器IP 系统版本 内核 GPU 内存和硬盘 后期扩容 10.0.2.125 CentOS Linux release 7.9.2009 5.3.10-1.el7.elrepo.x86_64 4 张 Tesla T4&#xff08;16G&#xff09; 376G 1.5T 物理机 10.0.2.130 CentOS Linux release …

消息中间件的介绍

消息中间件&#xff08;message oriented middleware&#xff09;是指支持与保障分布式应用程序之间同步/异步收发消息的中间件。消息是分布式应用之间进行数据交换的基本信息单位&#xff0c;分布式应用程序 之间的通信接口由消息中间件提供。其中&#xff0c;异步方式指消息发…

T2I-Adapter: 让马良之神笔(扩散模型)从文本生成图像更加可控

文章信息 单位&#xff1a;北大深张健团队&#xff0c;腾讯ARC lab 源码: https://github.com/TencentARC/T2I-Adapter 图1. 插个DXL的渲染图&#xff0c;这么真实的光感&#xff0c;感觉PS都可以被取代了 目录 文章信息前言一、介绍二、相关工作1.图像合成与转换2 扩散模型3 适…

多维时序 | MATLAB实现SSA-CNN-SVM麻雀算法优化卷积神经网络-支持向量机多变量时间序列预测

多维时序 | MATLAB实现SSA-CNN-SVM麻雀算法优化卷积神经网络-支持向量机多变量时间序列预测 目录 多维时序 | MATLAB实现SSA-CNN-SVM麻雀算法优化卷积神经网络-支持向量机多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | MATLAB实现…

【计算机图形学】Ditto: Building Digital Twins of Articulated Objects from Interaction

项目主页&#xff1a;Ditto: Building Digital Twins of Articulated Objects from Interaction 文章目录 1. 为什么要做这件事2. 做了件什么事3. 之前的工作&#xff08;Related work&#xff09;铰接模型估计铰接物体的3D重建隐式神经表达物理仿真中的铰接物体 4. 问题定义5…

腾讯云服务器上传文件 :Permission denied (os error 13) ,由于权限无法上传

根据网上的修改云服务器上传文件目录的权限&#xff0c;或是用root权限上传本地文件&#xff0c;均失败。 正解办法&#xff1a; ubuntu:/home/wwwroot# sudo passwd root Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully首先修…

Windows常用的功能命令

Win操作方法 快捷键winR&#xff0c;输入cmd回车&#xff0c;然后就可以输入cmd命令了&#xff0c;赶紧收藏起来&#xff0c;用的时候更方便 打开程序和功能 快捷键winR&#xff0c;输入appwiz.cpl回车 启动计算器 快捷键winR&#xff0c;输入calc回车 计算机管理 …

saas供应链批发订货系统源码整套输出的3大好处

随着电子商务的快速发展&#xff0c;越来越多的企业开始关注和采用供应链批发订货系统&#xff0c;以提高其供应链管理的管理效率和数据沉淀。现在大多企业还是使用SaaS供应链系统&#xff0c;而源码整套输出的3大好处、尤其是第三个可让企业受益匪浅。 1. 定制化能力&#xff…

Leetcode 55 跳跃游戏

题意理解&#xff1a; 非负整数数组 nums, 最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 需要跳到nums最后一个元素即为成功。 目标&#xff1a;是否能够跳到最后一个元素。 解题思路&#xff1a; 使用贪心算法来解题&#xff0c;需要理解…