算法问题:两数之和一些学习心得

算法问题:两数之和一些学习心得

代码使用Java开发
今天在力扣上学习了两数之和这一简单的算法问题,对不同的方法进行了学习和理解,下面是一些学习心得及代码:

问题介绍

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一种:暴力方法

思路

首先看到题,我们会优先考虑到使用暴力方法进行解决,这个题本身也限制了结果为一个两个数据的数组,所以我们不需要考虑太多其它问题,先跑一遍暴力方法,使用两个for对数组分别遍历,计算结果如果满足两数之和等于目标值,那么输出这个数组。代码如下:

class Solution {
    public int[] twoSum(int[] nums, int target) {
		for(int i = 0; i<nums.length; i++){
			for(int j = 0;j<nums.length;j++){
				if(i!=j){//保证不会出现重复索引的值之和为目标值
					if((nums[i]+nums[j])==target){
						return new int[]{i,j};
					}
				}
			}
		}
		return new int[0];
    }
}

我们不假思索的写完了这些通俗易懂的代码,下面我们在对其进行优化。
首先我们考虑到,两个for嵌套进行循环,会把整个nums数组进行两次全部遍历,于是我们分析代码内容得知,
在这里插入图片描述
我们第二次遍历的时候,会与第一次出现上述的重复情况,所以,我们第二次for的时候,让j的位置直接移到i的后一位,这样不仅解决了重复情况的出现,还可以去掉第二次for中通过if来防止索引重复的问题,于是,优化后的代码如下:

class Solution {
    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[i]+nums[j])==target){
					return new int[]{i,j};
				}
			}
		}
		return new int[0];
    }
}

第二种:哈希法

都说是哈希法了肯定就要用HashMap了,这里的思维就是减少暴力方法中对数据的重复计算,这里我们直接上代码来说:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class 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};
            }else{
            	map.put(nums[i], i);
            }
		}
		return new int[0];
    }
}

这里我们先提供一部分的函数说明:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
了解了这些方法之后,我们对代码也有了一个大致的了解。
首先在方法开始,我们创建了一个名为map的HashMap对象,key和value的类型都为int型,因为我们需要查询的key是nums相应的数值而不是索引,因此我们的key储存的是nums中的值,而value相对应的就是储存序列了。
在代码中我们只进行了一次for循环,在for循环内,我们先通过if语句判断map中是否含有target-nums[i]的值,到这里可能就有群众要问了,为什么这里要这样判断,这里我们后面会赘述,先继续看代码,当if判断没有target-nums[i]后,则给map中新增了当前nums[i]的值和索引,这样我们在后面的循环中就可以获取到这个nums[i]了,因此,就可以保证

当前循环的值+(target-当前循环的值)==target

这里的(target-当前循环的值)就是之前储存过的nums[i],因此即可得到问题所需要的结果,接下来我们只需要在if语句中输出对应的结果即可。

了解了这些原理,我们再换一下储存内容做一下知识的巩固,也就是把储存进map的值变成(target-nums[i])把需要查询的key变成nums[i],下面是答案,认真理解并手动写过以后再看哦~

答案:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class 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(nums[i])) {
                return new int[]{map.get(nums[i]), i};
            }else{
            	map.put(target - nums[i], i);
            }
		}
		return new int[0];
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值