详细解说请看视频JS老毕:人人都能看得懂的Leetcode力扣刷题教程合集
边看视频边记录笔记!!!部分题目在视频中无!

文章目录

  • LeetCode第1题:1. 两数之和
  • LeetCode第2题:2. 两数相加
  • LeetCode第3题:3.无重复字符的最长子串
  • LeetCode第5题:5. 最长回文子串
  • LeetCode第11题:11. 盛最多水的容器
  • LeetCode第15题:15. 三数之和
  • LeetCode第17题:17. 电话号码的字母组合
  • LeetCode第19题:19. 删除链表的倒数第 N 个结点
  • LeetCode第20题:20. 有效的括号
  • LeetCode第21题:21. 合并两个有序链表
  • LeetCode第24题:24. 两两交换链表中的节点
  • LeetCode第49题:49. 字母异位词分组
  • LeetCode第53题:53. 最大子序和
  • LeetCode第54题:54. 螺旋矩阵
  • LeetCode第55题:55. 跳跃游戏
  • LeetCode第56题:56. 合并区间
  • LeetCode第62题:62. 不同路径
  • LeetCode第66题:66. 加一
  • LeetCode第70题:70. 爬楼梯
  • LeetCode第73题:73. 矩阵置零
  • LeetCode第83题:83. 删除排序链表中的重复元素
  • LeetCode第206题:206. 反转链表
  • LeetCode第92题:92. 反转链表 II
  • LeetCode第121题:121. 买卖股票的最佳时机
  • LeetCode第122题:122. 买卖股票的最佳时机 II
  • LeetCode第123题:123. 买卖股票的最佳时机 III
  • LeetCode第125题:125. 验证回文串
  • LeetCode第134题:134. 加油站
  • LeetCode第135题:135. 分发糖果
  • LeetCode第141题:141. 环形链表
  • LeetCode第142题:142. 环形链表 II
  • LeetCode第152题:152. 乘积最大子数组
  • LeetCode第153题:153. 寻找旋转排序数组中的最小值
  • LeetCode第160题:160. 相交链表
  • LeetCode第187题:187. 重复的DNA序列
  • LeetCode第198题:198. 打家劫舍
  • LeetCode第200题:200. 岛屿数量
  • LeetCode第215题:215. 数组中的第K个最大元素
  • LeetCode第217题:217. 存在重复元素
  • LeetCode第219题:219. 存在重复元素 II
  • LeetCode第238题:238. 除自身以外数组的乘积
  • LeetCode第242题:242. 有效的字母异位词
  • LeetCode第283题:283. 移动零
  • LeetCode第328题:328. 奇偶链表
  • LeetCode第349题:349. 两个数组的交集
  • LeetCode第419题:419. 甲板上的战舰
  • LeetCode第445题:445. 两数相加 II
  • LeetCode第509题:509. 斐波那契数
  • LeetCode第680题:680. 验证回文字符串 Ⅱ
  • LeetCode第695题:695. 岛屿的最大面积
  • LeetCode第704题:704. 二分查找
  • LeetCode第733题:733. 图像渲染
  • LeetCode第796题:796. 旋转字符串
  • LeetCode第836题:836. 矩形重叠
  • LeetCode第844题:844. 比较含退格的字符串
  • LeetCode第876题:876. 链表的中间结点
  • LeetCode第904题:904. 水果成篮
  • LeetCode第905题:905. 按奇偶排序数组
  • LeetCode第922题:922. 按奇偶排序数组 II

LeetCode第1题:1. 两数之和


解法1:时间复杂度为O(n*n) 空间复杂度为O(1)

var twoSum = function(nums, target) {//给定一个nums,给定一个target,设定1个空数组用来存放下标//let result = [];//在nums中遍历,找到和为target的两个数,且这两个数不能为同一个元素,即下标不可相同for(let i=0;i<nums.length;i++){for(let j=i+1;j<nums.length;j++){if(nums[i] + nums[j] == target && i!=j){//返回这两个数的下标的数组return [i,j];}}}
};

解法2:时间复杂度为O(n) 空间复杂度为O(n)

var twoSum = function(nums,target){const map = new Map();for(let i = 0;i < nums.length;i++){const complement = target - nums[i];if(map.has(complement)){return [map.get(complement),i];}else{map.set(nums[i],i);}}return [];
}

LeetCode第2题:2. 两数相加


代码:

var addTwoNumbers = function(l1,l2){let dummy = new ListNode();let curr = dummy;let carry = 0;while(l1 !==null || l2 !==null){let sum = 0;if(l1){sum += l1.val;l1 = l1.next;}if(l2){sum += l2.val;l2 = l2.next;}sum +=carry;curr.next = new ListNode(sum % 10);carry = Math.floor(sum/10);curr = curr.next;}if(carry>0){curr.next = new ListNode(carry);}return dummy.next;
}

LeetCode第3题:3.无重复字符的最长子串


思路:

方法:sliding window(滑动窗口算法)

  1.创建一个set2.两个指针,第一个指向字符串的开头(j),第二个随着for循环遍历字符串(i)3.如果set里没有s(i),说明目前为止还没有重复的字符,把s(i)添加到set里,然后更新最大不重复字符的数量4.如果set里有s(i),则从set里开始删除s(i),并且递增j,再检查set里是否有s(i)5.重复步骤3和4,直到遍历完整个字符串

代码:

var lengthOfLongestSubstring = function(s){const set = new Set();let i = 0,j = 0,maxLength = 0;if(s.length === 0){return 0;}for(i;i<s.length;i++){if(!set.has(s[i])){set.add(s[i]);maxLength = Math.max(maxLength,set.size)}else{while(set.has(s[i])){set.delete(s[j]);j++;}set.add(s[i]);}}return maxLength;
};

LeetCode第5题:5. 最长回文子串


思路:

