js实现无序数组中的两数之和--力扣

目录

1 题目

2 输入输出

3 解法

1)暴力法

2)对象或者ES6中Map数据结构,以空间换取时间的方法

3)

4 代码

1 题目

https://leetcode-cn.com/problems/two-sum/

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍

2 输入输出

示例:

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

因为 nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]

3 解法

1)暴力法

遍历每个元素x,并查找是否存在一个值与 target - x 相等的目标元素。这里可以使用双层循环来实现;

时间复杂度:O(n2) 即n方

空间复杂度:O(1)

2)对象或者ES6Map数据结构,以空间换取时间的方法

为了对运行时间复杂度进行优化,我们需要一种更有效的方法来检查数组中是否存在目标元素。如果存在,我们需要找出它的索引。

通过以空间换取速度的方式,对象或者ES6Map数据结构查询速度比for查询快。将nums 数组值作为键,值为下标,构建对象或者Map。对数组nums遍历每个元素x,并查找是否存在一个值与 target - x 相等的目标元素,如果相等,得出结果,不相等,则把值作为键,下标作为值保存在对象或者Map

时间复杂度:O(n) ??????查询对象的键时间是O(1)???

空间复杂度:O(n) ????建立对象所需要的空间

3)

类似2),2)是边遍历数组,边构建对象或者Map;这里可以先遍历数组构建好构建对象或者Map,再遍历数组,寻找目标元素。(代码自己写)

4 代码

/**

 * @param {number[]} nums

 * @param {number} target

 * @return {number[]}

 * 求twoSum 暴力解法

 */

  var twoSum = function(nums, target) {

    if(nums === null || nums.length <= 1){ //数组长度小于或等于1时

        return [];

    }

    //console.time("11");

    for(let i = 0; i < nums.length; i++){  //长度大于2时

        let value = target - nums[i]; // 差值,在后面寻找与差值相等的值即可

        for(let j = i + 1; j < nums.length; j++){

            if(value === nums[j]){

                //console.timeEnd("11"); //0.332ms

                return [i, j];//如有相等,返回这两个坐标

            }

        }

    }

    return [];//没有相等,返回空数组

  };

  

  /**

 * @param {number[]} arr

 * @param {number} target

 * @return {number[]}

 * 求twoSum 先排序,再双指针求有序数组中的两个数和,,,解法错误,因为题目输出的是下标,如果排序的话,下标会变

 */

  var twoSum_2 = function(arr, target) {

    if(arr === null || arr.length <= 1){ //数组长度小于或等于1时

        return [];

    }

    //console.time("22");

    arr.sort(function (a,b) {

        return a - b; //返回正时,交换元素,正序升

    });

    //双指针,求有序数组的twoSum

    let left = 0;

    let right = arr.length - 1;

    while(left < right){  //不能相等,如果相等,则可能是一个数

        if(arr[left] + arr[right] === target){

            //console.timeEnd("22");//0.413ms

            return [left, right];

        }else if(arr[left] + arr[right] > target){

            right--;

        }else {

            left++;

        }

    }

    return []; //如果不存在两个数,返回空数组

  };

  

  /**

 * @param {number[]} arr

 * @param {number} target

 * @return {number[]}

 * 求无需数组中twoSum 将数组中的值作为对象obj中键,键唯一,且查找速度稍快

 */

  var twoSum_3 = function(arr, target) {

    if(arr === null || arr.length <= 1){ //数组长度小于或等于1时

        return [];

    }

    //console.time("22");

    let obj = {}; //建立空对象,对象的键必须唯一。键为数组中值(如果数组值相同,更新对象对应的键值),值为数组中对应下标

    for(let i = 0; i < arr.length; i++){

        let diff = target - arr[i]; //差值

        if(obj[diff] || obj[diff] === 0){  //这里的条件也可以使用obj.hasOwnProperty(diff)或者obj[diff] !== undefined

            //console.timeEnd("2obj[diff] !== undefined2");//22: 0.341ms

            return [obj[diff], i];

        }

        obj[arr[i]] = i;//键为数组中值(如果数组值相同,更新对象对应的键值),值为数组中对应下标,值有0,1,2...

    }

    return []; //如果不存在两个数,返回空数组

  };

  

  /**

 * @param {number[]} arr

 * @param {number} target

 * @return {number[]}

 * 求无需数组中twoSum 使用Map的数据结构

 */

  var twoSum_4 = function(arr, target) {

    if(arr === null || arr.length <= 1){ //数组长度小于或等于1时

        return [];

    }

    //console.time("22");

    let map = new Map(); //

    for(let i = 0; i < arr.length; i++){

        let diff = target - arr[i]; //差值

        if(map.has(diff)){  //

            //console.timeEnd("2obj[diff] !== undefined2");//22: 0.341ms

            return [map.get(diff), i];

        }

        map.set(arr[i], i);//键为数组中值(如果数组值相同,更新对象对应的键值),值为数组中对应下标,值有0,1,2...

    }

    return []; //如果不存在两个数,返回空数组

  };

  

  let nums = [3,2,4];

  let target = 6;

  console.log(twoSum(nums, target));

  console.log(twoSum_4(nums, target));

参考:力扣

百里于2020年5月23日

如果有错,请您指出!如有侵权,请联系我删除!

你可能感兴趣的:(#,力扣top)