乘风破浪:LeetCode真题_001_TwoSum
乘风破浪:LeetCode真题_001_TwoSum
一、前言
沉寂了很长时间,也悟出了很多的道理,写作是一种业余的爱好,是一种自己以后学习的工具,是对自己过往的经验积累的佐证,是检验自己理解深入度的方法。在前面的模块之中,我们已经将基本的编程知识、数据结构、设计模式、应用框架、各种优化烂熟于心了,对程序开发有了一定的理解,但是编程的功力是一种水磨的功夫,需要问题,也需要思考,最重要的是需要自己用心的去打出代码,在这个过程中经验、技巧、熟练度、思考力都是非常重要的,因此我们通过LeetCode上的一些题目来锻炼一下这方面的能力。
二、LeetCode真题_001_TwoSum
2.1 题目

2.2 分析与解决
其实从问题我们就可以看出,这是类似于helloworld的一个题目,比较简单,借以引导我们从不同的角度使用不同的方法去解决问题。最简单的想法就是暴力破解方法,通过穷举所有的情况来解决问题,但是代价是时间复杂度O(n~2),空间复杂度O(1)。那么有没有其他方法呢,于是我们想到了hash表的方法,用空间换时间,通过一次遍历就能找到所有的可能结果。
通过暴力算法来解决:

public int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] == target - nums[i]) {
return new int[] { i, j };
}
}
}
throw new IllegalArgumentException("No two sum solution");
}
通过hash算法来解决,又分为两次for循环和一次for循环:

public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement) && map.get(complement) != i) {
return new int[] { i, map.get(complement) };
}
}
throw new IllegalArgumentException("No two sum solution");
}

public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[] { map.get(complement), i };
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
}
来看看我们的算法:
import java.util.Arrays;
public class Solution {
private static class Node implements Comparable<Node> {
int val;
int idx;
public Node() {
}
public Node(int val, int idx) {
this.val = val;
this.idx = idx;
}
@Override
public int compareTo(Node o) {
if (o == null) {
return -1;
}
return this.val - o.val;
}
}
/**
* 题目大意
* 给定一个整数数组,找出其中两个数满足相加等于你指定的目标数字。
* 要求:这个函数twoSum必须要返回能够相加等于目标数字的两个数的索引,且index1必须要小于index2。
* 请注意一点,你返回的结果(包括index1和index2)都不是基于0开始的。你可以假设每一个输入肯定只有一个结果。
*
* 解题思路
* 创建一个辅助类数组,对辅助类进行排序,使用两个指针,开始时分别指向数组的两端,看这两个下标对应的值是否
* 等于目标值,如果等于就从辅助类中找出记录的下标,构造好返回结果,返回。如果大于就让右边的下标向左移,
* 进入下一次匹配,如果小于就让左边的下标向右移动,进入下一次匹配,直到所有的数据都处理完
*/
public int[] twoSum(int[] nums, int target) {
int[] result = {0, 0};
Node[] tmp = new Node[nums.length];
for (int i = 0; i < nums.length; i++) {
tmp[i] = new Node(nums[i], i);
}
Arrays.sort(tmp);
int lo = 0;
int hi = nums.length - 1;
while (lo < hi) {
if (tmp[lo].val + tmp[hi].val == target) {
if (tmp[lo].idx > tmp[hi].idx) {
result[0] = tmp[hi].idx ;
result[1] = tmp[lo].idx ;
} else {
result[0] = tmp[lo].idx ;
result[1] = tmp[hi].idx ;
}
break;
} else if (tmp[lo].val + tmp[hi].val > target) {
hi--;
} else {
lo++;
}
}
return result;
}
}
这种想法也比较巧妙,先对所有元素进行排序,然后通过定义首尾两个指针来不断地逼近最后的和,直至遍历完成,非常的巧妙,时间复杂度O(n),空间复杂度O(n)。不过也增加了额外的创建对象的空间。


