【java算法专场】双指针(下)

news2024/9/28 9:28:39

611. 有效三角形的个数

目录

611. 有效三角形的个数

算法思路

算法代码

LCR 179. 查找总价格为目标值的两个商品

算法思路

 算法代码

HashSet

双指针

15. 三数之和

算法思路

算法代码 

18. 四数之和

​编辑算法思路

算法代码 


611. 有效三角形的个数

算法思路

 

算法代码

/**
     * 计算可能的三角形数量。
     *
     * @param a 一个整数数组,数组中的元素代表三角形的边长。
     * @return 返回可能构成的三角形的数量。
     */
    public int triangleNumber(int[] a) {
        // 如果数组为空,则无法构成任何三角形
        if(a.length==0) return 0;

        // 对数组进行排序,以便后续通过比较边长来判断是否可以构成三角形
        Arrays.sort(a);//给数组排序

        // 初始化计数器,用于记录可以构成的三角形的数量
        int count=0;// 用来计算三角形个数

        // 从最长的边开始检查,逐步减少边长,以找到所有可能的三角形组合
        int n= a.length-1;
        while(n>=2){
            // 使用双指针技术,左指针指向最短边,右指针指向最长边,中间的边长由数组排序决定
            int left=0;
            int right=n-1;
            while(left<right){
                // 如果当前选择的三条边满足构成三角形的条件,则增加计数器,并移动右指针
                // 如果a+b大于c,那么此时可以构成三角形,且在【left,right】内的所有情况都可以构成三角形
                //count+=right-left,right--
                if(a[left]+a[right]>a[n]){
                    count+=right-left;
                    right--;
                }else{
                    // 如果不满足条件,则移动左指针,尝试其他可能的边长组合
                    // 如果a+b小于c,那么此时无法构成三角形,让left++
                    left++;
                }
            }
            // 检查完一组边长后,减少最长边的长度,继续检查下一组
            //当判断完后,让n--
            n--;
        }
        // 返回可以构成的三角形的总数量
        return count;
    }

LCR 179. 查找总价格为目标值的两个商品

算法思路

 

 算法代码

HashSet

 public int[] twoSum(int[] price, int target) {
         Set<Integer> set=new HashSet<>();
         int i=0;
         for(;i<price.length;i++){
             if(set.contains(target-price[i])){
                 return new int[]{target-price[i],price[i]};
             }else{
                 set.add(price[i]);
             }
         }
         return new int[]{-1,-1};
    }

双指针

/**
     * 使用双指针方法查找数组中两个数的和等于特定目标值的索引。
     * 这个方法避免了对每个可能的组合进行显式的迭代,通过调整左右指针来缩小搜索范围。
     *
     * @param a 输入的整数数组。
     * @param target 目标值,我们需要找到两个数的和等于这个值。
     * @return 包含这两个数索引的数组。如果不存在这样的两个数,则返回{-1, -1}。
     */
    public int[] twoSum(int[] a, int target) {
        // 初始化左指针为数组的起始位置
        // 利用双指针
        int left = 0;
        // 初始化右指针为数组的结束位置
        int right = a.length - 1;
        // 当左指针小于右指针时,执行循环
        while (left < right) {
            // 计算当前左右指针所指元素的和
            int sum = a[left] + a[right];
            // 如果和大于目标值,移动右指针,减小和
            if (sum > target) {
                right--;
            }
            // 如果和小于目标值,移动左指针,增大和
            else if (sum < target) {
                left++;
            }
            // 如果和等于目标值,返回当前左右指针的索引
            else {
                return new int[]{a[left], a[right]};
            }
        }
        // 如果没有找到合适的组合,返回{-1, -1}
        return new int[]{-1, -1};
    }

15. 三数之和

算法思路

