力扣#哈希表 两数之和

题目:

 示例&提示:

 

>所属知识点:哈希表(题解二)


题解1:暴力枚举:

可以通过两个循环遍历整个数组找出和为target的整数:

public class twoSum {

	public int[] twoSum(int[]nums,int target) {
		int len = nums.length;
		for(int i = 0;i < len - 1;i++) {     
			for(int j = i + 1;j < len;j++) {
				if(nums[i] + nums[j] == target) {
					return new int[] {i,j}; //返回包含两个索引的新数组
				}
			}
		}

        //遍历完所有可能组合后仍无解,抛出异常,异常表示无解
		throw new IllegalArgumentException("no two sum solution."); 
                    //抛出不合法或无效参数的异常类。异常处理放双层for循环外面
	}

}

可以看出时间复杂度为O(N^2),空间复杂度为O(1)。但是,我们能不能想出一个时间复杂度小于O(N^2)的算法呢?

那么接下来就来到我们的题解二:哈希表


题解二:哈希表:

对哈希表这个知识点不熟悉的可以参考这篇文章,通俗易懂:通俗易懂->哈希表详解-CSDN博客

简单来说,哈希表的作用就是:假设你有一本电话本,你想要查找张三的电话号码(12345678910),当你想要找到张三的电话号码时,不需要一页一页翻直接查名字就能立刻找到号码。哈希表就是这种【快速查字典】的结构:

· Key(键) ——>  类似电话本中的[【名字】,如数字2

· Value(值) ——> 类似电话本中的[【号码】,如数字2的索引0

· 存入数据用hashtable.put(key,value);查找数据用hashtable.containsKey(key)判断是否存在

回归题目:

这里用了补数的思想,而非凑数的方法。

遍历数组查找是否存在【补数 target-nums[i]】 :

①如果补数不存在,则将当前数字及其索引存入哈希表中,以供后续元素查询;

②如果补数已经存在于哈希表中,说明找到了两个数的和为target,直接返回它俩的索引。

public class twoSum {

	public int[] twoSum(int[]nums,int target) {
		Map<Integer,Integer> hashTable = new HashMap<>(); //初始化哈希表,哈希表此时为空
		for(int i = 0;i < nums.length;i++) {
			if(hashTable.containsKey(target-nums[i])) { //检查补数是否存在
				return new int[] {hashTable.get(target-nums[i]),i}; //补数存在则返回两个数的索引
			}
			hashTable.put(nums[i], i);//补数不存在,则存储当前数字及其索引至哈希表中,以供后续元素查询
		}
		throw new IllegalArgumentException("no two sum solution");
	}

}

图解:

 

时间复杂度降到O(N),只需遍历一次数组,每次查询补数只需O(1)时间;空间复杂度升到O(N),其中N是数组中的元素数量。主要为哈希表的开销。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值