有三种情况:
1.长度小于2,直接返回
2.奇数个,有中间字符
3.偶数个,没有中间字符

 1.如果字符串长度小于2,直接返回字符串2.定义两个变量,一个start存储当前找到的最大回文字符串的起始位置,另一个maxLength记录字符串的长度(终止位置就是start+maxLength)3.创建一个helper function,判断左边和右边是否越界,同时最左边的字符是否等于最右边的字符。如果以上三个条件都满足,则判断是否需要更新回文字符串最大长度及最大字符串的起始位置。然后将left--、right++,继续判断,直到不满足三个条件之一4.遍历字符串,每个位置调用helper function两遍,第一遍检查i-1,i+1,第二遍检查i、i+1(为什么要检查两遍?答:奇数/偶数)

代码:

var longestPalindrome = function(s){if(s.length<2){return s;}let start = 0;let maxLength = 1;function expandAroundCenter(left,right){while(left>=0 && right<s.length && s[left]===s[right]){if(right - left + 1 > maxLength){maxLength = right - left +1;start = left;}left--;right++;}}for(let i=0;i<s.length;i++){expandAroundCenter(i-1,i+1);expandAroundCenter(i,i+1);}return s.substring(start,start+maxLength);
};

LeetCode第11题:11. 盛最多水的容器

/*** @param {number[]} height* @return {number}*/
var maxArea = function(height) {let left = 0, right = height.length - 1;let max = 0;while(left < right){let maxAll = (right - left) * Math.min(height[left],height[right]);if(height[left] <= height[right]){left++;max = Math.max(max,maxAll);}else{right--;max = Math.max(max,maxAll);}}return max;
};//简化版
var maxArea = function(height) {let left = 0;let right = height.length - 1;let max = 0;while(left < right) {let temp = (right - left) * Math.min(height[left], height[right]);max = Math.max(temp, max);if (height[left] <= height[right]) {left++;} else {right--;}}return max;
};

LeetCode第15题:15. 三数之和


思路:

1.给数组排序
2.遍历数组,从0遍历到length-2为什么?答:防止越界
3.如果当前的数字等于前一个数字,则跳过这个数为什么?答:避免重复数组出现
4.如果数字不同,则设置start= i+1,end=length-1,查看i,start,end三个数的和比0大还是小,· 如果比0小,start++,· 如果比0大,end--· 如果等于0,则把这三个数添加到结果里
5.返回结果

代码:

var threeSum = function(nums) {const result = [];nums.sort((a,b)=>{return a-b;})for(let i=0;i<nums.length-2;i++){if(i===0 || nums[i] !== nums[i-1]){let start = i+1,end = nums.length-1;while(start < end){if(nums[i] + nums[start] + nums[end] === 0){resule.push([nums[i],nums[start],nums[end]]);start++;end--;while(start < end && nums[start] === nums[start-1]){start++;}while(start < end && nums[end] === nums[end+1]){end--;}}else if(nums[i] + nums[start] + nums[end] < 0){start++;}else{end--;}}}}return result;
};

LeetCode第17题:17. 电话号码的字母组合


代码:

// dfs,回溯算法
var letterCombinations = function(digits) {if (digits.length === 0) return [];let res = [];const map = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'};const dfs = (curStr, i) => {if (i > digits.length -1) {res.push(curStr);return;}const letters = map[digits[i]]for (letter of letters) {dfs(curStr + letter, i+1);}}dfs('', 0);return res;
};

LeetCode第19题:19. 删除链表的倒数第 N 个结点


思路:

   1.在第一个结点之前设置一个dummy结点,避免只有一个元素无法操作2.设置两个指针,分别为n1,n2,开始都指向dummy3.两种方法1)将n2结点移动n个距离,然后n1,n2同时向后移,当n2移动到最后一个元素即n2.next为null的时候,删除当前n1.next即n1.next = n1.next.nextfor(let i=0;i<n;i++){n2 = n2.next;}while(n2.next !== null){n1 = n1.next;n2 = n2.next;}2)将n2结点移动n+1个距离,然后n1,n2同时向后移,当n2为null时, 删除当前n1.next即n1.next = n1.next.nextfor(let i=0;i<=n;i++){n2 = n2.next;}while(n2 !== null){n1 = n1.next;n2 = n2.next;}

代码:

var removeNthFromEnd = function(head, n) {let dummy = new ListNode();dummy.next = head;let n1 = dummy;let n2 = dummy;for(let i=0;i<=n;i++){n2 = n2.next;}while(n2 !== null){n1 = n1.next;n2 = n2.next;}n1.next = n1.next.next;return dummy.next;
};

LeetCode第20题:20. 有效的括号


思路:

1.创建一个HashMap,把括号配对放进去
2.创建一个stack(array、栈),for循环遍历字符串,对于每一个字符,如果map里有这个key,那说明它是个左括号,从map里取得相对应的右括号(为什么?),把它push进stack里。否则的话,它就是右括号,需要pop出stack里的第一个字符,然后看它是否等于当前的字符。如果不相符,则返回false
3.循环结束后,如果stack不为空,说明还剩一些左括号没有被闭合,返回false。否则返回true。

代码:

var isValid = function(s) {const mappings = new Map();mappings.set("(" , ")");mappings.set("[" , "]");mappings.set("{" , "}");const stack = [];for(let i=0;i<s.length;i++){if(mappings.has(s[i])){stack.push(mappings.get(s[i]));}else{if(stick.pop() !== s[i]){return false;}}}if(stack.length !== 0){return false;}return true;
};

LeetCode第21题:21. 合并两个有序链表


代码:

var mergeTwoLists = function(l1, l2) {let curr = new ListNode();let dummy = curr;while(l1 !== null && l2 !== null){if(l1.val < l2.val){curr.next = l1;l1 = l1.next;}else{curr.next = l2;l2 = l2.next;}curr = curr.next;}if(l1 !== null){curr.next = l1;}if(l2 !== null){curr.next = l2;}return dummy.next;
};

LeetCode第24题:24. 两两交换链表中的节点


思路:

  1. n1 = p.next;
  2. n2 = p.next.next;
  3. p.next = n2;
  4. n1.next = n2.next;
  5. n2.next = n1;
  6. p = n1;

代码:

