LeetCode 1.The Sum

来源:互联网 发布:保利投顾 知乎 编辑:程序博客网 时间:2024/06/06 10:51

The 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].

个人思路:

两层for循环暴力求解。外层循环i从0到数组的长度,内层循环j从i的后一位开始循环,避免对同一个数字循环两次。然后判断数组下标为i和j的数字之和是否满足目标值,若满足,则返回这两个下标。需要注意的是返回的的下标是一个数组。

代码如下:

public class Solution {    public int[] TwoSum(int[] nums, int target) {        int[] arr = new int[2];        for (int i = 0; i < nums.Length; i++)        {            for (int j = i + 1; j < nums.Length; j++)            {                if (nums[i] + nums[j] == target)                {                    arr[0] = i;                    arr[1] = j;                }             }        }        return arr;    }}

官方解答:

方法#1(暴力)[接受]

暴力方法很简单。遍历每个元素Xx并找出是否有另一个值等于

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");}

复杂性分析:

时间复杂度: 为O(n^2)。对于每个元素,我们试图通过循环其余的数组来找到它的补充集上O(n)时间。所以时间复杂度是为O(n^2)。
空间复杂度:O(1)

方法2(双向哈希表)[接受]

为了提高我们的运行时间复杂度,我们需要一个更有效的方法来检查数组中是否存在补充。如果存在补充,我们需要查找它的索引。维护数组中每个元素到索引的映射的最佳方法是什么?一个哈希表。
我们从缩短查找时间O(n)到O(1)以交易空间为速度。哈希表正是为此目的而构建的,它支持在接近恒定的时间快速查找。说“近”,因为如果发生碰撞,查找可能退化为O(n)时间。但在哈希表中查找应摊销O(1)时间,只要仔细选择散列函数。
一个简单的实现使用两个迭代。在第一次迭代中,我们将每个元素的值及其索引添加到表中。然后,在第二次迭代中,我们检查每个元素的补充存在于表中。注意,补充一定不能是nums[i]本身!

//官方给出的是java版本,这里我修改为C#的实现public static int[] twoSum(int[] nums, int target)        {            Dictionary<int, int> dic = new Dictionary<int, int>();            for (int i = 0; i < nums.Length; i++)            {                dic.Add(nums[i], i);            }            for (int i = 0; i < nums.Length; i++)            {                int complement = target - nums[i];                if (dic.ContainsKey(complement) && dic[complement] != i)                {                    return new int[] { i, dic[complement] };                }            }            throw new ArgumentException("No two sum solution");        }

复杂性分析:

  • 时间复杂度:O(n)。我们遍历包含的列表n个元素恰好两次。由于散列表减少了查找时间O(1),时间复杂度是上O(n)。
  • 空间复杂度:O(n)。所需的额外空间取决于哈希表中存储的项目数量,该数据存储的确切数量n个元素。

方法3(一次散列表)[接受]

事实证明,我们可以一次完成。当我们迭代并向表格中插入元素时,我们也回头检查当前元素的补充是否已经存在于表格中。如果存在,我们已经找到了解决办法,并立即返回。

public static int[] twoSum(int[] nums, int target)        {            Dictionary<int, int> dic = new Dictionary<int, int>();            for (int i = 0; i < nums.Length; i++)            {                int complement = target - nums[i];                if (dic.ContainsKey(complement))                {                    return new int[] { dic[complement], i };                }                dic.Add(nums[i], i);            }            throw new ArgumentException("No two sum solution");        }

复杂性分析:

  • 时间复杂度:O(n)。我们遍历包含的列表n个元素只有一次。每个在表中查找成本只有O(1)次。
  • 空间复杂读:O(n)。所需的额外空间取决于最多存储在散列表中的项目数量n个元素。