【简单】1 – 两数之和

作者:Leopold    访问量:5

题目

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例

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

解法一:暴力法

双循环嵌套 O(n^2) O(1)

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

解法二:HashMap

哈希表索引查找 O(n) O(n)

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

以空间换时间(new HashMap),在哈希表不出现哈希冲突的情况下,退化为O(1),最差情况为O(n),因此填充因子起到关键作用。
考虑到map.containsKey(complement)中可能遇到双循环的问题,源码如下:

final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
}

不难发现,数组散列(无哈希冲突)的前提下,不会进入循环。即便发生多次哈希冲突,会改用getTreeNode方法去获取值, getTreeNode是从一棵红黑树中获取值, 时间复杂度顶多O(logN) < O(n^2)。



如果您觉得此文章对您有帮助,欢迎评论转载!

您的每一次评论与转载,都是对作者极大的鼓励!

注意:除非注明,否则均为[Leopold's Blog]原创文章,转载必须以链接形式标明本文链接。

本文链接:https://www.yusong.site/leopold/798.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注