04-20.eri-test 2种方法求和

问题:给定一个数组A和一个目标T,检查A中是否存在一个对的总和为T。

如果您是面试准备之旅的开始,这通常是您遇到的第一个。

让我们分解一下。
问我们要做什么?

  1. 我们得到了一个数组,该数组可以排序或不排序。 令A [] = [2,5,1,6,8,3,4,7]
  2. 给定目标T = 15
  3. We've to return check if there exists a pair which sum to t, ie let x & y be two elements in A such that x+y = T. We have to find those two elements.

天真/蛮力方法:
Brute force approach would be to search for each x & y pairs which would sum to target T:

public class Solution {

  //brute force O(n^2) time O(1) space
  public int[] twoSum(int[] nums,int target){
    for(int i=0;i<nums.length-1;i++){
      for(int j=i;j<nums.length;j++){
        if(nums[i]+nums[j] == target) return new int[]{i,j};
      }
    }
    return new int[]{-1,-1};
  }

这将生成所有可能的对,并将返回与条件匹配的第一对,现在让我们考虑一个情况,其中Give数组为

A = [1,2,3,4,5,6,7,8] Target = 15

在这种情况下,将生成[1,2],[1,3],[1,4],[1,5] .. [7,8]的所有可能组合。

改善:
让我们考虑一下我们可以使用的东西,如何在以前的最坏情况下处理数组,以减少现在的时间,最坏的情况发生在我们必须搜索整个数组并且结果位于 最后ie [7,8]?

  1. Sorting and Two pointers: if we sort the array A, then A becomes [1,2,3,4,5,6,7,8]. How can we use this to our advantage? let's assign two pointers, start and end. start = 0 & end = nums.length-1; here we observe that if
    1. nums [start] + nums [end] ==目标,我们已经解决了。
    2. nums[start] + nums[end] > target, we've too much of the bigger number, so decrement end.
    3. nums[start] + nums[end] < target, we've too less of the smaller number, so increment start. But here we face a caveat since we're expected to return the indices of the elements in the array. For that we do:
    4. 在数组中搜索开始和结束元素。
int[] nums2 = Arrays.copyOf(nums, nums.length);
            Arrays.sort(nums2);
            int a = 0, b = 0;
            int start = 0, end = nums2.length-1;
            //find two nums
            while(start<end){
                int sum = nums2[start] + nums2[end];
                if(sum < target)
                    start++;
                else if(sum > target)
                    end--;
                else{
                    a = nums2[start]; b = nums2[end];
                    break;
                }
            }
            //find the index of two numbers
            int[] res = new int[2];
            for(int i = 0; i < nums.length; i++){
                if(nums[i] == a){
                    res[0] = i;
                    break;
                }
            }
            if(a != b){
                for(int i = 0; i < nums.length; i++){
                    if(nums[i] == b){
                        res[1] = i;
                        break;
                    }
                }
            } else{
                for(int i = 0; i < nums.length; i++){
                    if(nums[i] == b && i != res[0]){
                        res[1] = i;
                        break;
                    }
                }
            }

            return res;
}

此时,面试官应该对您正在接近感到满意,但他会问
“我们可以做得更好吗?”
是的,我们可以。

  1. HashMap:HashMap存储对,我们使用此属性存储索引和总和。 我们将target-num [i]存储为键,将索引i存储为值。 让我们经历一下: 对于数组[2,5,1,6,8,3,4,7]和target = 15,存储的键值对为:
2 > 15-2 = 13 <13,0>
5 > 15-5 = 10 <10,1>
1 > 15-1 = 14 <14,2>
6 > 15-6 = 9  < 6,3>
8 > 15-8 = 7  < 7,4>
3 > 15-3 = 12 <12,5>
4 > 15-4 = 11 <11,6>

7 > now here is where the magic happens, since at index 4, element 8, we stored <7,4> in hashMap, it means that we need that and we've seen 15-7 = 8 at position 4. which means we've found the solution. return the current index of 7 ie 7 and index of 8 ie 4.

 Map<Integer,Integer> map = new HashMap<>();
        int[] res = new int[]{-1,-1};
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(nums[i])){
                res[1] = i;
                res[0] = map.get(nums[i]);
            }else{
                map.put(target-nums[i],i);
            }
        }
        return res;
 }

希望你喜欢这个旅程.
Github链接 : https://github.com/AKHILP96/Data-Structures-and-Algorithms/blob/master/problems/TwoSum.java

from: https://dev.to//akhilpokle/2-ways-to-two-sum-2dbh

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值