算法代码 

    /**
     * 寻找数组中所有不重复的三元组,这些三元组的和为零。
     * 
     * @param nums 输入的整数数组
     * @return 返回一个列表,包含所有和为零的不重复三元组
     */
    public List<List<Integer>> threeSum(int[] nums) {
        // 初始化结果列表
        List<List<Integer>> res = new ArrayList<>();
        // 如果数组长度小于3,无法找到满足条件的三元组,直接返回空列表
        if (nums.length < 3) {
            return res;
        }
        // 初始化指针k,用于遍历数组
        int k = 0;
        // 遍历数组,直到k指向的元素后至少还有两个元素
        for (; k < nums.length - 2;) {
            // 初始化左指针left,指向k后的第一个元素
            int left = k + 1;
            // 初始化右指针right,指向数组最后一个元素
            int right = nums.length - 1;
            // 计算目标值,即要找到的三个数的和,这里取当前k指向的数的相反数
            int target = -nums[k];
            // 当左指针小于右指针时,进行循环
            while (left < right) {
                // 计算当前左指针和右指针指向的数的和
                int sum = nums[left] + nums[right];
                // 如果和大于目标值,说明右指针太靠右,需要向左移动
                if (sum > target) {
                    right--;
                }
                // 如果和小于目标值,说明左指针太靠左,需要向右移动
                else if (sum < target) {
                    left++;
                }
                // 如果和等于目标值,找到了一个满足条件的三元组
                else {
                    // 将这个三元组添加到结果列表中
                    res.add(Arrays.asList(nums[k], nums[left], nums[right]));
                    // 移动左指针和右指针,继续寻找下一个满足条件的三元组
                    left++;
                    right--;
                    // 跳过所有与当前左指针指向的数相同的元素,避免重复
                    while (left < right && nums[left] == nums[left - 1]) {
                        left++;
                    }
                    // 跳过所有与当前右指针指向的数相同的元素,避免重复
                    while (left < right && nums[right] == nums[right + 1]) {
                        right--;
                    }
                }
            }
            // 移动k指针,继续寻找下一个可能的三元组
            k++;
            // 跳过所有与当前k指针指向的数相同的元素,避免重复
            while (k < nums.length - 2 && nums[k] == nums[k - 1]) {
                k++;
            }
        }
        // 返回结果列表
        return res;
    }

18. 四数之和

算法思路

考虑下面这种情况,我们需要给aim使用 long类型,并将target也强转为long

算法代码 

 /**
     * 寻找数组中所有不重复的四个数,使得它们的和等于指定的目标数。
     *
     * @param nums 输入的整数数组。
     * @param target 目标和。
     * @return 返回一个列表,包含所有满足条件的四个数的组合。
     */
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        // 如果数组长度小于4,无法找到四个数的组合,直接返回空结果
        if (nums.length < 4) {
            return res;
        }
        Arrays.sort(nums);
        // 双层循环遍历数组,第一层循环选择第一个数,第二层循环选择第二个数
        for(int t=0;t<nums.length-3;){
            for(int k=t+1;k<nums.length-2;){
                // 计算剩余两个数的目标和
                long aim=(long)target-nums[t]-nums[k];
                // 使用双指针法寻找剩余的两个数
                int left=k+1;
                int right=nums.length-1;
                // 当左指针小于右指针时,执行循环
                while(left<right){
                    // 当前两个数的和
                    int sum=nums[left]+nums[right];
                    // 如果当前和小于目标和,左指针右移
                    if(aim>sum) left++;
                    // 如果当前和大于目标和,右指针左移
                    else if(aim<sum) right--;
                    // 如果当前和等于目标和,将四个数的组合添加到结果中
                    else {
                        res.add(Arrays.asList(nums[t],nums[k],nums[left],nums[right]));
                        // 移动左指针和右指针,避免重复组合
                        left++; right--;
                        // 跳过所有与前一个数相同的数,避免重复组合
                        while(left<right && nums[left]==nums[left-1]) left++;
                        while(left<right && nums[right]==nums[right+1]) right--;
                    }
                }
                // 移动第二个数的指针,避免重复组合
                k++;
                while(k<nums.length-2 && nums[k]==nums[k-1]) k++;
            }
            // 移动第一个数的指针,避免重复组合
            t++;
            while(t<nums.length-3 && nums[t]==nums[t-1]) t++;
        }
        return res;
    }

 以上就是双指针专题篇的内容,若有不足,欢迎指正~

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

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

