算法题
疾风知劲草~
这个作者很懒,什么都没留下…
展开
-
leetcode128 最长连续序列(三种方法)
//方法一:数组先去重后排序,最后遍历查询最长连续序列 // let result = 1,count=1 // if(nums.length==0) return 0 // nums = Array.from(new Set(nums)) // nums.sort((a,b)=>{return a-b }) // for(let i=0;i<nums.length-1;i++){ // if(nums[i+1]==nums[i]+1){ ...原创 2021-04-21 22:22:02 · 188 阅读 · 0 评论 -
leetcode 3 无重复字符的最长子串
无重复字符的最长子串给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度思路:滑动窗口1.创建set集合存放不重复字符,定义左右指针2.右指针每次向右移动一格,直到出现重复字符,将此时左右字符的长度存入ans中3.此时左指针向右移动一格,去掉set集合中的最前面字符4.重复2.3步骤,直到左指针到头5. 返回ansvar lengthOfLongestSubstring = function(s) { let length = s.length let result原创 2021-04-03 16:42:59 · 141 阅读 · 0 评论 -
leetcode146 LRU缓存机制
/* put if(key) 更新节点值 将节点移到链表的头部 else if(缓存满了) 移出最后一个节点,删除它在哈希表中的映射 新建一个节点 在哈希表中增加映射 把节点加到链表头部 get if(key) 返回节点值原创 2021-03-27 22:51:31 · 64 阅读 · 0 评论 -
leetcode142 环形链表||
/* 方法一:哈希表,将节点放入set中,如果set中已经有了这个节点,说明有环,返回即可 */ // let list = new Set() // while(head){ // if(list.has(head)) // return head // list.add(head) // head = head.next // } // return null /*原创 2021-03-27 22:01:14 · 76 阅读 · 0 评论 -
leetcode2 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。思路:1.n1 = 链表1.val n2 = 链表2.val carry = 进位值2.carry = (n1+n2+carry)/10 result.val = (n1+n2+carry)%103.长度短的原创 2021-03-24 10:09:55 · 50 阅读 · 0 评论 -
leetcode160 相交链表
编写一个程序,找到两个单链表相交的起始节点思路:方法一:哈希表1.遍历链表A,将其节点放入哈希表中2.遍历链表B,如果哈希表中存在链表B的元素,返回该元素方法二:双指针1.指针1指向headA,指针2指向headB2.指针1遍历完headA,重定位到headB指针2遍历完headB,重定位到headA3.如果两者相同,则说明必有相交处(PA + AC + PB = PB + AC + PA)var getIntersectionNode = function(headA, headB)原创 2021-03-22 17:18:54 · 157 阅读 · 0 评论 -
leetcode876 链表的中间结点
给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。思路:快慢指针法1.快慢指针指向头节点,快指针运动2步,慢指针运动1步 当fast==null || fast.next==null,慢指针指向中间节点function ListNode(val) { this.val = val; this.next = null;}var middleNode = function(head) { let fast = head原创 2021-03-22 16:46:45 · 115 阅读 · 0 评论 -
leetcode206反转链表
反转一个单链表思路:指针1.创建两个指针p,q 依次反转链表,直到q为nullvar reverseList = function(head) { let p=null let q=head while(q){ let temp = q.next q.next = p p = q q = temp } head.next = null return p};...原创 2021-03-22 11:49:27 · 58 阅读 · 0 评论 -
leetcode348 数组交集
给定两个数组,编写一个函数来计算它们的交集思路:排序+指针1.先排序2.p指针指向nums1[0],q指向nums2[0]3.将较小的那个指针++4.如果两者相等且不等于pre,将其加入新数组,更新prev5.如果一个指针为null,结束循环,返回新数组注意:用好pre进行去重var intersection = function(nums1, nums2) { let result = [] nums1.sort((a,b)=>{return a-b}) nums2原创 2021-03-22 11:28:15 · 77 阅读 · 0 评论 -
leetcode141环形链表
给定一个链表,判断链表中是否有环。思路:1.快慢指针,fast=head.next slow=head2.如果有环,快指针必将追上慢指针 如果没环,fast==null || slow == null return falsevar hasCycle = function(head) { if(head==null || head.next==null) return false let fast = head.next let slow = head while(原创 2021-03-22 10:52:31 · 89 阅读 · 0 评论 -
leetcode21 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。思路:1.添加一个哨兵节点,用l2,l2分别指向链表的开头2.比较两者中较小的那个,将其放入新链表中function ListNode(val, next) { this.val = (val===undefined ? 0 : val) this.next = (next===undefined ? null : next)}var mergeTwoLists = function(原创 2021-03-22 10:39:22 · 62 阅读 · 0 评论 -
leetcode19删除链表的倒数第N个节点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。思路:快慢指针1.建立虚拟节点0,fast向前走n+1步2.fast与slow同步走,这样fast与slow之间相差n3.如果fast==null,说明删除的是头节点4.如果fast!=null,正常处理var removeNthFromEnd = function(head, n) { let dummy = new ListNode(-1,head) let fast = dummy let slow原创 2021-03-22 09:54:36 · 72 阅读 · 0 评论 -
leetcode53 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和思路:dp[i]=max{dp[i-1]+nums[i],nums[i]}var maxSubArray = function(nums) { let length=nums.length let pre=0 let result= nums[0] for(let i=1;i<length+1;i++){ pre=Math.max(nums[i-1],原创 2021-03-20 10:41:38 · 37 阅读 · 0 评论 -
leetcode14 最长公共前缀
var longestCommonPrefix = function(strs) { //先将字符串1设为ans,将ans与字符串2,3,4...比较求公共字符串,最终求得公共字符串 if(!strs.length) return '' let ans=strs[0] for(i=1;i<strs.length;i++){ let j=0; for(;j<ans.length&&j<strs[i].length原创 2021-03-19 19:57:34 · 58 阅读 · 0 评论 -
leetcode746使用最小花费爬楼梯
数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。var minCostClimbingStairs = function(cost) { let dp=new Array(cost.length+1).fill(0) dp[0]原创 2021-03-19 19:39:23 · 136 阅读 · 0 评论 -
leetcode70爬楼梯
爬楼梯问题和凑零钱问题,主要是排列和组合的区别假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?注意:给定 n 是一个正整数。转移方程:dp[j]=dp[j-1]+dp[j-2]边界:dp[0]=1 dp[1]=1var climbStairs = function(n) { dp=new Array(n+1).fill(0) dp[0]=1 dp[1]=1 for(let j=2;j&l原创 2021-03-19 19:26:12 · 47 阅读 · 0 评论 -
leetcode518 零钱兑换||
给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。思路:动态规划,求组合数建立一个元素全为0的数组,遍历coins.length次数组每次遍历时,都要根据coin的值,改变dp中的值dp[0]=1dp[x]+=dp[x-coin]var change = function(amount, coins) { dp=new Array(amount+1).fill(0) dp[0]=1 for(coin of co原创 2021-03-19 17:39:11 · 132 阅读 · 0 评论 -
leetcode226翻转二叉树
翻转一棵二叉树。思路:递归终止条件: node==null递归条件:左右子树交换var invertTree=function (root) { if (!root) return null if(root){ let temp=root.left root.left=root.right root.right=temp } invertTree(root.left) invertTree(root.right) ret原创 2021-03-19 15:18:10 · 66 阅读 · 0 评论 -
leetcode230 二叉搜索树中的第k小的元素
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)var kthSmallest = function(root, k) { //方法一:递归 中序遍历,放入数组,查找第k个元素 let result=[] const midOrder=(root)=>{ if(result.length==k) return if(root!=null){ midOr原创 2021-03-19 14:51:18 · 101 阅读 · 0 评论 -
求二叉树中两个指定节点的最短距离
给定一个二叉树, 找到该树中两个指定节点间的最短距离思路:求最近公共祖先节点,然后再求最近公共祖先节点到两个指定节点的路径,再求两个节点的路径之和const shortestDistance=function (root,p,q) { let lowestCA=lowerCommonAncestor(root,p,q) let pDis=[],qDis=[] getPath(lowestCA,p,pDis) getPath(lowestCA,q,qDis) ret原创 2021-03-19 11:23:34 · 1910 阅读 · 0 评论 -
leetcode113 二叉树的路径总和
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。思路:1.终止条件:nodenull || 叶子节点 node.val+sumtargetSum2.递归条件:左子树和右子树均需递归var pathSum = function(root, targetSum) { const result=[] const pathSumFunction=(node,path,sum) =>{ i原创 2021-03-18 11:17:57 · 149 阅读 · 0 评论 -
leetcode112 二叉树路径总和(DFS递归和BFS遍历)
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。思路:方法一:递归1.终止条件:叶子节点,return false2.递归返回值:left+=递归返回值right+=递归返回值if(left!=target && right!=target) return falsereturn true方法二:BFS用两个队列q1、q2 q1用来装当前的原创 2021-03-17 16:43:23 · 121 阅读 · 0 评论 -
leetcode110 平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。思路:递归(从底向上)终止条件:叶子节点,返回0 。递归返回值:左子树的高度为left,右子树的高度为rightleft=-1 || right==-1 return -1abs(left-right)>1,return -1abs(left-right)<=1,return max{left,right}+1var isBalanc原创 2021-03-17 15:38:14 · 84 阅读 · 0 评论 -
leetcode 236二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”思路:递归终止条件:碰到p或q 碰到叶子节点递归返回:左子树和右子树判断条件:1.p和q在分列左右子树,左子树和右子树返回均不为null返回root2.p和q在左子树或右子树中,左右子树中有一个返回不为null返回该子树的返回值3.p和q不在左右原创 2021-03-17 15:00:16 · 57 阅读 · 0 评论 -
leetcode105 从前序与中序遍历中构造二叉树
根据一棵树的前序遍历与中序遍历构造二叉树。思路:1.根据前序数组,找到根节点2.根据中序数组中的根节点,找到左子树的长度3.根据左子树的长度,找到左右子树的前序数组和中序数组4.递归调用,直到前序数组为nullfunction TreeNode(val, left, right) { this.val = (val===undefined ? 0 : val) this.left = (left===undefined ? null : left) this.right原创 2021-03-17 14:20:35 · 53 阅读 · 0 评论 -
leetcode104 二叉树的最大深度
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。思路:利用回溯法,先求左子树的最大深度,再求右子树的最大深度,整棵树的最大深度为两者最大值+1var maxDepth = function(root) { //方法一:通过层序遍历,求最大深度 // let resLength=0 // if(!root) return resLength // let q=[] // q.push(root) // while(原创 2021-03-17 11:21:54 · 93 阅读 · 0 评论 -
leetcode107 二叉树的层次遍历
给定一个二叉树,返回其节点值自底向上的层序遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)思路:1.创建一个数组result,创建一个队列q,将root加入队列2. 每次从队列中取出一个节点,将该节点的左右节点放入队列每次while循环必须将队列中所有节点遍历完,才能进行下一次循环while(q.length!=0){ let subResult=[] result.push(node.val) for (let i = 0; i <原创 2021-03-17 10:11:49 · 52 阅读 · 0 评论 -
leetcode102 二叉树的层次遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。思路:1.创建一个数组result,创建一个队列q,将root加入队列2. 每次从队列中取出一个节点,将该节点的左右节点放入队列每次while循环必须将队列中所有节点遍历完,才能进行下一次循环while(q.length!=0){node=q.shift()result.push(node.val)for (let i = 0; i <q.length; i++) {if(node.left)原创 2021-03-17 09:50:49 · 56 阅读 · 0 评论 -
leetcode15 三数和
三数和用一层循环加指针如果个数<3 个数等于3且和为0 直接返回操作个数>3 先排序一层循环,相当于指针1,去重4.存储指针left,指针right5.如果外层循环+left+right=sum=0,加入result left,right去重 left++ right–6.sum<0,left++ sum>0 right–7.直到left<right,继续i++8.返回resultvar threeSum = function(nums)原创 2021-03-14 22:09:22 · 58 阅读 · 0 评论 -
leetcode 151 翻转字符串
给定一个字符串,逐个翻转字符串中的每个单词//思路:1.先剪除字符串左右的空格2.创建一个数组存放word,从字符串左边开始,当遇到空格时,判定是一个word,用unshift方法将它放到头部去,实现翻转3.字符串遍历完毕,输出wordvar reverseWords = function(s) { let left=0 let right=s.length-1 while (left<right && s.charAt(left)==' ') lef原创 2021-03-13 11:11:01 · 120 阅读 · 0 评论 -
leetcode 220 存在重复元素
在整数数组 nums 中,是否存在两个下标 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值小于等于 t ,且满足 i 和 j 的差的绝对值也小于等于 ķ 。/如果存在则返回 true,不存在返回 false。//思路:// 1.有一个大桶,存放k个小桶,存满k个小桶就会删除第一个小桶,这样相当于滑动窗口// 2.小桶需要根据大小贴标签// 3.如果当前大桶中含有小桶,说明符合条件// 4.如果当前大桶中没有含有小桶,小桶左边桶存在,且两个桶相差小于t,说明符合条件//原创 2021-03-13 10:03:32 · 74 阅读 · 0 评论 -
最简单的快排思路讲解
//快排使用分治的思想,将一个复杂问题,分为多个相似的子问题,不断分,直到更小的问题可以简单求解。// 快排步骤:// 1.选基准数// 2.将大于基准的数放在右边,小于基准的数放在左边// 创建指针left,指针right,指针left遇到大数,指针right遇到小数,两者交换// 3.重复上述操作,直到数组完全排序let quickSort = (arr) => { quick(arr, 0 , arr.length - 1)}let原创 2021-03-12 22:28:40 · 1016 阅读 · 0 评论 -
leetcode242判断字母异位词
//给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。//1.如果两个字符串的长度不等,直接返回false//2.创建一个26长度的数组,记录s中各个字符出现的个数,t中各个字符每出现一次,个数就减一//3.如果出现,个数<0,说明有不同的字符,返回false。//4.t遍历结束,没有发现不同字符,返回truevar isAnagram = function(s, t) { if(s.length!=t.length) return false; c原创 2021-03-11 23:18:37 · 290 阅读 · 1 评论 -
leetcode179 最大数
// 给定一组非负整数 nums,重新排列它们每个数字的顺序(每个数字不可拆分)使之组成一个最大的整数。// 注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。//注:// 证明 a应该在b的前面,则ab>ba // 假设a不在b的前面,则存在c,b>c>a,则ab>ba且bc>cb,推出 ac>ca,产生矛盾//思路:通过ab>ba,降序排列。如果数组只包含0,直接返回即可var largestNumber = f原创 2021-03-11 22:52:23 · 139 阅读 · 0 评论 -
leetcode20有效括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。思路:1.如果字符串个数是奇数,直接返回false2.遍历,将遇到的左符号放入栈中,遇到右符号,进入栈中查看。如果栈为空或栈中没有对应的左符号,则返回false。如果栈中有对应的左符号,则继续3.遍历完成后,如果栈中没有左括号,则返回truevar isValid = function(s) { //声明一个栈stock let stock=[],length=s.length;原创 2021-03-10 15:40:43 · 56 阅读 · 0 评论 -
leetcode75 颜色分类
/给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。思路:指定两个指针,指针p0指向0,指针p2一个指向2,当i向后移动时,如果遇到0就和p0交换,如果遇到2就和p2交换var sortColors = function(nums) { let p0=0,p2=nums.length-1; for (let i = 0; i <num原创 2021-03-10 09:13:29 · 57 阅读 · 0 评论 -
leetcode57插入区间
给你一个 无重叠的 ,按照区间起始端点排序的区间列表。在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。var insert = function(intervals, newInterval) { let res=[]; intervals.push(newInterval); if(intervals.length==0) return res.push(newInterval); //升序 i原创 2021-03-09 23:18:02 · 109 阅读 · 0 评论 -
56 合并区间
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间思路: 我们用数组 merged 存储最终的答案。/首先,我们将列表中的区间按照左端点升序排序。然后我们将第一个区间加入 merged 数组中,并按顺序依次考虑之后的每个区间:如果当前区间的左端点在数组 merged 中最后一个区间的右端点之后,那么它们不会重合,我们可以直接将这个区间加入数原创 2021-03-09 22:56:31 · 67 阅读 · 0 评论 -
leetcode 01两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。var twoSum = function(nums, target) { //创建一个哈希表,通过哈希表快速找到那个target所对应值的下标 const map = new Map(); //将前面的数一个个放入map中,等到有合适的数再取出那个值的下标 map.set(nums[0],0); for(let i=1;i<nu原创 2021-03-09 22:30:03 · 44 阅读 · 0 评论 -
斐波那契数列
从前往后计算,根据f(0)和f(1)计算出f(2),再根据f(1)和f(2)计算出f(3)……以此类推就可以计算出第n项。时间复杂度O(n)。function fibonacci(n){ let arr= [0,1]; if (n < 2) { return ori[n]; }; let fiboOne = 1,fiboTwo = 0,fiboSum = 0; for (let i = 2; i < n; i++) { fiboSum = fiboOne + fiboTwo;原创 2021-03-06 16:21:08 · 55 阅读 · 0 评论