1. 两数之和

本文解析了两数之和问题的两种解法,一是直接双重循环遍历,时间复杂度O(n^2),二是使用Map集合存储元素值与下标,通过一次遍历查找,时间复杂度降为O(n)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解法

方法1

直接双重循环遍历数组,查找和值为 target 的两个元素
时间复杂度o(n2)

方法2

用Map集合把作为参数的数组存起来,数组中元素的值作为键Key,而对应的元素下标作为值Value。遍历一次数组(找出一个元素),并同时在Map集合中找另一个,Map集合查找的时间复杂度是o(1),这样整体的时间复杂度就降到了 o(n) 线性阶,最后将数组中找到的其中一个元素的下标,和Map集合中另一个元素(键)作为集合 get() 方法的参数得到的值即元素在原数组中的位置存在数组中返回

代码实现

方法1

public int[] twoSum(int[] nums, int target) {
		int[] arr = new int[2];
		for (int i = 0; i < nums.length; i++) {
	        for (int j = i + 1; j < nums.length; j++) {
	        	if (nums[i] + nums[j] == target) {
	            	arr[0] = i;
	            	arr[1] = j;
	            	return arr;
	            }
	        }
	    }
	    throw new IllegalArgumentException("No two sum solution");
	}

注:方法中返回数组的语句可以直接写成:

return new int[] { i, j };

这样将原来的四句代码变为了一句

时间复杂度:o(n2)
空间复杂度:o(1)

方法2

第一段: 先存再找

public int[] twoSum(int[] nums, int target) {
	    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
	    for (int i = 0; i < nums.length; i++) {
	        map.put(nums[i], i);//先遍历一遍数组,将数组全部放入Map集合中
	    }
	    for (int i = 0; i < nums.length; i++) {//开始找了,先遍历数组
	        if (map.containsKey(target - nums[i]) && map.get(target - nums[i]) != i) {
	        //直接在集合中找符合条件的元素
	            return new int[] { i, map.get(target - nums[i]) };
	        }
	    }
	    throw new IllegalArgumentException("No two sum solution");
	}

第二段: 边存边找

public int[] twoSum(int[] nums, int target) {
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
	    for (int i = 0; i < nums.length; i++) {//只遍历一次数组
	        if (map.containsKey(target - nums[i])) {//在集合中找符合条件的元素
	            return new int[] { map.get(target - nums[i]), i };
	        }
	        map.put(nums[i], i);//将数组中的元素存入集合
	    }
	    throw new IllegalArgumentException("No two sum solution");
	}

时间复杂度:o(n)
空间复杂度:o(n)

对比两种方法,要不浪费空间只好牺牲速度,而要提高效率就会牺牲空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值