重點回顧題
題外話:多是之前參加ACM比賽時,被一道須要利用動態規劃的題絆住了,致使到如今爲止,只要看到跟動態規劃有關的題,就打怵😂,這是留下了多大的陰影啊
假設當前判斷的迴文是從第 0 個字符,到第 4 個字符,那麼就是推導 s[0] === s[4] && s[1-3] 是迴文。
定義二維數組 dp,橫座標表示起始字符,縱座標表示當前新加入字符,獲得 dpi = s[i] === s[j] && dpi-1。
時間複雜度是 O(n*n/2)算法
var longestPalindrome = function(s) { if (s === '') return '' let arr = s.split('') let dp = new Array(arr.length).fill([]) for (let i = 0; i < dp.length; i++) { dp[i] = new Array(arr.length).fill(false) } let max = 1 let maxStart = 0 let maxEnd = 0 for (let i = 0; i < arr.length; i++) { for (let j = 0; j <= i; j++) { if (i === j) { dp[i][j] = true } if (i - j === 1) { dp[i][j] = arr[i] === arr[j] if (dp[i][j] && max < 2) { max = 2 maxStart = j maxEnd = i } } if (i - j > 1) { dp[i][j] = arr[i] === arr[j] && dp[i-1][j+1] const len = i - j + 1 if (dp[i][j] && max < len) { max = len maxStart = j maxEnd = i } } } } let result = '' for (let i = maxStart; i <= maxEnd; i++) { result += arr[i] } return result };
本題須要注意有符號和無符號,還有存儲範圍,按照程序化一步步操做就好數組
var myAtoi = function (str) { const numreg = /^[0-9]*$/ const num = str.trim() const result = parseInt(str) || 0 if (isNaN(result)) { return 0; } if (num[0] == '-') { const min = Math.pow(-2, 31) return result < min ? min : result } else if (numreg.test(num[0]) || num[0] == '+') {//開頭是數字 const max = Math.pow(2, 31) - 1 return result > max ? max : result } else { return 0; } };
也能夠用parseInt來處理指針
var myAtoi = function(str) { str = str.trim(); var max = Math.pow(2,31)-1; var min = -Math.pow(2,31); str = parseInt(str); if(str>=max){ return max; } if(str<=min){ return min; } if(isNaN(str)){ return 0; }else{ return str; } };
初看,轉換成數學題,是求最大面積,因此又是一道動態規劃題
看了官方題解的思路,雙指針法是最優解法code
var maxArea = function(height) { let left = 0; let right = height.length - 1; let max = 0; while(left < right) { const area = (right - left) * Math.min(height[right], height[left]); if (area > max) { max = area } if (height[left] < height[right]) { left++; } else { right--; } } return max; };
看上去不難,可是有額外要求 :不要使用除法,且在 O(_n_) 時間複雜度
思路:記錄每一個元素左面全部元素的乘積(不包括自身)
右邊的乘積不須要記錄,直接和左面乘積相乘字符串
/** * @param {number[]} nums * @return {number[]} */ var productExceptSelf = function (nums) { let v = 1 let result=[1] for (let i = 1; i < nums.length; i++) { v *= nums[i - 1] result[i] = v } v = 1 for (let i = nums.length - 1; i > 0; i--) { v *= nums[i] result[i - 1] *= v } return result };
給定一組不含重複元素的整數數組 _nums_,返回該數組全部可能的子集(冪集)。數學
說明:解集不能包含重複的子集。
看到 「子集」、「組合」這樣的詞語,首先想到回溯算法。
全排列:N!
組合:N!
子集:2^N ,每一個元素均可能存在或不存在。it
var subsets = function(nums) { const n = nums.length; const result = []; if (nums.length < 1) return [[]]; const backTrace = (arr, currentIndex) => { result.push(arr); if (currentIndex >= n) return; for (let i = currentIndex; i < n; ++i) { arr.push(nums[i]); backTrace(arr.slice(), i+1); arr.pop(); } } backTrace([], 0); return result; };
小結:果真上了中等難度後,就真的開始變難了,很久不碰算法,記憶都模糊了,加油~io