【算法】两数之和

原题

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

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

思路

最简单的方法是通过两层for循环进行遍历, 使用暴力的查找两个子元素。但是这种方法的时间复杂度为O(n^2)。在大数据量的测试用例的情况下执行时间超时。那么我们有什么办法可以将时间复杂度降下来吗?这时我们可以用到HashMap。通过HashMap我们可以将时间复杂度降为O(2n)。如果是有序数组的情况下, 时间复杂度可以是O(n), 详见下题

1、使用map

这个思路比较简单,而且复杂度低,但是需要对map有对应的应用和理解;
通过这个方法,我学习到的一点是:对应的数组中的某个数和数字下标用map对应起来。通过map的key、value把数组中的值和它对应的下标对应起来,很巧妙的结合起来。

        var twoSum2 = function (nums, target) {
            const len = nums.length; // 获取长度
            let map = new Map()  //定义map
            for (let i = 0; i < len; i++) {
                const diff = target - nums[i] // 拿到目标值与当前值的差值 
                if (map.has(diff)) { // 判断map里是否存在,若存在则说明:当前值nums[i]+map.get(diff)=target
                    return [map.get(diff), i] // 直接返回对应的下标
                } else {
                    map.set(nums[i], i) // 不存在,则存当前值以及对应的下标,继续循环
                }
            }
            return [] // 没找到
        };
2、使用两个for循环
        var twoSum2 = function (nums, target) {
            // 暴力法
            for (let i = 0; i < nums.length; i++) {
                for (let j = i + 1; j < nums.length; j++) {
                    if (nums[i] === target - nums[j]) return [i, j]
                }
            }
            return []
        }
3、先记录下标,然后对数组进行排序,使用双指针法(这个方法比较复杂,是借鉴的三数之和的方法)
        var twoSum = function (nums, target) {
            let [res, arr, len] = [[], [], nums.length];
            nums.forEach((item, index) => {
                arr.push({ key: index, value: item })
            })

            arr.sort((a, b) => a.value - b.value)
            // 数组
            console.log(arr)
            for (let i = 0; i < len - 1; i++) {
                let k = len - 1
                while (i < k) {
                    console.log(arr[i])
                    console.log(arr[k])
                    let sum = arr[i].value + arr[k].value
                    console.log(sum)
                    if (sum < target) {
                        i++
                        if (i > 0 && arr[i - 1].value === arr[i].value) {
                            i++
                        }
                    } else if (sum > target) {
                        k--
                        if (k > 0 && arr[k + 1].value === arr[k].value) {
                            k--
                        }
                    } else {
                        console.log(arr[i])
                        console.log(arr[k])
                        res.push(arr[i].key, arr[k].key)
                        return res

                    }
                }
            }
        };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值