相关文章

echarts无法加载Map地图的问题

项目场景&#xff1a; echarts无法加载Map地图的问题 详情 查阅相关资料讲&#xff0c;echarts4.9以上版本已经移除了map&#xff0c;那么我们就得重新打包echarts文件了。打包echarts.min.js的链接&#xff1a;https://echarts.apache.org/zh/builder.html 在这个链接页面可…

CTFShow的36D杯

神光 还是想了一下&#xff0c;但那个异或搞不出来&#xff0c;都是对dword_41A038操作&#xff0c;想起开头就给了 key &#xff0c;还有反调试应该是要调试的 输出的应该就是 flag &#xff0c;只是为什么是乱码呢&#xff1f; 放 od 再试试&#xff0c;直接就出 flag 了&am…

对比:9款最佳个人项目管理软件盘点

文章介绍了9款个人项目管理软件&#xff1a;PingCode、Worktile、Flowus、Todoist、Trello、Teambition、有道云笔记、Notion、Microsoft To Do。 在管理个人项目时&#xff0c;是否常感到信息零散、进度难以把控&#xff1f;选择合适的项目管理软件&#xff0c;可以有效解决这…

关于解决双屏幕鼠标移动方向问题

1.点开设置》系统》屏幕 2.分清屏幕标识&#xff0c;一般笔记本为1 3.点击要移动的屏幕&#xff0c;然后按住鼠标左键不方进行移动 感谢您的浏览&#xff0c;希望可以帮到您&#xff01;

【探索Linux】P.38(传输层 —— TCP协议通信连接管理机制简介 | TCP连接状态转换)

阅读导航 引言一、TCP协议通信连接管理机制二、连接状态转换1. TCP状态转换图2. 状态转换过程3. 理解TIME_WAIT状态&#xff08;1&#xff09;目的和作用&#xff08;2&#xff09;状态转换&#xff08;3&#xff09;特殊情况&#xff08;4&#xff09;影响和优化 4. 理解 CLOS…

医疗器械的售后与服务探讨

彩虹医械维修培训 8月长期班报名啦 学技术 考证书 技术支持 大型医疗设备的宕机不仅会造成医疗机构直接的巨额经济损失&#xff0c;宕机期间的损失甚至可以超过维修费用&#xff0c;而且还可能会耽误患者的病情检查&#xff0c;因此对医疗设备的定期保养已经成为各级医院的…

学生选课管理系统(Java+MySQL)

技术栈 Java: 用于实现系统的核心业务逻辑。MySQL: 作为关系型数据库&#xff0c;用于存储系统中的数据。JDBC: 用于Java程序与MySQL数据库之间的连接和交互。Swing GUI: 用于创建图形用户界面&#xff0c;提升用户体验。 系统功能 我们的学生选课管理系统主要针对学生和管理…

SQL中on和where的区别

SQL中on和where的区别   前言&#xff0c;在工作写SQL使用中&#xff0c;在涉及到多个表的关联时&#xff0c;既可以通过on进行数据过滤&#xff0c;又可以使用where进行数据过滤&#xff0c; 确实有点不太了解这两个关键字在left join后的区别&#xff0c;所以就去查了些资…

从产业链视角审视工作

从产业链视角审视工作&#xff1a;定位、价值与成长 作为一名技术博客博主&#xff0c;我经常收到各种关于职业发展、技术成长和学习路径的问题。最近&#xff0c;我看了一份学习报告&#xff0c;其中提到了一种非常有趣且实用的视角——从产业链的角度去审视自己的工作。这种视…

【实战指南】揭秘Pandas:从零开始掌握数据处理与分析的超级工具箱

