Two Sum

题目:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

给定一个数组,如果其中有两个值的和为target,那么就返回这两个值的下标!

一、First

我一开始的代码是这个样子:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] arr = new int[2];
        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){          
                    arr[0] = i;
                    arr[1] = j;
                }
        return arr;
    }
}

结果是可以AC的!但是总是有些不完善的地方。最原则性的错误就是没有考虑到边界条件,如果不存在这两个数呢?

然后,返回数组的代码行数不够简洁!首次修改如下:

class Solution {
    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 sum Exception");
    }
}

这样,时间复杂度为O(n^2),空间复杂度为O(1)。

OK,虽然进行了改进,但是,有思维上的一点需要改进,那就是 “nums[i] + nums[j] == target” 。我这么思考是这个原因:只要这两个数的和相加等于target!但是看了解释后,我发现他们是这么思考的“target - nums[i] == nums[j]”,这种思维指的是:目标值减去下标i代表的值会得到一个数,下面判断这个数是不是存在于这个数组中即可!虽然,一个加法和一个减法,但是思维方式是截然不同的!

class Solution {
    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(target - nums[i] == nums[j]){          
                    return new int[]{i,j};
                }
        throw new IllegalArgumentException("No sum Exception");
    }
}

二、Second

能否改进时间复杂度呢?一般通过空间换时间的方式,获得一个值对应的索引值最快的方法是通过HASH!于是,第一反应,康吃糠吃

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

有一点很重要!map.put(nums[i],i); 这里应该考虑到值的冲突问题;如果你这样写:map.put(i,nums[i]); 你运行会发现{3,3},target = 6时,就会发生错误!

这样,时间复杂度和空间复杂度都是O(n)。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值