leetcode01-两数之和

问题描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

接着,给出我自己的方法:

/* javascript编写 */
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
function twoSum (nums, target) {
  // 这里的作用是开辟一块新的内存复制nums数组
  let temp = nums.slice(0)
  // 对temp数组进行排序
  temp.sort(function (a, b) {
      return a - b
  })
  let i = 0, j = nums.length - 1
  let tempSum = temp[i] + temp[j]
  while (tempSum !== target) {
    // 如果首尾相加大于目标值,则j要减1
    if (tempSum > target) j--
    // 如果首尾相加小于目标值,则i要加1
    else i++
    // 出现i > j的情况则说明数组中不存在这样的两个数
    if (i > j) throw "no two sum solution"
    // 正常情况下我们要先计算下依次下标i,j对应数的和
    else tempSum = temp[i] + temp[j]
  }
  // 到这一步,就说明存在这样的两个数,那么我们将这两个数在原来的数组中寻找到它们的下标
  let a, b
  for (let n = 0; n < nums.length; n++) {
      if (a === undefined && nums[n] === temp[i]) a = n
      if (a !== n && b === undefined && nums[n] === temp[j]) b = n
      if (a !== undefined && b !== undefined) break
  }
  return [a, b]
}

时间复杂度分析:从上面的代码中可以看到,我们先将数组进行排序,然后进行了一个while循环(O(n)),最后又进行了一次for循环(O(n)),所以起绝对作用的是数组排序的时间复杂度(八大排序算法之一)。

官方解答:
解法一:

/* 方法一,暴力法 */
/* javascript编写 */
/*
复杂度分析:
1.时间复杂度:O(n^2),对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费O(n)的时间。因此时间复杂度为O(n^2).
2.空间复杂度:O(1).
*/
function twoSum (nums, target) {
    for (let i = 0; i < nums.length; i++) {
        for (let j = i + 1; j < nums.length; j++) {
            if (nums[j] === target - nums[i]) {
                return [i, j]
            }
        }
    }
    throw "no two sum solution"
}

解法二:

/* java编写 */
/* 方法二:两遍哈希表 */
/*
复杂度分析:
1.时间复杂度:O(n), 我们把包含有 n 个元素的列表遍历两次。由于哈希表将查找时间缩短到 O(1) ,所以时间复杂度为 O(n)。
2.空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表中存储了 n 个元素。 
*/
public int[] twoSum(int[] nums, int target) {
  Map < Integer, Integer > map = new HashMap < > ();
  for (int i = 0; i < nums.length; i++) {
    map.push(nums[i], i);
  }
  for (int i = 0; i < nums.length; i++) {
    int complement = target - nums[i];
    if (map.containsKey(complement) && map.get(complement) != i) {
      return new int[] {
        i,
        map.get(complement)
      }
    }
  }
  throw new IllegalArgumentException("No two sum solution")
}

解法三:

/* javascript编写,这里用对象来代替哈希表 */
/*
复杂度分析:
1.时间复杂度:O(n), 我们只遍历了包含有 n 个元素的列表一次。在表中进行的每次查找只花费 O(1)的时间。
2.空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表最多需要存储 n 个元素。
*/
/* 方法三:一遍哈希表 */
function twoSum(nums, target) {
  let arrObj = {}
  for (let i = 0; i < nums.length; i++) {
    let complement = target - nums[i]
    if (undefined !== arrObj[complement]) {
      return [arrObj[complement], i]
    }
    arrObj[nums[i]] = i
  }
  throw "no two sum solution"
}
发布了80 篇原创文章 · 获赞 91 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/YaoDeBiAn/article/details/88323416