赞
踩
- /**
- * @param {string[][]} items
- * @param {string} ruleKey
- * @param {string} ruleValue
- * @return {number}
- */
- var countMatches = function(items, ruleKey, ruleValue) {
- let resSum=0
- const ruleValueArr=["type","color","name"]
- const index=ruleValueArr.indexOf(ruleKey)
- if(index<0)
- return 0
- for(let item of items){
- if(item[index]==ruleValue)
- resSum++
- }
- return resSum
- };
- /**
- * @param {number[]} nums
- * @param {number} target
- * @return {number[]}
- */
- var twoSum = function(nums, target) {
- for(let i=0,len=nums.length;i<len;i++){
- let findingNum=target-nums[i]
- if(nums.indexOf(findingNum)>=0&&nums.indexOf(findingNum)!==i){
- return [i,nums.indexOf(findingNum)].sort((a,b)=>a-b)
- }
- }
- return []
- };
当时第一反应想到的解法
- /**
- * Definition for singly-linked list.
- * function ListNode(val, next) {
- * this.val = (val===undefined ? 0 : val)
- * this.next = (next===undefined ? null : next)
- * }
- */
- /**
- * @param {ListNode} l1
- * @param {ListNode} l2
- * @return {ListNode}
- */
- var addTwoNumbers = function(l1, l2) {
- function reverseList(head) {
- let cur = head
- let pre = null
- let res = ""
- while (cur != null) {
- const next = cur.next
- cur.next = pre
- pre = cur
- cur = next
- }
- while (pre != null) {
- res = res + pre.val
- pre = pre.next
- }
- return res
- }
- let res1 = reverseList(l1)
- let res2 = reverseList(l2)
- let res3 = (Number(res1) + Number(res2)).toString().split("").reverse()
- let resL = new ListNode()
- let cur = resL
- for (let i = 0; i < res3.length; i++) {
- cur.next = new ListNode(res3[i])
- cur = cur.next
- }
- return resL.next
- };
就是翻转链表获取参数然后数字相加,但是发现了最后两题过不去,数字范围太大超过最大值导致返回NaN了。
后来想到 应该可以直接链表相加。满10进1
- /**
- * Definition for singly-linked list.
- * function ListNode(val, next) {
- * this.val = (val===undefined ? 0 : val)
- * this.next = (next===undefined ? null : next)
- * }
- */
- /**
- * @param {ListNode} l1
- * @param {ListNode} l2
- * @return {ListNode}
- */
- var addTwoNumbers = function(l1, l2) {
- //当前指针
- let cur1 = l1
- let cur2 = l2
- let carry = 0
- let res = new ListNode()
- let resCur = res
- while (cur1 && cur2) {
- let tempRes = cur1.val + cur2.val + carry
- resCur.next = new ListNode(tempRes % 10)
- carry = Math.floor(tempRes / 10)
- cur1 = cur1.next
- cur2 = cur2.next
- resCur = resCur.next
- }
- while (cur1) {
- let tempRes = cur1.val + carry
- resCur.next = new ListNode(tempRes % 10)
- carry = Math.floor(tempRes / 10)
- cur1 = cur1.next
- resCur = resCur.next
- }
- while (cur2) {
- let tempRes = cur2.val + carry
- resCur.next = new ListNode(tempRes % 10)
- carry = Math.floor(tempRes / 10)
- cur2 = cur2.next
- resCur = resCur.next
- }
- if (carry > 0) {
- resCur.next = new ListNode(carry)
- }
- return res.next;
- };
第一反应解法
时间复杂度太高了,她测试用例居然输入了那么长的字符串
- /**
- * @param {string} s
- * @return {string}
- */
- var longestPalindrome = function(s) {
- //双指针法
- let p1 = 0
- let res = ""
- while (p1 < s.length) {
- let p2 = p1
- while (p2 < s.length) {
- let target = s.slice(p1, p2 + 1)
- if (target === target.split("").reverse().join("")) {
- res = res.length > target.length ? res : target
- }
- p2++
- }
- p1++
- }
- return res
- };
第二反应采用的是中心扩散的方法 就是以一个字符为中心左右移动开始指针和结束指针,判断是否回文。
- /**
- * @param {string} s
- * @return {string}
- */
- var longestPalindrome = function (s) {
- //中心扩散 中心指针
- //回文的几种基本情况
- /**
- * @type 仅自身回文 “a”
- * @type 偶数回文 “abba”
- * @type 中心对称奇数回文 “aba”
- */
- let res = ""
- for (let len = s.length, i = 0; i < len; i++) {
- getResString(i, i) //情况1 3 以某元素为中心左右扩展
- getResString(i, i + 1)//情况2 以i和i+1元素为起始左右扩展
- }
- function getResString(left, right) {
- while (left >= 0 && right < s.length) {
- if (s.charAt(left) !== s.charAt(right)) {
- return
- } else {
- let target = s.slice(left, right + 1)
- res = res.length > target.length ? res : target
- left--
- right++
- }
- }
- }
- return res
- };
第一眼看完只能说是没什么思路。思考了一会:直接看答案
- /**
- * @type .表示任意字符 *表示前面的单个字符任意数目重复
- * @param {string} s 字符串
- * @param {string} p 字符规律
- * @return {boolean}
- */
- var isMatch = function (s, p) {
- //从左向右扫描的话 *的出现会影响结果 改为从右向左扫 把b*看成一个整体进行子集匹配
- if (s == null || p == null) return false;
-
- const sLen = s.length, pLen = p.length;
-
- const dp = new Array(sLen + 1);
- for (let i = 0; i < dp.length; i++) {
- dp[i] = new Array(pLen + 1).fill(false); // 将项默认为false
- }
- // base case
- dp[0][0] = true;
- for (let j = 1; j < pLen + 1; j++) {
- if (p[j - 1] == "*") dp[0][j] = dp[0][j - 2];
- }
- // 迭代
- for (let i = 1; i < sLen + 1; i++) {
- for (let j = 1; j < pLen + 1; j++) {
-
- if (s[i - 1] == p[j - 1] || p[j - 1] == ".") {
- dp[i][j] = dp[i - 1][j - 1];
- } else if (p[j - 1] == "*") {
- if (s[i - 1] == p[j - 2] || p[j - 2] == ".") {
- dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j];
- } else {
- dp[i][j] = dp[i][j - 2];
- }
- }
- }
- }
- return dp[sLen][pLen]; // 长sLen的s串 是否匹配 长pLen的p串
- }
暴力解法 计算出所有的组合比较大小 肯定超时就不试了,只能想其他的方法:
思路就是 左右指针 左指针如果移动到比上一位小的height 则跳过判断,右指针左移同理。
- /**
- * @param {number[]} height
- * @return {number}
- */
- var maxArea = function (height) {
- //双指针法
- let maxS = 0
- let i = 0, tempStartMaxHeight = 0
- while (i < height.length - 1) {
- if (height[i] > tempStartMaxHeight) {
- let j = height.length - 1, tempEndMaxHeight = 0
- while (j > i) {
- if (height[j] > tempEndMaxHeight) {
- let tempS = Math.min(height[i], height[j]) * (j - i)
- maxS = tempS > maxS ? tempS : maxS
- tempEndMaxHeight = height[j]
- }
- j--
- }
- tempStartMaxHeight = height[i]
- }
- i++
- }
- return maxS
- };
猛一看全是思路,细想不暴力解决的话还是有点东西:
自己瞎写的通过了 但是算不上简洁
- /**
- * @param {number[]} nums
- * @return {number[][]}
- */
- var threeSum = function(nums) {
- let res = []
- let left = nums.filter(item => {
- return item < 0
- })
- let right = nums.filter(item => {
- return item >= 0
- })
- for (let i = 0; i < left.length; i++) {
- for (let j = 0; j < right.length; j++) {
- let target = 0 - left[i] - right[j]
- if (left.indexOf(target, i + 1) !== -1 || right.indexOf(target, j + 1) !== -1) {
- let tempArrStr = [left[i], right[j], target].sort((a, b) => a - b).join("!")
- if (!res.includes(tempArrStr))
- res.push(tempArrStr)
- }
- }
- }
- res = res.map(item => {
- return item.split("!")
- })
- let zeroNum = 0
- for (let item of right) {
- if (item === 0) {
- zeroNum++
- }
- }
- if (zeroNum >= 3) {
- res.push([0, 0, 0])
- }
- return res
- };
看着一般
回溯法:JS算法之回溯法_js回溯算法_前端小魔女的博客-CSDN博客
- /**
- * @param {string} digits
- * @return {string[]}
- */
- var letterCombinations = function (digits) {
- let res = []
- if(digits.length===0) return []
- const digitsObj = {
- "1": [],
- "2": ["a", "b", "c"],
- "3": ["d", "e", "f"],
- "4": ["g", "h", "i"],
- "5": ["j", "k", "l"],
- "6": ["m", "n", "o"],
- "7": ["p", "q", "r", "s"],
- "8": ["t", "u", "v"],
- "9": ["w", "x", "y", "z"]
- }
- /**
- *
- * @param {number} index 当前处理的digits索引
- * @param {string} path 当前生成的组合
- */
- function dfs(index, path) {
- if (index === digits.length) res.push(path)
- else if (index < digits.length) {
- for (let item of digitsObj[digits.charAt(index)]) {
- path = path + item
- dfs(index + 1, path)
- path = path.slice(0, path.length - 1)
- }
- }
- }
- dfs(0, [])
- return res
- };
指针法怼它就完事了
- /**
- * Definition for singly-linked list.
- * function ListNode(val, next) {
- * this.val = (val===undefined ? 0 : val)
- * this.next = (next===undefined ? null : next)
- * }
- */
- /**
- * @param {ListNode} head
- * @param {number} n
- * @return {ListNode}
- */
- var removeNthFromEnd = function(head, n) {
- let res = new ListNode()
- res.next = head
- let o = res
- let p = head
- let q = head
- for (let i = 0; i < n-1; i++) {
- q = q.next
- }
- while (q.next) {
- o = o.next
- p = p.next
- q = q.next
- }
- o.next = p.next
- return res.next
- };
经典题目 入栈出栈思维就好
- /**
- * @param {string} s
- * @return {boolean}
- */
- var isValid = function (s) {
- let left = ["(", "[", "{"]
- let tempItems = []
- for (let i = 0; i < s.length; i++) {
- if (left.includes(s.charAt(i))) {
- tempItems.push(s.charAt(i))
- } else if (s.charAt(i) === ")" && tempItems[tempItems.length - 1] === "(") {
- tempItems.pop()
- } else if (s.charAt(i) === "]" && tempItems[tempItems.length - 1] === "[") {
- tempItems.pop()
- } else if (s.charAt(i) === "}" && tempItems[tempItems.length - 1] === "{") {
- tempItems.pop()
- } else {
- return false
- }
- }
- if (tempItems.length === 0) return true
- return false
- };
经典中的经典了
- /**
- * Definition for singly-linked list.
- * function ListNode(val, next) {
- * this.val = (val===undefined ? 0 : val)
- * this.next = (next===undefined ? null : next)
- * }
- */
- /**
- * @param {ListNode} list1
- * @param {ListNode} list2
- * @return {ListNode}
- */
- var mergeTwoLists = function(list1, list2) {
- let res=new ListNode()
- let o=res
- while(list1&&list2){
- if(list1.val<list2.val){
- res.next=list1
- list1=list1.next
- }else{
- res.next=list2
- list2=list2.next
- }
- res=res.next
- }
- while(list1){
- res.next=list1
- list1=list1.next
- res=res.next
- }
- while(list2){
- res.next=list2
- list2=list2.next
- res=res.next
- }
- return o.next
- };
还是回溯法 只不过可以剪枝
- let res = []
- let path = ""
- function getLength(str, target) {
- return str.split(target).length - 1
- }
- function dfs(index) {
- if (index === 2 * n) {
- res.push(path)
- } else {
- for (let item of ["(", ")"]) {
- if (item === "(" && getLength(path, "(") < n) {
- path = path + "("
- dfs(index + 1)
- path = path.slice(0, path.length - 1)
- } else if (item === ")" && getLength(path, "(") > getLength(path, ")")) {
- path = path + ")"
- dfs(index + 1)
- path = path.slice(0, path.length - 1)
- }
- }
- }
- }
- dfs(0)
- return res
虽然是困难题,但是我的解决办法就是循环执行11题,两两排序。就比较简单了。
- /**
- * Definition for singly-linked list.
- * function ListNode(val, next) {
- * this.val = (val===undefined ? 0 : val)
- * this.next = (next===undefined ? null : next)
- * }
- */
- /**
- * @param {ListNode[]} lists
- * @return {ListNode}
- */
- var mergeKLists = function (lists) {
- if (lists.length === 0) return null
- let res = lists[0]
- function sortTwoList(l1, l2) {
- let o = new ListNode()
- let res = o
- while (l1 && l2) {
- if (l1.val < l2.val) {
- o.next = l1
- l1 = l1.next
- } else {
- o.next = l2
- l2 = l2.next
- }
- o = o.next
- }
- while (l1) {
- o.next = l1
- o = o.next
- l1 = l1.next
- }
- while (l2) {
- o.next = l2
- o = o.next
- l2 = l2.next
- }
- return res.next
- }
- for (let i = 1; i < lists.length; i++) {
- res = sortTwoList(res, lists[i])
- }
- return res
- };
做的时候没啥思路太困了 看了官方的方法
- /**
- * @param {number[]} nums
- * @return {void} Do not return anything, modify nums in-place instead.
- */
- var nextPermutation = function(nums) {
- //逆序找变小值返回索引
- let indexMin = -1
- let changeIndex = -1
- for (let i = nums.length - 2; i >= 0; i--) {
- if (nums[i] < nums[i + 1]) {
- indexMin = i
- break
- }
- }
- if (indexMin === -1) return nums.sort((a, b) => a - b)
- //查找第一个比min大的数
- for (let i = nums.length; i >= indexMin; i--) {
- if (nums[i] > nums[indexMin]) {
- changeIndex = i
- break
- }
- }
- //交换两个数的位置
- let tempData = nums[indexMin]
- nums[indexMin] = nums[changeIndex]
- nums[changeIndex] = tempData
- //将后面的排序
- let tempArray = []
- for (let i = nums.length - 1; i > indexMin; i--) {
- tempArray.push(nums.pop())
- }
- nums.push(...tempArray)
- };
开始懒得想直接暴力求解 果然超时
- /**
- * @param {string} s
- * @return {number}
- */
- var longestValidParentheses = function(s) {
- let maxLength = 0
- function judge(str) {
- let list = []
- for (let i = 0; i < str.length; i++) {
- let target = str.charAt(i)
- if (target === "(") {
- list.push("(")
- } else if (target === ")" && list[list.length - 1] === "(") {
- list.pop()
- } else {
- return false
- }
- }
- if (list.length === 0) return true
- return false
- }
- for (let pre = 0; pre < s.length; pre++) {
- for (let next = 1; next < s.length; next++) {
- if(s.length-pre<maxLength) return maxLength
- let target = s.slice(pre, next+1)
- if (judge(target)) {
- maxLength = maxLength > target.length ? maxLength : target.length
- }
- }
- }
- return maxLength
- };
后来直接去看答案 还是答案想的周到,这里采用双指针法
- /**
- * @param {string} s
- * @return {number}
- */
- var longestValidParentheses = function (s) {
- let left = 0
- let right = 0
- let maxLength = 0
-
-
- for (let i = 0; i < s.length; i++) {
- const target = s.charAt(i)
- if (target === "(") {
- left++
- } else if (target === ")") {
- right++
- }
- if (right > left) {
- right = 0
- left = 0
- }else if (left === right) {
- const length = 2 * right
- maxLength = maxLength > length ? maxLength : length
- }
- }
- right=left=0
- for (let i = s.length - 1; i >= 0; i--) {
- const target = s.charAt(i)
- if (target === "(") {
- left++
- } else if (target === ")") {
- right++
- }
- if (right < left) {
- right = 0
- left = 0
- }else if (left === right) {
- const length = 2 * left
- maxLength = maxLength > length ? maxLength : length
- }
- }
-
- return maxLength
- };
关于贪心算法的补充
后面有几道过于简单的就省略掉了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。