如果在检查使用 hashmap 解决 Leetcode 二和的解决方案之前执行 map.put,为啥会失败?

Posted

技术标签:

【中文标题】如果在检查使用 hashmap 解决 Leetcode 二和的解决方案之前执行 map.put,为啥会失败?【英文标题】:why will fail if do map.put before checking for solutions in solving Leetcode Two Sum using hashmap?如果在检查使用 hashmap 解决 Leetcode 二和的解决方案之前执行 map.put,为什么会失败? 【发布时间】:2019-11-06 22:13:07 【问题描述】:

对于经典的 Leetcode TwoSum 问题: 给定一个整数数组,返回两个数字的索引,使它们相加为特定目标。

您可以假设每个输入都只有一个解决方案,并且您不能两次使用相同的元素。

例子:

给定 nums = [2, 7, 11, 15],target = 9,因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]。

试了下面的代码,可以通过测试用例,但是提交失败。

public class Solution 
    public int[] twoSum (int[] arr, int target) 
        if (arr == null || arr.length < 1) 
            throw new IllegalArgumentException ("array given is null or 
length less than 1, no two sum solutions"); 
        
        Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
        for (int i = 0; i < arr.length; i++) 
            map.put (arr[i], i);
            int component = target -arr[i]; 
            if (map.containsKey(component) && map.get(component) != i) 
                return new int[] i, map.get(component);
            
           
        throw new IllegalArgumentException (" no two sum solution found 
"); 
    

如果我只是在解决方案检查后移动 map.put,如下所示,会通过,不知道为什么?

public class Solution 
    public int[] twoSum (int[] arr, int target) 
        if (arr == null || arr.length < 1) 
            throw new IllegalArgumentException ("array given is null or 
length less than 1, no two sum solutions"); 
        
        Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
        for (int i = 0; i < arr.length; i++) 

            int component = target -arr[i]; 
            if (map.containsKey(component) && map.get(component) != i) 
                return new int[] i, map.get(component);
            
            map.put (arr[i], i);
           
        throw new IllegalArgumentException (" no two sum solution found 
"); 
    

【问题讨论】:

【参考方案1】:

考虑测试用例[5,5,8],目标是10; 如果您在解决方案检查之前放置 mapmap.put (arr[i], i);,则测试用例将失败

对于相同的键,您将覆盖地图中的索引

【讨论】:

【参考方案2】:

如果数组包含重复项,您的第一个 sn-p 将失败,target 是两个相等数组元素的总和。

假设target == arr[i] + arr[j] 对应一些ij,这样ij 和arr[i]==arr[j]。在这种情况下,您将首先输入map.put (arr[i], i),然后用map.put (arr[j], j) 覆盖它。因此,map.containsKey(component) 将是 truemap.get(component) != i 将是 false,并且您将无法返回一对索引 ij

因此,您应该只在检查条件后将当前元素添加到Map

例如,以下输入将在第一个解决方案中失败,在第二个解决方案中成功:

twoSum(new int[] 4,5,7,5,10)

【讨论】:

谢谢!所以意味着如果我使用 arr[i] 作为 hashmap 键,如果 arr[] if arr[] == arr[i] 将继续覆盖该值,即使在目标时使用第二种方法!=两个副本的总和。这是否意味着使用 [i] 作为 hashmap 键比 arr[i] 更好? @user9571515 确实如此,但在这种情况下,覆盖该值并不重要。如果某个 k 的 arr[i]+arr[k]==target,arr[j]+arr[k] 也将是 == target,所以返回 i & k 或 j & k 都没有关系。

以上是关于如果在检查使用 hashmap 解决 Leetcode 二和的解决方案之前执行 map.put,为啥会失败?的主要内容,如果未能解决你的问题,请参考以下文章

Java HashMap 内容 [重复]

Java HashMap 中的冲突解决

HashMap在高并发下如果没有处理线程安全会有怎样的安全隐患,具体表现是什么

java 使用Hashmaps检查Anagrams

存储在磁盘上的 HashMap 从磁盘读回非常慢

在Flink中广播HashMap