1. 两数之和
思路
- 创建一个Map,for循环遍历nums数组;
- 用target减nums[i],得到符合要求的数字targetNum
- 检查map里有没有targetNum: 如果没有则将nums[i]当做key,i当做value存入map;如果有则返回结果;
code
const twoSum = (nums, target) => {
const prevNums = new Map(); // 存储出现过的数字,和对应的索引
for (let i = 0; i < nums.length; i++) { // 遍历元素
const curNum = nums[i]; // 当前元素
const targetNum = target - curNum; // 满足要求的目标元素
if (prevNums.has(targetNum)) { // 如果存在,直接返回 [目标元素的索引,当前索引]
return [prevNums.get(targetNum), i];
} else { // 如果不存在,说明之前没出现过目标元素
prevNums.set(curNum, i)
}
}
}
2. 两数相加
思路
code
3. 无重复字符的最长子串
思路
- 创建一个set和maxLength;
- 创建两个指针i和j,j指向字符串开头,i随着for循环遍历字符串s;
- 如果set里没有s[i],说明目前为止还没有重复的字符,把s[i]添加到set里,比较maxLength和set.size,maxLength取最大值;
- 如果set里有s[i],则从set里删除s[j],并且递增j,再检查set里有没有s[i];
- 重复步骤3和4,直到遍历完整个字符串;
- 返回set的长度;
code
var lengthOfLongestSubstring = function (s) {
if (s.length === 0) {
return 0;
}
const temp = new Set();
let maxLength = 1;
let i = 0, j = 0;
for (i; i < s.length; i++) {
if (temp.has(s[i])) {
while (temp.has(s[i])) {
temp.delete(s[j]);
j++;
}
temp.add(s[i])
} else {
temp.add(s[i])
}
maxLength = maxLength > temp.size ? maxLength : temp.size;
}
return maxLength;
};
5. 最长回文子串
思路
- 如果字符串的长度小于2,直接返回愿字符串;
- 定义两个变量,一个start存储当前找到的最大字符串的位置,另一个maxLength记录字符串的长度(终止位置 = start + maxLength);
- 创建一个helper function,判断左边和右边是否越界,最左边的字符是否等于最右边的字符;如果以上三个条件都满足,则判断是否需要更新maxLenght和start,然后left--,right++,继续判断直到不满足以上三个条件之一;
- 遍历字符串,每个位置调用helper function两遍,第一次检查i-1,i+1,第二次检查i,i+1;
code
var longestPalindrome = function(s) {
if (s.length < 2) {
return s;
}
let start = 0, maxLength = 1;
function helper(left, right){
while(left >= 0 && right < s.length && s[left] === s[right]) {
const curLength = right - left + 1;
if (curLength > maxLength) {
maxLength = curLength;
start = left;
}
left--;
right++;
}
}
for(let i = 0; i < s.length ; i++) {
helper(i-1, i+1)
helper(i, i+1)
}
return s.substr(start, maxLength)
};
15. 三数之和
思路
- 给数组排序;
- 遍历数组,从0到target-2;
- 如果当前数字等于前一个数字,则跳过这个数字;
- 如果数字不同,则设置start = i + 1,end = length - 1,查看i、start和end三个数的和比零大还是比零小,如果比0小,start++,如果比0大,end--;
- 返回结果;
19. 删除链表的倒数第N个节点

思路
code
[20. 有效的括号
](leetcode-cn.com/problems/va…)
[21. 合并两个有序链表
](leetcode-cn.com/problems/me…)
[24. 两两交换链表中的节点
](leetcode-cn.com/problems/sw…)
39. 数组中出现次数超过一半的数字
/**
* 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
* 你可以假设数组是非空的,并且给定的数组总是存在多数元素
*
* 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
* 输出: 2
*/
摩尔投票法
var majorityElement = function (nums) {
let count = 1;
let result = nums[0];
for (let i = 1; i < nums.length; i++){
if (count === 0) {
result = nums[i]
}
if (result === nums[i]) {
count++;
} else {
count--;
}
}
return result;
};
算法复杂度
时间复杂度: 时间复杂度 O(n) 空间复杂度:O(1)
斐波那契数列/青蛙跳台阶
递归 + 动态规划
function fib(n) {
var temp = {};
function count(n) {
let result;
if (temp[n]) {
return temp[n]
}
if (n <= 0) {
result = 0;
} else if (n === 1) {
result = 1
} else if (n === 2) {
result = 1
} else {
result = count(n - 1) + count(n - 2);
}
temp[n] = result;
return result;
}
return count(n);
};
硬币找零
/**
* 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。
* 如果没有任何一种硬币组合能组成总金额,返回 -1。
*
* 输入: coins = [1, 2, 5], amount = 11
* 输出: 3
* 解释: 11 = 5 + 5 + 1
*/
贪心算法
function coinChange(coins: number[], amount: number): number {
function _coinChange(coins: number[], amount: number): number[] {
if (amount <= 0) {
return [];
}
// 数组里的最大值 && <= amount
let temp = 0;
for (let i = 0; i < coins.length; i++) {
let coin = coins[i];
if (temp < coin && coin <= amount) {
temp = coin;
}
}
let result = [temp];
const next = _coinChange(coins, amount - temp);
result = result.concat(next);
return result;
}
const result = _coinChange(coins, amount);
return result.length;
}
最长公共子序列
分治法 + 动态规划
var longestCommonSubsequence = function (text1, text2) {
var temp = [];
function _(text1, text2) {
// num++;
if (text1 === '' || text2 === '') {
return '';
}
for(let item of temp) {
if (item.str1 === text1 && item.str2 === text2) {
return item.result;
}
}
let result = '';
if (text1[0] === text2[0]) {
result = text1[0] + _(text1.substr(1), text2.substr(1));
} else {
let lcs1 = _(text1.substr(1), text2)
let lcs2 = _(text1, text2.substr(1));
result = lcs1.length > lcs2.length ? lcs1 : lcs2;
}
temp.push({
str1: text1,
str2: text2,
result
})
return result;
}
return _(text1, text2).length;
};