var swapPairs = function(head) {let dummy = new ListNode();dummy.next = head;let current = dummy;// n1,n2均不为0while(current.next !== null && current.next.next !== null){let n1 = current.next;let n2 = current.next.next;current.next = n2;n1.next = n2.next;n2.next = n1;current = n1;}return dummy.next;
};

LeetCode第49题:49. 字母异位词分组


思路:

1.检查是否为空数组
2.建立一个长度为26的数组,起始值为0
3.遍历所有字符串,将字符出现的频率放到数组的对应位置里(ASCII)
4.遍历数组,按照相同字母出现频率表进行分组归类(hashMap)
5.遍历map,将结果返回

纠错:join里面的分隔符改成别的例如 . -

测试用例如果是【bdddddddddd, bbbbbbbbbbc】的话key会相同 会报错

0, 1, 0, 10, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0

010100000000000000000000000

0, 10, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0

010100000000000000000000000
Map(1) {
010100000000000000000000000 = 【 bdddddddddd, bbbbbbbbbbc 】
}

代码:

var groupAnagrams = function(strs) {if(strs.length === 0){return [];}const map = new Map();for(const str of strs){const characters = Array(26).fill(0);for(let i=0;i<str.length;i++){//console.log(str[i]);   const ascii = str.charCodeAt(i) - 97;//console.log(str.charCodeAt(i));//console.log(ascii);characters[ascii]++;}//const key = characters.join("");const key = characters.join(".");if(map.has(key)){//map.set(key,map.get(key.push(str)))map.set(key,[...map.get(key),str]);}else{map.set(key,[str]);}}const result = [];for(const arr of map){result.push(arr[1]);    // 0是键,1是键值}return result;
};

LeetCode第53题:53. 最大子序和


思路:

两次判断:
1.将新的数加入到前面的数组中,还是舍弃之前的数组新开一个数组
2.判断最大值

代码:

var maxSubArray = function(nums) {const memo = [];memo[0] = nums[0];for(let i=1;i<nums.length;i++){memo[i] = Math.max(nums[i] + memo[i-1],nums[i]);}let max = nums[0];for(let i=1;i<memo.length;i++){max = Math.max(max,memo[i]);}return max;
};

LeetCode第54题:54. 螺旋矩阵


思路:

1.如果数组为空,返回空数组
2.定义4个边界以及当前方向
3.当左边界小于等于右边界,且上边界小于等于下边界时,执行while循环按照右,下,左,上的顺序,依次将路径上的字符添加到结果里
4.while循环结束后,返回结果

代码:

var spiralOrder = function(matrix) {if(matrix.length === 0){return [];}let top = 0;let bottom = matrix.length - 1;let left = 0;let right = matrix[0].length - 1;let direction = 'right';let result = [];/* [1 , 2 , 3 , 4],[5 , 6 , 7 , 8],[9 , 10, 11 ,12]*/while(left <= right && top <= bottom){if(direction === 'right'){for(let i=left;i<=right;i++){result.push(matrix[top][i]);}top++;direction = 'down';}else if(direction === 'down'){for(let i=top;i<=bottom;i++){result.push(matrix[i][right]);}right--;direction = 'left';}else if(direction === 'left'){for(let i=right;i>=left;i--){result.push(matrix[bottom][i]);}bottom--;direction = 'top';}else if(direction === 'top'){for(let i=bottom;i>=top;i--){result.push(matrix[i][left]);}left++;direction = 'right';}}return result;
};

LeetCode第55题:55. 跳跃游戏


解法1:递归版(动态规划)

var canJump = function(nums) {const totalLength = nums.length;const memo = Array(totalLength).fill(0);//dpmemo[totalLength - 1] = 1;function jump(position){if(memo[position] === 1){return true;}else if(memo[position] === -1){return false;}const maxJump = Math.min(position + nums[position],totalLength - 1)for(let i=position+1;i<=maxJump;i++){const jumpReault = jump(i);if(jumpReault === true){memo[position] = 1;return true;}}memo[position] = -1;return false;}let result = jump(0);return result;
};

解法2:优化版1(bottom-up)

//bottom-up思路:
//从后往前判断,只要倒数第二个能到达最后一个,
//就判断从前面哪个能到倒数第二个,再继续依次向前推,直到数组最开始
var canJump = function(nums) {const totalLength = nums.length;const memo = Array(totalLength).fill(0);//dpmemo[totalLength - 1] = 1;for(let i=totalLength - 2;i>=0;i--){const maxJump = Math.min(totalLength-1,i+nums[i]);for(let j=i+1;j<=maxJump;j++){if(memo[j] === 1){memo[i] = 1;break;}}}if(memo[0] === 1){return true;}else{return false;}
};

解法3:优化版2(贪心算法)

//贪心算法思路:
//依旧从后往前判断,刚开始的maxJump=nums.length - 1,
//判断索引+该索引对应的值是否大于maxJump,
//大于则maxJump就为该索引i,
//循环结束如果maxJump为0,则说明了到达了第一个数,证明成功了
var canJump = function(nums) {let maxJump = nums.length - 1;for(let i=nums.length-2;i>=0;i--){if(i+nums[i] >= maxJump){maxJump = i;}}return maxJump === 0;
};

LeetCode第56题:56. 合并区间


思路:

1.将数组中的区间按照起始位置排序
2.用curr数据记录当前合并的最大区间,遍历数组中的每一个区间,如果当前区间的起始位置小于curr的终点位置,则可以继续合并,所以合并并更新curr的起始和终止位置。如果当前区间的起始位置大于curr的终止位置,则无法合并所以将curr加入到result里,并用当前的区间替换curr的值

代码:

var merge = function(intervals) {if(intervals.length < 2){return intervals;}intervals.sort((a,b)=>{return a[0] - b[0];})let curr = intervals[0];let result = [];for(let interval of intervals){if(curr[1] >= interval[0]){curr[1] = Math.max(curr[1],interval[1]);}else{result.push(curr);curr = interval;}}if(curr.length !== 0){result.push(curr);}return result;
};

LeetCode第62题:62. 不同路径


代码:

//动态规划//到达每个格子的路劲总数等于到达该格子上面和左面的路径之和//依次累加
var uniquePaths = function(m, n) {const memo = [];//建立一个二维数组for(let i=0;i<n;i++){memo.push([]);}for(let row=0;row<n;row++){memo[row][0] = 1;}for(let col=0;col<m;col++){memp[0][col] = 1;}for(let row=1;row<n;row++){for(let col=1;col<m;col++){memo[row][col] = memo[row-1][col] + memo[row][col-1];}}return memo[n-1][m-1];
};

LeetCode第66题:66. 加一


代码:

var plusOne = function(digits) {for(let i=digits.length-1;i>=0;i--){if(digits[i] !== 9){digits[i]++;return digits}else{digits[i] = 0;}}const result = [1,...digits];return result;
};

LeetCode第70题:70. 爬楼梯


代码:

var climbStairs = function(n) {//memo[i-2] = 2//memo[i-1] = 3//memo[i] = memo[i-1] + memo[i-2] = 5const memo = [];memo[1] = 1;memo[2] = 2;//memo[3] = 3;//memo[4] = 5;for(let i=3;i<=n;i++){memo[i] = memo[i-2] + memo[i-1];}return memo[n];
};

LeetCode第73题:73. 矩阵置零


思路:

1.检查并标记第一行和第一列是否有0(firstColHasZero和firstRowHashZero)
2.使用第一行和第一列,来标记其余行列是否含有0
3.接下来,利用第一行和第一类的标0情况,将matrix中的数字标0
4.最后,处理第一行和第一列如果firstColHasZero等于true,将第一列全设为0如果firstRowHashZero等于true,将第一行全设为0

代码:

var setZeroes = function(matrix) {let firstColHashZero = false;let firstRowHashZero = false;//判断第一列是否有0for(let i=0;i<matrix.length;i++){if(matrix[i][0] === 0){firstColHashZero = true;}}//判断第一行是否有0for(let i=0;i<matrix.length;i++){if(matrix[0][i] === 0){firstRowHashZero = true;}}//排除第一行和第一列,标记其余行列是否含有0,//有0则将该0所对应的行、列所在的第一行、第一列数字标0for(let row=1;row<matrix.length;row++){for(let col=1;col<matrix[0].length;col++){if(matrix[row][col] === 0){matrix[row][0] = 0;matrix[0][col] = 0;}}}//利用第一行和第一类的标0情况,将matrix中的数字标0for(let row=1;row<matrix.length;row++){for(let col=1;col<matrix[0].length;col++){if(matrix[row][0] === 0 || matrix[0][col] === 0){matrix[row][col] = 0;}}}// 如果firstColHasZero等于true,将第一列全设为0if(firstColHashZero){for(let i=0;i<matrix.length;i++){matrix[i][0] = 0;}}//如果firstRowHashZero等于true,将第一行全设为0if(firstRowHashZero){for(let i=0;i<matrix[o].length;i++){matrix[0][i] = 0;}}return matrix;
};

LeetCode第83题:83. 删除排序链表中的重复元素


思路:

1.建立一个指针遍历整个链表
2.如果前一个和后一个相等,则删除下一个指针,否则指针后移

代码:

var deleteDuplicates = function(head) {let current = head;while(current !== null && current.next !==null){if(current.val === current.next.val){current.next = current.next.next;}else{current = current.next;}}return head;
};

LeetCode第206题:206. 反转链表


解法1:普通版

var reverseList = function(head) {let prev = null;let curr = head;let next = head;while(curr !== null){next = curr.next;curr.next = prev;prev = curr;curr = next;}return prev;
};

解法2:优化版

var reverseList = function(head) {let prev = null;let curr = head;while(curr !== null){[curr.next,prev,curr] = [prev,curr,curr.next];}return prev;
};

LeetCode第92题:92. 反转链表 II


解法1:普通版

//思路://1、反转m至n之间的链表//2、将反转后的链表与原链表拼接
var reverseBetween = function(head, left, right) {let prev = null;let curr = head;let next = head;for(let i=1;i<left;i++){prev = curr;curr = curr.next;}let prev2 = prev;let curr2 = curr;for(let i=left;i<=right;i++){next = curr.next;curr.next = prev;prev = curr;curr = next;}if(prev2 !== null){prev2.next = prev;}else{head = prev;}curr2.next = curr;return head;
};

解法2:简化版

//思路://1、反转m至n之间的链表//2、将反转后的链表与原链表拼接
var reverseBetween = function(head, left, right) {let prev = null;let curr = head;for(let i=1;i<left;i++){prev = curr;curr = curr.next;}let prev2 = prev;let curr2 = curr;for(let i=left;i<=right;i++){[curr.next,prev,curr] = [prev,curr,curr.next]}if(prev2 !== null){prev2.next = prev;}else{head = prev;}curr2.next = curr;return head;
};

LeetCode第121题:121. 买卖股票的最佳时机


思路:

1.设定两个变量,一个用来存储目前所在点左半边的最小点,另一个用来存储目前利润的最大值
2.遍历数组首先判断minPrice是否是最小值再判断maxProfit是否是最大值

代码:

var maxProfit = function(prices) {if(prices.length === 0){return 0;}let minPrice = prices[0];let maxProfit = 0;for(let i=0;i<prices.length;i++){if(prices[i] < minPrice){minPrice = prices[i];}else if(prices[i] - minPrice > maxProfit){maxProfit = prices[i] - minPrice;}}return maxProfit;
};

LeetCode第122题:122. 买卖股票的最佳时机 II


思路:

思路1:1.向上的曲线,底端买入,顶端卖出2.向下的曲线不买也不卖
思路2:将每一项和它的后一项进行对比,如果小于后一项,就把之差加到利润中

代码:

var maxProfit = function(prices) {if(prices.length === 0){return 0;}//思路1!!!/* let profit = 0, valley = prices[0], peak = prices[0];let i = 0;while(i<prices.length - 1){while(i<prices.length - 1 && prices[i] >= prices[1+1]){i++;}valley = prices[i];while(i<prices.length - 1 && prices[i] <= prices[i+1]){i++;}peak = prices[i];profit += peak - valley;} *///思路2!!!let profit = 0; for(let i=0;i<prices.length - 1;i++){if(prices[i] < prices[i+1]){profit += prices[i+1] - prices[i];}}return profit;
};

LeetCode第123题:123. 买卖股票的最佳时机 III


代码:

var maxProfit = function(prices) {if(prices.length === 0){return 0;}//二维数组,行,列const dp = Array.from(Array(3),()=>new Array(prices.length));//将第一行,第一列都设为0for(let i=0;i<prices.length;i++){dp[0][i] = 0;}for(let i=0;i<3;i++){dp[i][0] = 0;}for(let i=1;i<3;i++){let maxProfit = -prices[0];for(let j=1;j<prices.length;j++){dp[i][j] = Math.max(dp[i][j-1],prices[j]+maxProfit);maxProfit = Math.max(maxProfit,dp[i-1][j] - prices[j]);}}return dp[2][prices.length-1];};

LeetCode第125题:125. 验证回文串


思路:

1.用正则表达式去掉非数字和字母
2.如果字符串长度小于2,返回true
3.定义两个指针,一个在字符串开头,一个在字符串结尾
4.建议一个while循环,当left<right时执行循环,如果在任意地点s[left] !== s[right],return false,否则left++,right--,继续执行循环
5.当循环完成后都没有return false,则return true

代码:

var isPalindrome = function(s) {s = s.toLowerCase().replace(/[\W_]/g,"");if(s.length < 2){return true;}let left = 0;let right = s.length - 1;while(left < right){if(s[left] !== s[right]){return false;}left++;right--;}return true;
};

LeetCode第134题:134. 加油站


思路:

1.首先将所有加油站的油加起来,再把需要消耗的油全部加起来,如果前者 小于后者,则能走完一圈,继续算法,否则直接返回-1
2.从某个点开始逐步判断,如果走不通则从走不通的那个点重新开始判断

代码:

var canCompleteCircuit = function(gas, cost) {let totalGas = 0;let totalCost = 0;for(let i=0;i<gas.length;i++){totalCost += cost[i];totalGas += gas[i];}if(totalCost > totalGas){return -1; }let currentGas = 0;let start = 0;for(let i=0;i<gas.length;i++){currentGas = currentGas - cost[i] + gas[i];if(currentGas < 0){currentGas = 0;start = i + 1;}}return start;
};

LeetCode第135题:135. 分发糖果

// 贪心算法
var candy = function(ratings) {const n = ratings.length;const left = new Array(n).fill(0);//从左向右遍历,找出右边比左边大的for(let i=0; i<n; i++) {if (i > 0 && ratings[i] > ratings[i-1]) {left[i] = left[i-1] + 1;} else {left[i] = 1;}}//从右向左遍历,找出左边比右边大的let right = 0, res = 0;for(let i=n-1; i>-1;i--) {if (i < n-1 && ratings[i] > ratings[i+1]) {right++;} else {right = 1;}res += Math.max(left[i], right);}return res;
};

LeetCode第141题:141. 环形链表


思路:

 1.设定两个指针,快指针每次走两步,慢指针每次走一步2.如果存在环,快指针和慢指针总会重合3.慢指针比快指针快几步,快指针就能几步追上慢指针

代码:

var hasCycle = function(head) {  if(head === null){return false;}let slow = head;let fast = head;while(fast.next !== null && fast.next.next !== null){slow = slow.next;fast = fast.next.next;if(slow === fast){return true;}}return false;
};

LeetCode第142题:142. 环形链表 II


代码:

var detectCycle = function(head) {    if(head === null){return null;}let slow = head;let fast = head;let isCycle = false;while(fast.next !== null && fast.next.next !== null){slow = slow.next;fast = fast.next.next;if(slow === fast){isCycle = true;break;}}if(!isCycle){return null;}fast = head;while(slow !== fast){slow = slow.next;fast = fast.next;}return fast;
};

LeetCode第152题:152. 乘积最大子数组


代码:

var maxProduct = function(nums) {const maxProductMemo = [];const minProductMemo = [];maxProductMemo[0] = nums[0];minProductMemo[0] = nums[0];let max = nums[0];for(let i=1;i<nums.length;i++){//乘minProductMemo的原因在于nums[i]可能是个负值,//minProductMemo也可能是负值,负负得正maxProductMemo[i] = Math.max(nums[i],nums[i]*maxProductMemo[i-1],nums[i]*minProductMemo[i-1]);minProductMemo[i] = Math.min(nums[i],nums[i]*maxProductMemo[i-1],nums[i]*minProductMemo[i-1]);max = Math.max(max,maxProductMemo[i]);}return max;
};

LeetCode第153题:153. 寻找旋转排序数组中的最小值


思路:

1.如果数组长度为1,返回唯一的一个数
2.定义两个指针,第一个left指向数组开头,第二个right指向数组结尾
3.检查数组是否被翻转,如果没有,则返回数组里的第一个数
4.当left小于right时,取中间作为mid进行二分搜索,如果mid的左边一个数大于mid,或者mid右边的一个数小于mid,则返回mid
5.否则的话,如果left所在的数小于mid,则将left右移至mid+1位置(砍掉左半边)
6.否则的话,将right左移至mid-1的位置(砍掉右半边)

代码:

var findMin = function(nums) {if(nums.length === 1){return nums[0];}let left = 0, right = nums.length - 1;if(nums[right] > nums[0]){return nums[0];}while(left < right){let mid = Math.floor(left + (right - left) / 2);if(nums[mid] > nums[mid + 1]){return nums[mid + 1];}if(nums[mid - 1] > nums[mid]){return nums[mid];}if(nums[mid] > nums[left]){left = mid + 1;}else{right = mid - 1;}}
};

LeetCode第160题:160. 相交链表


代码:

var getIntersectionNode = function(headA, headB) {let n1 = headA;let n2 = headB;while(n1 !== n2){if(n1 === null){n1 = headB;}else{n1 = n1.next;}if(n2 === null){n2 = headA;}else{n2 = n2.next;}}return n1;
};

LeetCode第187题:187. 重复的DNA序列


解法1:

var findRepeatedDnaSequences = function(s) {const map = new Map();const result = [];let i = 0;while(i + 10 <= s.length){const dna = s.substring(i,i+10);if(map.get(dna) === undefined){map.set(dna,1);}else if(map.get(dna) === 1){map.set(dna,2);result.push(dna);}else{map.get(dna,map.get(dna) + 1);}i++;}return result;
};

解法2:

var findRepeatedDnaSequences = function(s) {const set = new Set(),result = new Set();let i = 0;while(i + 10 <= s.length){const dna = s.substring(i,i+10);if(set.has(dna)){result.add(dna);}else{set.add(dna);}i++;}return Array.from(result);
};

LeetCode第198题:198. 打家劫舍


解法1:

var rob = function(nums) {if(nums.length === 0){return 0;}if(nums.length === 1){return nums[0];}const memo = [];memo[0] = nums[0];memo[1] = Math.max(nums[0],nums[1]);for(let i=2;i<nums.length;i++){memo[i] = Math.max(nums[i] + memo[i-2],memo[i-1]);}return memo[nums.length - 1];
};

解法2:

var rob = function(nums) {if(nums.length === 0){return 0;}if(nums.length === 1){return nums[0];}let prev2 = nums[0];let prev1 = Math.max(nums[0],nums[1]);for(let i=2;i<nums.length;i++){const temp = Math.max(nums[i] + prev2,prev1);prev2 = prev1;prev1 = temp;}return prev1;
};

LeetCode第200题:200. 岛屿数量

代码:

//bfs -- 广度优先搜索(上下左右一次处理完,往外扩散再上下左右)
//dfs -- 深度优先搜索(上下左右,先把一条路走完,再返回去处理)
var numIslands = function(grid) {let count = 0;function dfs(row,col){if(row<0 || row>=grid.length || col<0 || col>=grid[0].length || grid[row][col] === '0'){return;}grid[row][col] = '0';dfs(row-1 , col);dfs(row+1 , col);dfs(row, col-1);dfs(row, col+1);}for(let row=0;row<grid.length;row++){for(let col=0;col<grid[0].length;col++){if(grid[row][col] === '1'){count++;dfs(row,col);}}}return count;
};

LeetCode第215题:215. 数组中的第K个最大元素

// 堆排序

LeetCode第217题:217. 存在重复元素

代码:

var containsDuplicate = function(nums) {const set = new Set();for(let i=0;i<nums.length;i++){if(set.has(nums[i])){return true;}set.add(nums[i]);}return false;
};

LeetCode第219题:219. 存在重复元素 II


代码:

var containsNearbyDuplicate = function(nums, k) {const map = new Map();for(let i=0;i<nums.length;i++){if(map.has(nums[i]) && (i - map.get(nums[i]) <= k)){return true;}else{map.set(nums[i],i);}}return false;
};

LeetCode第238题:238. 除自身以外数组的乘积


代码:

var productExceptSelf = function(nums) {const result = Array(nums.length).fill(1);let product = 1;for(let i=0;i<nums.length;i++){result[i] = result[i] * product;product = product * nums[i];}product = 1;for(let i=nums.length - 1;i>=0;i--){result[i] = result[i] * product;product = product * nums[i];}return result;
};

LeetCode第242题:242. 有效的字母异位词


思路:

1.如果两个数组长度不一致,则返回false
2.创建一个map,用来存储每个字符出现的次数
3.对于第一个单词的每个字母,也就是s1[i],在map里将出现次数+1对于第二个单词的每个字母,也就是s2[i],在map里将出现次数-1
4.遍历完成后,检查map里的每一个字母出现的次数是不是0,如果有一个非0的字母,返回false,否则返回true

代码:

var isAnagram = function(s, t) {if(s.length !== t.length){return false;}const map = new Map();for(let i=0;i<s.length;i++){if(map.has(s[i])){map.set(s[i],map.get(s[i])+1);}else{map.set(s[i],1);}if(map.has(t[i])){map.set(t[i],map.get(t[i])-1);}else{map.set(t[i],-1);}}for(const letter of map){if(letter[1] !== 0){return false;}}return true;
};

LeetCode第283题:283. 移动零


思路:

将非0的数字移到数字开头,然后将剩余的位置补上0,用i和j控制

代码:

var moveZeroes = function(nums) {let j = 0;for(let i=0;i<nums.length;i++){if(nums[i] !== 0){nums[j] = nums[i];j++;}}for(i=j;i<nums.length;i++){nums[i] = 0;}return nums;
};

LeetCode第328题:328. 奇偶链表


代码:

var oddEvenList = function(head) {if(head === null){return null;}if(head.next === null){return head;}let odd = head;let even = head.next;let evenHead = head.next;while(even !== null && even.next !== null){odd.next = odd.next.next;odd = odd.next;even.next = even.next.next;even = even.next;}odd.next = evenHead;return head;
};

LeetCode第349题:349. 两个数组的交集


代码:

//交集即nums1中有,nums2中也有的元素
var intersection = function(nums1, nums2) {const result = new Set();const set = new Set(nums2);/* for(num of nums2){set.add(num);} */for(num of nums1){//数组搜索值,复杂度O(n)//Set Map --- .has  复杂度O(1)if(set.has(num)){result.add(num);}}return Array.from(result);
};

LeetCode第419题:419. 甲板上的战舰


解法1:把相邻的X全都转化成 .

var countBattleships = function(board) {let result = 0;for(let row=0;row<board.length;row++){for(let col=0;col<board[0].length;col++){if(board[row][col] === 'X'){result++;dfs(row,col);}}}function dfs(row,col){if(row<0 || row>=board.length || col<0 || col>=board[0].length || board[row][col] !== 'X'){return;}board[row][col] = '.';dfs(row-1,col);dfs(row+1,col);dfs(row,col+1);dfs(row,col-1);}return result;
};

解法2:不管相邻的X,继续往下进行

var countBattleships = function(board) {let result = 0;for(let row=0;row<board.length;row++){for(let col=0;col<board[0].length;col++){if(board[row][col] === 'X'){//左面if(row>0 && board[row-1][col] === 'X'){continue;}//上面if(col>0 && board[row][col-1] === 'X'){continue;}result++;}}}return result;
};

LeetCode第445题:445. 两数相加 II


思路:

1.将这两个链表里的数都放到栈里,然后依次相加,注意存储进位
2.将第一个和作为链表的最后一项,把它的下一项设为null,即curr的初始值
3.然后把node赋值给curr,依次循环
4.检查最后的进位如果为1,继续上述操作,将1设为链表第一项

代码:

var addTwoNumbers = function(l1, l2) {const stack1 = [], stack2 = [];while(l1 !== null){stack1.push(l1.val);l1 = l1.next;}while(l2 !== null){stack2.push(l2.val);l2 = l2.next;}let carry = 0, curr = null;while(stack1.length!==0 || stack2.length!==0){let sum = 0;if(stack1.length !== 0){sum += stack1.pop();// const sum = stack1.pop();// sum = sum + num;}if(stack2.length !== 0){sum += stack2.pop();// const num = stack1.pop();// sum = sum + num;}sum += carry;const node = new ListNode(sum % 10);carry = Math.floor(sum / 10);node.next = curr;curr = node;}if(carry !== 0){const node = new ListNode(carry);node.next = curr;curr = node;}return curr;
};

LeetCode第509题:509. 斐波那契数


解法1:top-down

var fib = function(n) {if(n <= 1){return n;}const cache = [];cache[0] = 0;cache[1] = 1;function memoize(number){if(cache[number] !== undefined){return cache[number];}cache[number] = memoize(number-1) + memoize(number-2);return cache[number];}const result = memoize(n);return result;
};

解法2:bottom-up

var fib = function(n) {if(n <= 1){return n;}const cache = [];cache[0] = 0;cache[1] = 1;for(let i=2;i<=n;i++){cache[i] = cache[i-1] + cache[i-2];}return cache[n];
};

解法3:bottom-up(空间复杂度优化)

var fib = function(n) {if(n <= 1){return n;}let prev2 = 0;let prev1 = 1;let result = 0;for(let i=2;i<=n;i++){result = prev1 + prev2;prev2 = prev1;prev1 = result;}return result;
};

LeetCode第680题:680. 验证回文字符串 Ⅱ


代码:

var validPalindrome = function(s) {function isPalindrome(left,right){while(left < right){if(s[left] !== s[right]){return false;}left++;right--;}return true;}let left = 0;let right = s.length - 1;while(left < right){if(s[left] !== s[right]){const result = isPalindrome(left+1,right) || isPalindrome(left,right-1);return result;}left++;right--;}return true;
};

LeetCode第695题:695. 岛屿的最大面积


代码:

var maxAreaOfIsland = function(grid) {let result = 0;for(let row=0;row<grid.length;row++){for(let col=0;col<grid[0].length;col++){if(grid[row][col] === 1){const count = dfs(row,col);result = Math.max(count,result);}}}function dfs(row,col){if(row<0 || row>=grid.length || col<0 || col>=grid[0].length || grid[row][col] === 0){return 0;}grid[row][col] = 0;let count = 1;count += dfs(row-1,col);count += dfs(row+1,col);count += dfs(row,col-1);count += dfs(row,col+1);return count;}return result;
};

LeetCode第704题:704. 二分查找


思路:

1.left=0,right=length-1,mid=left+(right-left)/2
2.当left<=right,如果mid上的值等于target,返回mid,如果小于target,left=mid+1(砍掉左半边),如果大于target,right=mid-1(砍掉右半边)
3.如果while循环结束后都没有找到target,返回-1

代码:

var search = function(nums, target) {let left = 0, right = nums.length - 1;while(left <= right){mid = Math.floor(left + (right - left) / 2);if(nums[mid] === target){return mid;}else if(nums[mid] < target){left = mid + 1;}else{right = mid - 1;}}return -1;
};

LeetCode第733题:733. 图像渲染


代码:

var floodFill = function(image, sr, sc, newColor) {if(image[sr][sc] === newColor){return image;}const oldColor = image[sr][sc];function dfs(sr,sc){if(sr<0 || sr>=image.length || sc<0 || sc>=image[0].length || image[sr][sc] !== oldColor){return;}image[sr][sc] = newColor;dfs(sr-1,sc);dfs(sr+1,sc);dfs(sr,sc-1);dfs(sr,sc+1);}dfs(sr,sc);return image;
};

LeetCode第796题:796. 旋转字符串

代码:

//在s和goal的长度相等的情况下,在s后面再连接上一个s,则所有可能的情况都包含在这个新的字符串中,只需查看这个新字符串中是否包含目标字符串
var rotateString = function(s, goal) {if(s.length !== goal.length){return false;}const str = s + s;return str.includes(goal);
};

LeetCode第836题:836. 矩形重叠


思路:

 rec1右 <= rec2左rec1左 >= rec2右rec1下 >= rec2上rec1上 <= rec2下

代码:

var isRectangleOverlap = function(rec1, rec2) {if(rec1[2]<=rec2[0] || rec1[0]>=rec2[2] || rec1[1]>=rec2[3] || rec1[3]<=rec2[1]){return false;}else{return true;}
};

LeetCode第844题:844. 比较含退格的字符串


代码:

var backspaceCompare = function(s, t) {let i = s.length - 1, j = t.length - 1;let backspaceS = 0, backspaceT = 0;while(i>=0 || j>=0){while(i>=0){if(s[i] === '#'){backspaceS++;i--;}else if(backspaceS > 0){backspaceS--;i--;}else{break;}}while(j>=0){if(t[j] === '#'){backspaceT++;j--;}else if(backspaceT > 0){backspaceT--;j--;}else{break;}}if(s[i] !== t[j]){return false;}if((i<0 && j>=0) || (i>=0 && j<0)){return false;}i--;j--;}return true;};

LeetCode第876题:876. 链表的中间结点


代码:

var middleNode = function(head) {let slow = head;let fast = head;while(fast !== null && fast.next !== null){slow = slow.next;fast = fast.next.next;}return slow;
};

LeetCode第904题:904. 水果成篮


代码:

var totalFruit = function(fruits) {const map = new Map();let max = 1;let j = 0;for(let i=0;i<fruits.length;i++){map.set(fruits[i],i);if(map.size > 2){let minIndex = fruits.length - 1;for(const [fruit,index] of map){if(index < minIndex){minIndex = index;}}map.delete(fruits[minIndex]);j = minIndex + 1;}max = Math.max(max,i-j+1);}return max;
};

LeetCode第905题:905. 按奇偶排序数组


代码:

var sortArrayByParity = function(nums) {let i = 0, j = nums.length - 1;while(i < j){if(nums[i]%2 === 1 && nums[j]%2 === 0){[nums[i],nums[j]] = [nums[j],nums[i]];i++;j--;}// }else if(nums[i]%2 === 0 && nums[j]%2 === 0){//     i++;// }else if(nums[i]%2 === 0 && nums[j]%2 === 1){//     i++;//     j--;// }else{//     j--;// }if(nums[i]%2 === 0){i++;}if(nums[j]%2 === 1){j--;}}return nums;
};

LeetCode第922题:922. 按奇偶排序数组 II

代码:

var sortArrayByParityII = function(nums) {let j = 1;for(let i=0;i<nums.length;i+=2){if(nums[i]%2 === 1){while(nums[j]%2 === 1 && j<nums.length){j+=2;}[nums[i],nums[j]] = [nums[j],nums[i]];}}return nums;
};

LeetCode部分刷题笔记!!!JavaScript!!!相关推荐

  1. leetcode分类刷题笔记

    leetcode分类刷题笔记--基于python3 写在前面 1.做题如果实在想不出时间复杂度比较优的解法,可以先写出暴力解法,尝试在其基础上优化 2.排序.双指针.二分等--经常可以优化时间复杂度 ...

  2. Newcoder和LeetCode七月刷题笔记

    碰到的知识点都总结成笔记了,方便自己学习 牛客编程基础知识点: 1.Ascii码表有多少不同的字符编码? 答:128个.因为使用 2.c++中 操作 double d = 2.3 ;  d>&g ...

  3. Leetcode Math刷题笔记

    165. Compare Version Number blog.csdn.net/crazy1235/a- 66. Plus One 遍历每一位,如果小于9则直接加一return,反之则为0.如果l ...

  4. 力扣(LeetCode)刷题笔记

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

  5. LeetCode Java刷题笔记—876. 链表的中间结点

    876. 链表的中间结点 给定一个头结点为 head 的非空单链表,返回链表的中间结点.如果有两个中间结点,则返回第二个中间结点. 简单难度.使用快慢指针即可,快指针fast每次走2步,慢指针slow ...

  6. LeetCode Java刷题笔记—297. 二叉树的序列化与反序列化

    297. 二叉树的序列化与反序列化 请实现两个函数,分别用来序列化和反序列化二叉树.这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化 ...

  7. 卷进大厂系列之LeetCode刷题笔记:二分查找(简单)

    LeetCode刷题笔记:二分查找(简单) 学算法,刷力扣,加油卷,进大厂! 题目描述 涉及算法 题目解答 学算法,刷力扣,加油卷,进大厂! 题目描述 力扣题目链接 给定一个 n 个元素有序的(升序) ...

  8. 赞!Google 资深软件工程师 LeetCode 刷题笔记首次公开

    有人说写代码就像我们平时开车,仅凭经验你就可以将车开走:但当有一天,这辆车出问题跑不起来的时候,你不懂汽车的运行机制,你要怎么排除和解决问题?所以拥有扎实的数据结构和算法,才能开好编程这辆车. 作为程 ...

  9. Google 资深软件工程师 LeetCode 刷题笔记首次公开

    BAT 等国内的一线名企,在招聘工程师的过程中,对算法和数据结构都会重点考察.但算法易学难精,我的很多粉丝技术能力不错,但面试时总败在算法这一关,拿不到好 Offer.但说实话,数据结构和算法花点时间 ...

最新文章

  1. VSCode 搭建Vue开发环境之Vue CLI
  2. java joptionpanel_JOptionPane用法--java
  3. Opengl-基本章节的学习成果
  4. ElementUI的el-table怎样隐藏某一列
  5. python selenium webdriver方法封装(find_element_by)
  6. Linux 安装Redis全过程日志
  7. Cygwin 的代理设置(同 Linux)
  8. linux dns chroot,chroot DNS 过程(包括一些简单的排错过程)
  9. Content Provider的使用
  10. Qt编译时报堆空间不足
  11. C语言之父Dennis Ritchie告诉你:如何成为世界上最好的程序员?
  12. 小米9008授权账号_小米AI音箱APP的秘密
  13. 规则引擎Drools使用 第二篇Drools规则引擎介绍
  14. pyhive、pyspark配置
  15. MAX30102 高灵敏度脉搏氧器和心率传感器说明书
  16. ionic android n权限,ionic权限问题
  17. SCI论文分区有两种方法
  18. 计算机的隐藏功能应用,关于Mac电脑的8个神奇隐藏功能,你知道几个?
  19. Java笔记(韩顺平Java基础7-8章)
  20. word论文格式管理和孤行控制

热门文章

  1. C语言中将字符数字转换为数值的小技巧和方法
  2. 初学者学习插画原画以后就业方向有哪些?和大家聊聊插画原画师就业、薪资等
  3. 地铁WIFI值28亿?运营商终于不用背锅了
  4. Zabbix5.0前端个性化设置,手把手教你定制Logo
  5. 荷塘趣事计算机作业,【《荷塘趣事》摄影图片】生态摄影_人称开哥_太平洋电脑网摄影部落...
  6. firefox不能正常下载文件
  7. 网络抓包工具wireshark的使用
  8. 邮政收件箱界面html,时尚邮件收件箱UI设计效果
  9. 从0-1的CTF比赛环境搭建过程
  10. Python 判断列表中是否含有给定字符串