蔡昊 - 三数之合问题

简介: 拓展:可以用集合或者二维数组,得到满足条件的三个数用双指针的技巧解决一些算法问题读者思考:第三种方案为什么不将余下数都放入set,然后去比较

package test.algorithm;

import java.util.Arrays;

import java.util.HashSet;

/**

* 三数之和问题

*

* @author CaiHao

* @since 2022/3/22 19:44

*/

public class SumOfThree {

   /**

    * 问题描述:

    * 现有一个数,问数组中是否有三个数之和,与之相等

    *

    */

   public static void main(String[] args) {

       int[] a = {2, 5, 8, 27, 13, 36};

       // 多个数来验证结果

       int[] sums = {12, 22, 23, 27, 32, 42, 57};

       Boolean hasResult;

       for (int i = 0; i < sums.length; i++) {

           hasResult = solution1(a, sums[i]);

           System.out.println(sums[i] + ":" + hasResult);

       }

   }

   /**

    * 三重循环·1

    * 特点:复杂度过高,不推荐

    * 时间复杂度O(n^3),空间复杂的O(1)

    *

    * @param a

    * @param sum

    * @return Boolean

    */

   private static Boolean solution1(int[] a, int sum) {

       int total;

       for (int i = 0; i < a.length - 2; i++) {

           for (int j = i + 1; j < a.length - 1; j++) {

               for (int k = j + 1; k < a.length; k++) {

                   total = a[i] + a[j] + a[k];

                   if (sum == total) {

                       return true;

                   }

               }

           }

       }

       return false;

   }

   /**

    * 双指针·2

    * 特点:循环少、性能好、需对数组排序

    * 时间复杂度O(n^2),空间复杂的O(1)

    *

    * @param a

    * @param sum

    * @return Boolean

    */

   private static Boolean solution2(int[] a, int sum) {

       Arrays.sort(a);

       // 低指针

       int LowPointer;

       // 高指针

       int HighPointer;

       // 总值

       int total;

       for (int i = 0; i < a.length - 2; i++) {

           LowPointer = i + 1;

           HighPointer = a.length - 1;

           // 核心:当前值固定,高值或低值移动,三值相加与sum比较

           while (HighPointer > LowPointer) {

               total = a[i] + a[LowPointer] + a[HighPointer];

               if (total == sum) {

                   return true;

               }

               // 值过大时,高值的指针左移

               else if (total > sum) {

                   HighPointer--;

               }

               // 值过小时,低值的指针右移

               else if (total < sum) {

                   LowPointer++;

               }

           }

       }

       return false;

   }

   /**

    * HashSet方案·3

    * 特点:性能较好,保留原有数组顺序

    * 时间复杂度O(n^2),空间复杂的O(n)

    *

    * @param a

    * @param sum

    * @return Boolean

    */

   private static Boolean solution3(int[] a, int sum) {

       HashSet<Integer> set = new HashSet<Integer>();

       int remain;

       int last;

       for (int i = 0; i < a.length - 1; i++) {

           set.clear();

           // 剩下两个值的和

           remain = sum - a[i];

           for (int j = i + 1; j < a.length; j++) {

               // 需要的最后一个值

               last = remain - a[j];

               // 需要的值在set集合出现过,则找到

               if (set.contains(last)) {

                   return true;

               }

               set.add(a[j]);

           }

       }

       return false;

   }

}


相关文章
|
6月前
|
机器学习/深度学习 自然语言处理 算法
AI 世界生存手册(一):从LR到DeepSeek,模型慢慢变大了,也变强了
大家都可以通过写 prompt 来和大模型对话,那大模型之前的算法是怎样的,算法世界经过了哪些比较关键的发展,最后为什么是大模型这条路线走向了 AGI,作者用两篇文章共5.7万字详细探索一下。
AI 世界生存手册(一):从LR到DeepSeek,模型慢慢变大了,也变强了
|
4月前
|
JavaScript 前端开发 中间件
除了 Pinia,还有哪些状态管理库可以实现类似的中间件功能?
除了 Pinia,还有哪些状态管理库可以实现类似的中间件功能?
233 73
|
7月前
|
数据可视化 算法 数据挖掘
用傅里叶变换解码时间序列:从频域视角解析季节性模式
本文介绍了如何使用傅里叶变换和周期图分析来识别时间序列中的季节性模式,特别是在能源消耗数据中。通过Python实现傅里叶变换和周期图,可以有效提取并量化时间序列中的主要和次要频率成分,克服传统可视化分析的局限性。这对于准确捕捉时间序列中的季节性变化具有重要意义。文章以AEP能源消耗数据为例,展示了如何应用这些方法识别日、周、半年等周期模式。
316 3
用傅里叶变换解码时间序列:从频域视角解析季节性模式
|
存储 监控 Linux
在Linux中,什么是 inode ?
在Linux中,什么是 inode ?
|
人工智能 供应链 大数据
云上智能物流:重塑物流行业的未来图景
随着全球化的深入推进,云上智能物流将更加注重全球化布局。通过构建跨国界的物流网络和信息系统,实现全球范围内的物流信息共享和资源整合,提高全球物流效率和服务水平。
|
自然语言处理 索引
技术写作最佳实践与策略指南
作为一名技术写作者,遵守既定的最佳实践有助于确保您的工作的一致性、清晰性和整体质量。一些常见的最佳实践包括: 始终考虑受众: 牢记用户视角编写内容。确保技术术语、语言和复杂程度与您的目标读者相匹配。 逻辑地组织内容: 将材料分为章节、子章节、项目符号列表和表格。使用标题帮助读者浏览内容。 必要时使用图表和图像: 视觉辅助工具通常可以提高对复杂概念或过程的理解。 写出清晰简洁的句子: 避免使用读者可能不明白的模糊信息和术语。始终追求可读性。 编辑、编辑、编辑: 校对您的工作,纠正语法和拼写错误,并确保信息准确且最新。 遵循这些最佳实践可以提高您的技术写作效率,并确保您的受众能够轻松理
1364 0
C++11实用技术(二)std::function和bind绑定器
C++11实用技术(二)std::function和bind绑定器
202 0
|
缓存 JSON 数据格式
HTTP-Header中常见的字段有哪些
HTTP-Header中常见的字段有哪些
|
存储 小程序 关系型数据库
【Navicat提示】:Access violation at address0000000a1063 in module‘navicat.exe‘. Read of address000000058
【Navicat提示】:Access violation at address0000000a1063 in module‘navicat.exe‘. Read of address000000058
1133 0