leetcode twosum java_LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY...

题目:

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.

翻译:

给定一组整数,两个数字的返回索引,它们的和会等于一个特定的数。

您可能假设每个输入都有一个解决方案,但是你不能使用同一个元素两次。(好吧一开始英语弱鸡的我也没懂,后来编程的时候想到的解释:同一个数不能通过自加而得到目标数)

第一遍编写:74ms

classSolution {public int[] twoSum(int[] nums, inttarget) {

Set resultSet = new HashSet();for (int i = 0; i < nums.length; i++) {for (int j = i + 1; j < nums.length; j++) { //就是这里想到一个数自加,所以应该从i+1开始。

if (nums[i] + nums[j] ==target) {

resultSet.add(i);

resultSet.add(j);

}

}

}int[] result = new int[resultSet.size()];for (int i = 0; i < result.length; i++) {

result[i]=(Integer) resultSet.toArray()[i];

}returnresult;

}

}

好吧,第一次刷题,隐隐小激动,一开始确实没看清题目。。

看清题目后第一次:46ms    时间复杂度:O(n2)

1 classSolution {2 public int[] twoSum(int[] nums, inttarget) {3 int[] result = new int[2];4 for (int i = 0; i < nums.length; i++) {5 for (int j = i + 1; j < nums.length; j++) {6 if (nums[i] + nums[j] ==target) {7 result[0] =i;8 result[1] =j;9 break;10 }11 }12 }13 returnresult;14 }15 }

自己看着都觉得菜的很。。竟然用了嵌套for。。

下面是参考答案:12ms    时间复杂度:O(n)

1 public int[] twoSum(int[] nums, inttarget) {2 Map map = new HashMap();3 int[] result = new int[2];4

5 for (int i = 0; i < nums.length; i++) {6 if (map.containsKey(target -nums[i])) {7 result[0] = map.get(target -nums[i]);8 result[1] = i; //此时 i 对应的元素还没有放进去。

9 returnresult;10 }11 map.put(nums[i], i);12 }13 returnresult;14 }

原来用了HashMap来定位两者有某种关系的数。。快了一倍多。。

结论:

当需要使用嵌套for循环来查找或者定位的时候,尽量优先考虑是否能使用Map(存储每一个值作为key,相应下标作为value)

使用  map.containsKey(__) 方法来进行定位

2018-1-8更新:今天做到3sum想到和这里的2sum联系,

3sum:求所有的相加为目标值的数组,

2sum:一旦查找到相加为目标值的俩数组则直接返回俩下标,程序直接结束(仅一组)

现在将2sum的题目改为如下:

给定一个n个整数的数组,在数组中找到和为目标值的所有唯一的两个元素组合【注意不是求下标】

注意:答案集不能包含重复的双胞胎。

测试用例:{1,4,-1,2,-1,0}   1     结果:[[0, 1], [-1, 2]]

{3,2,3,4,1,4,5,5}  8     结果:[[4, 4], [3, 5]]

Code1:时间复杂度:O(N)    【其实应该是Arrays.sort(num)的复杂度】

1 public static List> twoSumAll(int[] num, inttarget) {2 Arrays.sort(num); //将所有相同元素挨在一起

3 List> res = new LinkedList>();4 Set set = new HashSet(); //不需要下标,并且需要元素唯一,所以采用Set

5 for (int i = 0; i < num.length; i++) {6 if (set.contains(target -num[i])) {7 res.add(Arrays.asList(target -num[i], num[i]));8 set.remove(target - num[i]); //防止后续重复元素继续利用此值(因为已经排序,后面不会再有前面的值,不需要再remove(num[i]))

9 }10 set.add(num[i]);11 }12 returnres;13 }

此方法仍然采用上面2sum的思想,利用contains()函数减少一次循环,注意Set的remove使答案避免了”双胞胎数组“

下面采用第15题的3sum的‘’双指针相向移动‘’的思想进行算法编写:

Code2:时间复杂度:O(N)   【其实应该是Arrays.sort(num)的复杂度】

1 public static List> twoSumAll2(int[] num, inttarget) {2 Arrays.sort(num);3 List> res = new LinkedList>();4 int left = 0;5 int right = num.length - 1;6 while (left

双指针相向移动:利用了  已排序数组和  所查找的两个数的和为定值这两个性质

这两个性质如果联合一起用的话………………duang!!!

在已排序数组两端指针所指数之和如果小于目标值,只需要移动左边的指针,否则只需要移动右边的指针

结论:在求和为目标数时,求下标——HashMap;

求具体组合值——前后指针;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值