三、总结
通过这个简单的问题,我们明白了对于一件事情,要么使用时间换取空间,要么使用空间换取时间,最后达到我们想要的结果,往往通过空间换取时间的比较多,因此hash算法就变得非常的重要了,当然也有其他的算法。
乘风破浪:LeetCode真题_001_TwoSum的更多相关文章
- 乘风破浪:LeetCode真题_041_First Missing Positive
乘风破浪:LeetCode真题_041_First Missing Positive 一.前言 这次的题目之所以说是难,其实还是在于对于某些空间和时间的限制. 二.First Missing Posi ...
- 乘风破浪:LeetCode真题_040_Combination Sum II
乘风破浪:LeetCode真题_040_Combination Sum II 一.前言 这次和上次的区别是元素不能重复使用了,这也简单,每一次去掉使用过的元素即可. 二.Combination Sum ...
- 乘风破浪:LeetCode真题_039_Combination Sum
乘风破浪:LeetCode真题_039_Combination Sum 一.前言 这一道题又是集合上面的问题,可以重复使用数字,来求得几个数之和等于目标. 二.Combination Sum ...
- 乘风破浪:LeetCode真题_038_Count and Say
乘风破浪:LeetCode真题_038_Count and Say 一.前言 这一道题目,很类似于小学的问题,但是如果硬是要将输入和结果产生数值上的联系就会产生混乱了,因此我们要打破思维定势. ...
- 乘风破浪:LeetCode真题_037_Sudoku Solver
乘风破浪:LeetCode真题_037_Sudoku Solver 一.前言 这次我们对于上次的模型做一个扩展并求解. 二.Sudoku Solver 2.1 问题 2.2 分析与解决 这道题 ...
- 乘风破浪:LeetCode真题_036_Valid Sudoku
乘风破浪:LeetCode真题_036_Valid Sudoku 一.前言 有的时候对于一些基础知识的掌握,对我们是至关重要的,比如ASCII重要字符的表示,比如一些基本类型的长度. 二.Valid ...
- 乘风破浪:LeetCode真题_035_Search Insert Position
乘风破浪:LeetCode真题_035_Search Insert Position 一.前言 这次的问题比较简单,也没有限制时间复杂度,但是要注意一些细节上的问题. 二.Search Insert ...
- 乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array
乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array 一.前言 这次我们还是要改造二分搜索,但是想法却 ...
- 乘风破浪:LeetCode真题_033_Search in Rotated Sorted Array
乘风破浪:LeetCode真题_033_Search in Rotated Sorted Array 一.前言 将传统的问题进行一些稍微的变形,这个时候我们可能无所适从了,因此还是实践出真知, ...
随机推荐
- jsf和facelets的生命周期
一.JSF生命周期 JSF是基于事件驱动.JSF生命周期分为两个主要阶段:执行阶段和渲染阶段. 1.执行阶段 分为六个阶段: 恢复视图阶段 当客户端请求一个JavaServer Faces页面时,Ja ...
- java几个经典的算法题目----------查询子串和等于已知数字
给出一个排序好的数组和一个数,求数组中连续元素的和等于所给数的子数组 public class testClockwiseOutput { public static void main(String ...
- 重温js基础部分
临近面试,因此打算回过头来巩固一下js的一些基础部分,同时也是为了记录自己的一些比较薄弱的点. 1.typeof操作符 typeof返回一个基本数据类型,包括number,string,boolean ...
- jquery 选择唯一值 选择器“”非“用法
$(document).ready(function () { $("#addwork").hide(); $(".xi").click(function(){ ...
- 远程连接MongoDB数据库
不使用用户名和密码 安装MongoDB后,默认不使用用户名和密码即可在本地登录,如需远程登录,只要修改/bin/mongo.conf文件即可
- kinect 深度图像去噪算法
算法设计思路 (1)读取16位深度图像到待处理图像帧组: (2)ROI区域计算 由于kinect 彩色摄像头和红外深度摄像头是存在视角偏差的,经过视角对齐后,得到的深度图像是有黑边的.此处通过取帧组第 ...
- JDBC数据库连接池
用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库 ...
- SQL导出到Excel 存储过程
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_exporttb]') and OBJECTPROPER ...
- Thymeleaf学习记录(4)--$/*/#/@语法
表达式符号 Thymeleaf对于变量的操作主要有$\*\#三种方式: 变量表达式: ${...},是获取容器上下文变量的值. 选择变量表达式: *{...},获取指定的对象中的变量值.如果是单独的对 ...
- 在 Ubuntu上使用 MySQL
MySQL 安装配置 https://help.ubuntu.com/12.04/serverguide/mysql.html MySQL Manual http://dev.mysql.com/do ...