题目1
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
实例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
思路:
- 创建一-个map
- for循环遍历nums数组
- 用target减nums[i],以计算哪个数能跟当前的数字相加得到target
- 检查map里有没有用target减nums[i]得到的数,如果有则返回结果,如果没有则把num[i]当作key,i当作value放入map中(为什么?)u用到了map.has检查map中对应的key
模拟假如:nums=[2,3,11,7] target=
7,6,-2,2
要找到2和7并返0和3
MAP = {
2:0,
3:1,
11:2
}
9-7等于2,在map中有这这个数,就找到了2和7这个对应的值
const twoSum = (nums, target) => {
//创建一-个map
const map = new Map()
//for循环遍历nums数组
for (let i= 0; i<nums.length; i++) {
//用target减nums[i],以计算哪个数能跟当前的数字相加得到target
const complement = target - nums[i]
// 检查map里有没有用target减nums[i]得到的数,如果有则返回结果,如果没有则把num[i]当作key,i当作value放入map中,用到了map.has检查map中对应的key
if (map.has(complement)) {
//如果查找到map中存在就返回两个数对应的下标
return [map.get(complement),i]
}else {
map.set(nums[i],i)
}
}
return []
}
console.log(twoSum([2,3,11,7],9))//[ 0, 3 ]
题目2-斐波拉契数列
第n 个数由数列的前两个相加而来: f(n) = f(n - 1) + f(n -2),用代码实现斐波拉契数列,无非就是要考察递归的写法,但是,单纯使用递归,在严格要求时间复杂度和空间复杂度上是不可行的,因为他做了无数次无用的计算.
1, 1, 2, 3, 5, 8, 13, …
普通实现 (递归)
这种方式计算的时候会有很多重复的计算,而且递归的层数越来越深容易递归爆栈。
const fib = n => n <= 1 ? n :fib(n-1)+fib(n-2)
console.log(fib(5))
减少时间复杂度(闭包+递归)
通过增加一层缓存,用来存放之前已经计算过的数值,当需要计算新值的时候先通过查找缓存,缓存命中则直接返回,未命中再继续计算。但是使用了数组,增加了空间复杂度.
const fib3 = function (n) {
n <= 1 && n
const cache = []
cache[0] = 1
cache[1] = 1
function memoize(num) {
if (cache[num] !== undefined) {
return cache[num]
}
cache[num] = memoize(num - 1) + memoize(num - 2)
// console.log(cache[num])
return cache[num]
}
const result = memoize(n-1)
return result
}
console.log(fib3(4))
但是这样的实现方式有一个问题,如果不是依次计算斐波那契数列就会增加额外的消耗,比如直接计算 fib(1000) ,这个时候数组中会先初始化中间的其他数组项为 undefined 这里会小一些时间,但是计算完毕之后1-1000之间的斐波那契数列都填充完毕了。
参考网上的一种解法是用对象替换数组来进行缓存,这样就少去了填充 undefined 的时间
// 闭包 + 缓存对象
const fibonacci = (function () {
const f = {}
return function(n) {
if(n === 0 || n === 1) {
return n
}
if(f[n-2] === undefined) {
f[n-2] = fibonacci(n-2)
}
if(f[n-1] === undefined) {
f[n-1] = fibonacci(n-1)
}
return f[n] = f[n-1] + f[n-2]
}
})()
换一种从前往后算的写法:::从前面的数一步一步的往后计算一直计算到n
const fib =function (n){
n <= 1 && n
const cache = []
cache[0] = 1
cache[1] = 1
for (let i= 2; i<=n; i++ ) {
cache[i] = cache[i-1] +cache[i-2]
}
return cache[n-1]
}
console.log(fib(5))
减少空间复杂度
不使用和数组,减少空间维度 从前往后算
const fib = n =>{
n <= 1 && n
let prev2 = 0
let prev1 = 1
let result = 0
for (let i = 2;i<=n;i++) {
result =prev2+prev1
prev2 = prev1
prev1 = result
}
return result
}