var threeSum = function (nums) { let res = [] nums = nums.sort((a,b)=>a-b) //首先要进行排序 for (let i = 0; i < nums.length-2; i++) { //减2是因为求得是三个元素的和。 if (i > 0 && nums[i] == nums[i - 1]) continue//a去重 let left = i + 1,right = nums.length - 1//指定双指针 while (left < right) { let sum = nums[i]+nums[left]+nums[right] if (sum>0) right-- if (sum<0) left++ if(sum===0){ res.push([nums[i],nums[left],nums[right]]) //后两个数去重逻辑,如果指针指向下一个元素与当前相同,跳过该元素 while(left<right && nums[left] === nums[left+1]) left++ while(left<right && nums[right] === nums[right-1]) right-- left++ //忘记调整这两个了 right-- } } } return res }
反转链表
自定义链表
解题代码
1 2 3 4 5 6 7 8 9 10 11 12
var reverseList = function(head) { let prev = null let cur = head while(cur){ // 这一步我忘记了,没有把next的值保存下来,直接给cur.next赋值了 const next = cur.next cur.next = prev prev = cur cur = next } return prev //最后一个cur是null,他前面一个才是第一个有值的节点 };
var dailyTemperatures = function(temperatures) { let n = temperatures.length let stack = [0] let res = Array(n).fill(0) for(let i=1;i<n;i++){ let top = stack[stack.length-1] //小于和等于的情况,直接压入栈 if (temperatures[i] === temperatures[top]){ stack.push(i) } elseif(temperatures[i] < temperatures[top]){ stack.push(i) } //当前元素大于栈顶元素的情况,要计算距离, //删掉栈顶元素知道所有小于当前元素的栈顶元素被删完,压入当前元素 else{ while (stack.length && temperatures[i] > temperatures[stack[stack.length-1]]) { top = stack.pop() res[top] = i-top } stack.push(i) } } return res };
var nextGreaterElement = function (nums1, nums2) { const m = nums1.length const n = nums2.length let stack = [nums2[0]] let res = Array(m).fill(-1) let map = newMap() for (let i = 0; i < m; i++) { map.set(nums1[i],i) } for (let j = 1; j < n; j++) { let top = stack[stack.length-1] if (nums2[j]<top || nums2===top) stack.push(nums2[j]) else{ // console.log(res) while(stack.length && nums2[j]>stack[stack.length-1]){ top = stack.pop() if (map.has(top)){ res[map.get(top)] = nums2[j]
var nextGreaterElements = function(nums) { let n = nums.length let res = Array(n).fill(-1) let stack = [0] for(let i=1;i<n*2;i++){ let j = i if (i>=n) j = i - n while (stack.length && nums[j] > nums[stack[stack.length - 1]]) { let top = stack.pop() res[top] = nums[j] } stack.push(j) } return res };
var trap = function(height) { let n = height.length let res = 0 let stack = [0] for(let i=1;i<n;i++){ while(stack.length && height[i]>height[stack[stack.length-1]]){ let top = stack.pop() if (stack.length === 0) break let topl = stack[stack.length-1] res += (Math.min(height[i],height[topl])-height[top]) * (i-topl-1) } stack.push(i) } return res };
var largestRectangleArea = function(heights) { heights = [0,...heights,0] let n = heights.length let maxArea = 0 let stack =[0] for (let i=1;i<n;i++){ while(heights[i]<heights[stack[stack.length-1]]){ let top = stack.pop() let topl = stack[stack.length-1] let w = i-topl-1 maxArea = Math.max(maxArea,w*heights[top]) } stack.push(i) } return maxArea };
中序 var inorderTraversal = function (root) { // 入栈:左->右 // 出栈:左 中 右 let res = [] if (!root) return res const stack = [] cur = root while (cur || stack.length){ if (cur){ stack.push(cur) cur = cur.left } else{ cur = stack.pop() res.push(cur.val) cur = cur.right } } return res }
超时了,129/132 var countSubstrings = function(s) { let num = 0 functionisHuiwen(t) { let p = 0;q = t.length-1 while (p<q){ if (t[p] != t[q]){ returnfalse } p++; q-- } returntrue } for (let i=0;i<s.length;i++){ for (let j=i+1;j<=s.length;j++){ console.log(isHuiwen(s.substring(i, j))) if (isHuiwen(s.substring(i,j))) num ++ } } return num };
动态规划 var countSubstrings = function(s) { let num = 0 let n = s.length let dp = Array.from({length:n},()=>Array(n).fill(false)) for(let i=n-1;i>=0;i--){ //j是尾巴,尾巴j大于等于头i for(let j=i;j<n;j++){ if (s[i]==s[j]){ if (j-i>1) { dp[i][j] = dp[i+1][j-1] } else dp[i][j] = true } if (dp[i][j] === true) num++ } } console.log(dp) return num };
if (s[i-1]==t[j-1]) dp[i][j] = dp[i-1][j-1] +dp[i-1][j],使用s[i-1]这个元素+不使用s[i-1]这个元素
else dp[i][j] = dp[i-1][j],模拟删除当前元素,也就是不考录当前的元素。
3、初始化:
dp[i][0] = 1(); t是空字符串的话,把s中元素全部删除可以得到t
dp[0][j] = 0; s为空字符串,t不可能出现在s中,所以未0
dp[0][0]= 1; s和t都为空字符串的话,只有一种可能
4、遍历顺序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var numDistinct = function(s, t) { let n = s.length let m = t.length let dp = Array.from({length:n+1},()=>Array(m+1).fill(0)) for (let i=0;i<=n;i++) {dp[i][0]=1} for (let i=1;i<=n;i++){ for (let j=1;j<=m;j++){ //相等,可以选择使用s[i-1]或者不使用s[i-1] if (s[i-1]==t[j-1]) dp[i][j] = dp[i-1][j-1] + dp[i-1][j] else dp[i][j] = dp[i-1][j] //不相等说明s[i-1]用不了得删掉。 } } return dp[n][m] };
var minDistance = function(word1, word2) { let n = word1.length let m = word2.length let dp = Array.from({length:n+1},()=>Array(m+1).fill(0)) //这两个for循环用于初始化dp数组 for (let i=0;i<=n;i++){ dp[i][0] = i } for (let j=0;j<=m;j++){ dp[0][j] = j } for (let i=1;i<=n;i++){ for(let j=1;j<=m;j++){ if (word1[i-1] == word2[j-1]) dp[i][j] = dp[i-1][j-1] else dp[i][j] = Math.min(dp[i-1][j]+1,dp[i][j-1]+1) } } return dp[n][m] };
var minDistance = function(word1, word2) { let n= word1.length let m = word2.length let dp = Array.from({length:n+1},()=>Array(m+1).fill(0)) for (let i=0;i<=n;i++){ dp[i][0] = i } for (let j=0;j<=m;j++){ dp[0][j] = j } for (let i=1;i<=n;i++){ for (let j=1;j<=m;j++){ if (word1[i-1]==word2[j-1]) dp[i][j] = dp[i-1][j-1] else dp[i][j] = Math.min(dp[i][j-1]+1,dp[i-1][j]+1,dp[i-1][j-1]+1) } } return dp[n][m] };
if (nums[i]>nums[j]) dp[i] = max(dp[i],dp[j]+1)这里的含义是,取dp[j]+1的最大值。
3、初始化,子序列的长度最短为1
4、遍历顺序,外层遍历i(1 ~ n),内层遍历j(0 ~ i-1)
还要注意并不是dp[n-1]才是最终的值,最大值应该是dp数组中的最大值。
1 2 3 4 5 6 7 8 9 10 11 12
var lengthOfLIS = function(nums) { let n = nums.length let dp = Array(n).fill(1) let result = 1 for(let i=1;i<n;i++){ for(let j=0;j<i;j++){ if (nums[i]>nums[j]) dp[i] = Math.max(dp[i],dp[j]+1) } if (dp[i]>result) result = dp[i] } return result };
var findLengthOfLCIS = function(nums) { let n = nums.length let dp = Array(n).fill(1) let result =1 for(let i=1;i<n;i++){ if(nums[i]>nums[i-1]) dp[i] = dp[i-1]+1 if (dp[i]>result) result = dp[i] } return result };
var findLength = function(nums1, nums2) { let n = nums1.length let m = nums2.length let dp = Array.from({length:n+1},()=>Array(m+1).fill(0)) let result = 0 for (let i=1;i<=n;i++){ for(let j=1;j<=m;j++){ if(nums1[i-1] == nums2[j-1]) dp[i][j]=dp[i-1][j-1]+1 if (dp[i][j] > result) result = dp[i][j] } } return result };
var maxUncrossedLines = function(nums1, nums2) { let n = nums1.length let m = nums2.length let dp = Array.from({length:n+1},()=>Array(m+1).fill(0)) for(let i = 1;i<=n;i++){ for(let j = 1;j<=m;j++){ if (nums1[i-1]==nums2[j-1]) dp[i][j] = dp[i-1][j-1]+1 else dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]) } } return dp[n][m] };