目录 Series 创建 Series 访问数据 DataFrame 创建 DataFrame 读取 CSV 文件 写入 CSV 文件 基本操作 查看前几行: 查看后几行: 描述性统计: 选择列: 选择行: 条件筛选: 排序: 合并数据: Pandas 是一个强大的 Python 库&#xff0c;主要用于数据分析和数据处理…

【INTEL(ALTERA)】为什么我使用 PIO 边缘捕获中断的 Nios® II 设计不能正常工作?

目录 说明 解决方法 说明 当用户选择了不正确的边缘捕获设置&#xff0c;从而阻止触发中断时&#xff0c;可能会出现此问题。 在 PIO&#xff08;并行 I/O&#xff09;英特尔 FPGA IP内核中&#xff0c;如果“启用单个位设置/清除”选项被关闭&#xff0c;则将任何值写入边…

智驭未来:人工智能与目标检测的深度交融

在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;如同一股不可阻挡的浪潮&#xff0c;正以前所未有的速度重塑着我们的世界。在众多AI应用领域中&#xff0c;目标检测以其独特的魅力和广泛的应用前景&#xff0c;成为了连接现实与智能世界的桥梁。本文旨在…

精讲:java之多维数组的使用

一、多维数组简介 1.为什么需要二维数组 我们看下面这个例子&#xff1f;“ 某公司2022年全年各个月份的销售额进行登记。按月份存储&#xff0c;可以使用一维数组。如果改写为按季度为单位存储怎么办呢&#xff1f; 或许现在学习了一维数组的你只能申请四个一维数组去存储每…

探索Kotlin:从K1到K2

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 嘿&#xff0c;小伙伴们&#xff01;今天我们来聊聊Kotlin&#xff0c;这个在安卓开发圈里越来越火的编程语言。…

轴心轨迹的绘制(包含降噪前处理,MATLAB)

由于旋转机械振动波形的噪声干扰大&#xff0c;直接对振动数据特征提取和选择的故障诊断方法&#xff0c;其精度容易受到噪声影响。当前&#xff0c;基于图像的旋转机械故障诊断技术已经得到飞速的发展。针对旋转机械的故障诊断问题&#xff0c;传统方法趋向于从振动数据中提取…

用6000万茅台案,了解什么是外挂?

近日&#xff0c;一起涉案金额高达6000余万元的案件出现在人们视野中。此前浙江丽水云和县公安局侦破了一起非法利用软件抢购电商平台茅台酒案。 据了解&#xff0c;犯罪嫌疑人以非法牟利为目的&#xff0c;开发了抢购软件&#xff0c;以有偿原价抢购电商平台飞天茅台酒为噱头&…

android13 rom frameworks 蓝牙自动接收文件

总纲 android13 rom 开发总纲说明 目录 1.前言 2.源码查找 3.我们先实现第一种改法 4.实现第二种改法 5.第三种改法代码参考 6.编译测试 1.前言 我们从导航栏这里,点开这个蓝牙的接收框,弹出来的对话框,使用android studio 的layout inspector可以发现这个是 Bluetoo…

如何用IP地址申请SSL证书实现网络安全

互联网是一个全球性的网络&#xff0c;它将世界各地的计算机系统和设备连接在一起。在这个庞大的网络中&#xff0c;每个设备都需要一个唯一的标识符&#xff0c;即IP&#xff08;Internet Protocol&#xff09;地址&#xff0c;以便其他设备能够找到并与其通信。然而&#xff…

解密 AI 客服:LangChain+ChatGPT 打造智能客服新时代

你需要了解 ChatGPT ChatGPT 是 OpenAI 开发的一种基于人工智能技术的自然语言处理模型。它可以通过对大量文本数据进行训练&#xff0c;自动生成高质量的回答和对话。ChatGPT 具有高效、准确、自然的特点&#xff0c;可以帮助人们更加高效地处理信息和交流。 ChatGPT 有很多…

硅纪元视角 | 电信公司出招!AI机器人全面反击AI诈骗电话

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…