Algorithm 算法集

216 阅读2分钟

简介

本篇文章是结合「算法导论」以及「leetcode」 记录下来的各种算法集,方便后期查看回顾。

预览

  • 欧几里得算法
  • 斐波那契
  • 两数之和
  • 三数之和

欧几里得算法

问题

计算两个非负整数 p 和 q 的最大公约数:若 q 是 0,则最大公约数为 p。否则,将 p 除以 q 得到余数 r,p 和 q 的最大公约数即为 q 和 r 的最大公约数

解答

function gcd(p, q) {
  if (q == 0 ) return p;
  let r = p % q;
  return gcd(q, r);
}

console.log(gcd(30, 40));

解析

  • 首轮:p < q,取余 r = p
  • 二轮:p, q 值互换,此时 p > q
  • 三轮:q, r 最大公因数即为当前结果

斐波那契

问题

这样一组数,1,1,2,3,5,8……,求第 n 位对应的数

解答

function Fibonacci(n, acc1 = 1, acc2 = 1) {
    if (n <= 2) return acc2;
    return Fibonacci(n - 1, acc2, acc1 + acc2);
}

两数之和

问题

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

如: twoSum([1,2,3,4,,59], 60),需要返回 1 和 59 的下标。

思路

替代两层循环,结合 Map 来存储遍历过的数据,通过 value: index 形式。

解答

function twoSum(nums, target) {
    let map = new Map();
    for (let i= 0; i< nums.length; i++) {
        let currentNum = nums[i];
        if (!currentNum) continue; // 跳过空元素
        if (map.get(target - currentNum) !== undefined) {
            return [map.get(target - currentNum), i];
        };
        map.set(currentNum, i);
    }
};

三数之和

问题

给你一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c ,使得a + b + c = 0。请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
    [-1, 0, 1],
    [-1, -1, 2]
]

思路

双指针法,固定一个数,两外两个头尾移动,且需要先进行排序

解答

function threesSum(nums) {
    let res = [];
    let len = nums.length;
    nums = nums.sort((a, b) => a- b);

    for(let i = 0; i < len - 2; i++) {
        let j = i + 1;
        let k = len - 1;
        let currentSum = nums[i] + nums[j] + nums[k];
        while(j < k) {
            if (currentSum > 0){
                k --;
                while (j < k && nums[k] === nums[k +1]) { // 右指针重复时,递减
                    k--;
                }
            } else if (currentSum < 0) {
                j ++;
                while (j < k && nums[j] === nums[j+1]) {
                    j ++;
                }
            } else {
                res.push([ nums[i], nums[j], nums[k] ]);
                j ++;
                k --;
                while (j < k && nums[k] === nums[k +1]) { // 右指针重复时,递减
                    k--;
                }
                while (j < k && nums[j] === nums[j+1]) {
                    j ++;
                }
            }

        }
    }
    return res;
}

持续更新中……