查看“使用三种算法来解决Two-Sum问题”的源代码
←
使用三种算法来解决Two-Sum问题
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看和复制此页面的源代码。
https://www.bilibili.com/video/BV12V411a7xm === 题目 === 给定一个数组,给定一个数字n,求数组中是否存在两个数相加和是n 比如数组[2,4,6,7,1] === 第一种算法: === <syntaxhighlight lang="java"> public class Test1 { public boolean twoSum(int[] arr, int n) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j < i; j++) { if (arr[j] + arr[i] == n) { System.out.printf("arr[%d]=%d,arr[%d]=%d \n", j, arr[j], i, arr[i]); return true; } } } return false; } public static void main(String[] args) { int[] arr = {2,4,6,7,1}; Test1 test1 = new Test1(); test1.twoSum(arr, 10); } } </syntaxhighlight>思路: 从第i个数开始,依次尝试i之前的每一个数和i的和是否等于目标数。 时间复杂度是 O(n<sup>2</sup>/2) === 第二种算法 === <syntaxhighlight lang="java"> import java.util.HashMap; import java.util.Map; public class Test2 { public boolean twoSum(int[] arr, int n) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < arr.length; i++) { if (map.containsKey(n - arr[i])) { System.out.printf("arr[%d]=%d,arr[%d]=%d \n", map.get(n - arr[i]), n - arr[i], i, arr[i]); return true; } map.put(arr[i], i); } return false; } public static void main(String[] args) { int[] arr = {2,4,6,7,1}; Test2 test = new Test2(); test.twoSum(arr, 10); } } </syntaxhighlight>思路: 遍历数组,判断 目标数和当前数的差 是否存在于已经遍历过的元素中,不存在就将当前数放入已经遍历过的数的集合。 时间复杂度是 O(n),但还有O(n)的空间复杂度,需要字典来存放已遍历数。 === 第三种算法 === <syntaxhighlight lang="java"> public class Test3 { public boolean twoSum(int[] arr, int n) { bubbleSort(arr); System.out.print(arr[0]); for (int i = 1; i < arr.length; i++) { System.out.printf(", %d", arr[i]); } System.out.println(); //排序结束 int left = 0; int right = arr.length - 1; while (left < right) { int ret = arr[left] + arr[right]; if (ret == n) { System.out.printf("arr[%d]=%d,arr[%d]=%d \n", left, arr[left], right, arr[right]); return true; } else if (ret < n) { left++; } else if (ret > n) { right--; } } return false; } public static void bubbleSort(int[] arr) { if (arr == null || arr.length < 2) { return; } for (int e = arr.length - 1; e > 0; e--) {// 0 ~ e for (int i = 0; i < e; i++) { if (arr[i] > arr[i + 1]) { swap(arr, i, i + 1); } }//end for }//end for }//end bubbleSort public static void swap(int[] arr, int i, int j) { arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } public static void main(String[] args) { int[] arr = {2,4,6,7,1}; Test3 test = new Test3(); test.twoSum(arr, 10); } } </syntaxhighlight>思路: 首先得让数组有序——必须从左到右是从小到大,然后设置左右两个指针,让两个指针向中间移动,因为数组有序,所以左右两个指针肯定一个是从小到大移动、另一个从大到小进行移动, 左右相加小于目标数时右移小到大的左指针,左右相加大于目标数时左移大到小的右指针,直至两指针重合。 时间复杂度是O(n),空间复杂度是O(1)(left、right),但是需要对数组进行预先排序。
返回至
使用三种算法来解决Two-Sum问题
。
导航菜单
个人工具
登录
名字空间
页面
讨论
变种
视图
阅读
查看源代码
查看历史
更多
搜索
导航
首页
Spring Boot 2 零基础入门
Spring Cloud
Spring Boot
设计模式之禅
VUE
Vuex
Maven
算法
技能树
Wireshark
IntelliJ IDEA
ElasticSearch
VirtualBox
软考
正则表达式
程序员精讲
软件设计师精讲
初级程序员 历年真题
C
SQL
Java
FFmpeg
Redis
Kafka
MySQL
Spring
Docker
JMeter
Apache
Linux
Windows
Git
ZooKeeper
设计模式
Python
MyBatis
软件
数学
PHP
IntelliJ IDEA
CS基础知识
网络
项目
未分类
MediaWiki
镜像
问题
健身
国债
英语
烹饪
常见术语
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息