每天进步一点点
算法开始第一天 twoSum(两数之和) 刷了n次 写了n次 开始写文章记录一下 到年底希望自己能够坚持 让我开始吧!!!!!
题目描述
给定的一个整数数组
nums和一个目标值target,请你再该数组中找到和为目标值的那两个整数,并返回他们的数组下标 tips: 你可以假设每种输入只会对应一种答案,但是,你不要重复利用这个数组中同样的元素示例:给定
nums = [2,7,11,15]target = 9返回[0, 1]
两数之和之暴力递归
思路 已知target 已知第一层循环对应下标i的值 所以只要遍历下标i后面元素 找出元素与 differenceValue相等的下标
/**
* 两数之和之暴力递归
* @param {number} target
* @param {array} nums
* 时间复杂度: T(n) = 3n^2 + 6n + 5 -> 0(n) = O(n^2)
* 空间复杂度: O(1)
*/
function twoSum(target,nums){
let len = nums.length // 最坏执行的次数 1
for(let i = 0; i < len; i++){ // 最坏执行的次数: 2n + 2
let currentValue = nums[i] // 最坏执行的次数: n
let differenceValue = target - currentValue // 最坏执行的次数: n
for(let j = i + 1; j < len; j++){ // 最坏执行的次数: 2n^2 + 2n
if(nums[j] === differenceValue){ // 最坏执行的次数: n^2
return [i,j] //最坏执行的次数: 1
}
}
}
throw new Error('没有符合条件的值') //最坏执行的次数: 1
}
console.time('twoSum')
const result = twoSum(9,[2,4,7,11,15])
console.timeEnd('twoSum') // 0.081ms
console.log('>>>>', result) // [0,2]
空间换时间
大部分求和问题 都可以转化为求差问题
思路 可以使用Map来存储已经出现的值和下标 当Map拥有当前下标和目标值的差值 就返回这个两个下标
/**
* 空间换时间 一次遍历
* @param {array} nums
* @param {number} target
* 时间复杂度: T(n) = 4n + 5 -> O(n) = O(n)
* 空间复杂度: O(n)
*/
const twoSum = function(nums,target){
let len = nums.length // 最坏执行的次数 1
let map = new Map() // 最坏执行的次数 1
for(let i= 0; i< len; i++){ // 最坏执行的次数 2n + 2
if(map.has(target - nums[i])){ // n
return [map.get(target - nums[i]),i] // 1
}
map.set(nums[i], i) // n
}
}
console.time('twoSum')
const result1 = twoSum([2,4,7,11,15],9)
console.timeEnd('twoSum') // 0.04ms
console.log('>>>>', result) // [0,2]
相撞指针
思路分析 题目给出是一个有序的数组 可以使用双向指针 最小的值 + 最大的值 > target r-- 最小的值 + 最大的值 < target l++
/**
* 相撞指针
* @param {number[]} nums
* @param {number} target
* 时间复杂度 O(n) = 4n + 4 -> O(n)
* 空间复杂度: O(1)
*/
const twoSum2 = function(nums, target){
let len = nums.length // 最坏执行的次数: 1
let l = 0 // 最坏执行的次数: 1
let r = len - 1 // 最坏执行的次数: 1
while(r > l){ // 最坏执行的次数: n
if(nums[l] + nums[r] > target){ // 最坏执行的次数: n
r-- // 最坏执行的次数: n
}else if(nums[l] + nums[r] < target){ // 最坏执行的次数: n
l++ // 最坏执行的次数: n
}else{
return [l, r] // 最坏执行的次数: 1
}
}
}
console.time('twoSum2')
const result2 = twoSum2([2,4,7,11,15],9)
console.timeEnd('twoSum2') // 0.032ms
console.log('>>>>', result2) // [0,2]
n 越大这两种方法的性能差也会越多
ok!! Baybay! 明天见