前置知識算法
const Greedy = num => { //貪心 let arr = [100, 20, 10, 5, 2, 1] let count = 0; for (let i = 0; i < arr.length; i++) { let use = Math.floor(num / arr[i]) count += use; num = num - arr[i] * use console.log('須要面額爲' + arr[i] + '有' + count + '張') count = 0; } } Greedy(120)
// 孩子,糖果, const findContent = (g, s) => { g.sort() s.sort() let child = 0; let cookie = 0; while (child < g.length && cookie < s.length) { if (g[child] <= s[cookie]) { child++ } cookie++;//不管成功或者失敗,每一個糖果只嘗試一次,cookie向後移動 } return child } let g = [2, 4, 5, 6, 7] let s = [1, 3, 4, 6, 7] console.log(findContent(g, s))
舉例子數組
[1,17,5,10,13,15,10,5,16,8]cookie
[5,10,13,15] 屬於遞增序列動畫
也就是[小大小大...]或者[大小大小...]this
求最長的搖擺序列3d
const wiggleMax = nums => { let n = nums.length if (n < 2) { return n } let up = 1; let down = 1; for (let i = 1; i <n ; i++) { if (nums[i] > nums[i - 1]) { up=down+1; } if (nums[i] < nums[i - 1]) { down=up+1; } } return Math.max(up, down) } console.log(wiggleMax([1, 17, 5, 10, 13, 15, 10, 5, 16, 8,1,9]))
給定一個以字符串表示的非負整數 num,移除這個數中的 k 位數字,使得剩下的數字最小code
初始化一個棧blog
記得打斷點就懂了遞歸
class Stack { constructor() { this.items = [] } push(element) { this.items.push(element) } //移除棧中的元素,遵循先進後出原則 pop() { return this.items.pop() } //返回棧頂 peek() { return this.items[this.items.length - 1] } //判斷棧是否爲空,爲空爲true,不爲空爲false isEmpty() { return this.items.length == 0 } size() { return this.items.length } //清除棧 clear() { this.items = []; } print() { console.log(this.items) } }
const removeK = (num, k) => { //存在的棧 const stack = new Stack(); //貪心算法+棧 if (k >= num.length || num.length == 0) return '0'; //棧頂始終是最大值 stack.push(+num.charAt(0)); for (let i = 1; i < num.length; i++) { let now = +num.charAt(i); //當前棧不爲空的時候,並且k>0,當前值小於棧頂,就刪除棧中的一個元素 while (!stack.isEmpty() && k > 0 && now < stack.peek()) { stack.pop(); k--; } //不等於0能夠添加進去, //等於0,棧不爲空能夠填進去, if (now != 0 || !stack.isEmpty()) { stack.push(now); } } //56789去掉後面添加的我的 while (k > 0) { k--; stack.pop(); } //10,1(當now=0時,知足條件,去掉1,但now爲0,且爲空。) if (stack.isEmpty()) { return '0'; } //把棧中元素放到數組中 let sb = []; while (!stack.isEmpty()) { sb.push(stack.pop()); } //還原成字符串 let sub = ''; sb.reverse().map(val => sub += val) return sub } console.log(removeK('9234567', 3))
給出一個非負整數數組,你最初定位在數組的第一個位置。遊戲
數組中的每一個元素表明你在那個位置能夠跳躍的最大長度。
判斷你是否能到達數組的最後一個位置。
樣例
A = [2,3,1,1,4],返回 true.A = [3,2,1,0,4],返回 false.
const canJump = maxSteps => { if (maxSteps == null || maxSteps.length == 0) { return false; } let meetIndex = maxSteps.length - 1; for (let i = maxSteps.length - 1; i >= 0; i--) { if (i + maxSteps[i] >= meetIndex) { meetIndex = i; } } return meetIndex == 0; } console.log(canJump([0,2,0,1,4]))
>>
賦值
<<
打印
->
.
const getAnswer = h => { let n = h.length; let ans = 0; for (let i = 1; i < n; i++) { let a = Infinity; for (let j = i; j < n; j++) { a = Math.min(a, h[j]) ans = Math.max(ans, (j - i + 1) * a) } } return ans } console.log(getAnswer([1, 8, 3, 4, 8]))
遞歸版
const sum2=num=>{ if (num < 1) { return 0 } return sum2(num-1)+num } console.log(sum2(100))
非遞歸版
const sum1=n=>{ let result=0; for (let i = 0; i <=n; i++) { result+=i; } return result } console.log(sum1(100))
順序存儲是順序表
鏈表是線性表的鏈式存儲方式,不連續的
-數據的元素|下一個元素的地址
字符串的存儲可使用順序存儲和鏈式存儲兩種方式
BF算法: BF是蠻力,暴力窮舉
const BF = (s, t, pos) => { let i = pos, j = 1, sum = 0; let slen = s.length let tlen = s.length while (i <= slen && j <= tlen) { sum++ //若是相等,則繼續比較後面的字符 if (s[i - 1] == t[j - 1]) { i++ j++ } else { //i回退到上一輪開始比較的下一個字符 i = i - j + 2 //j回退到第1個字符 j = 1; } } return '一共比較了' + sum + '次' } console.log(BF('abcbcd', 'bcd', 0))
使用動態規劃解決
真前綴 除了自身之外,一個字符串的所有頭部組合
後前綴 除了自身以外,一個字符串的所有尾部組合
動畫
算出最長公共先後綴的長度(重複的長度)
開始比較(把數組下標爲3的向前走一位)
寫的很亂,如今從新分析下
移動的位數=匹配的字符數-對應的部分匹配值
//4-3=1 ,移動一位咱們算算匹配表的分解,p表示前綴,n表示後綴,r表示結果
a, p=>0, n=>0 r = 0 aa, p=>[a],n=>[a] , r = a.length => 1 aar, p=>[a,aa], n=>[r,ar] ,r = 0 aaro, p=>[a,aa,aar], n=>[o,ra,aro] ,r = 0 aaron p=>[a,aa,aar,aaro], n=>[n,on,ron,aron] ,r = 0 aarona, p=>[a,aa,aar,aaro,aaron], n=>[a,na,ona,rona,arona] ,r = a.lenght = 1 aaronaa, p=>[a,aa,aar,aaro,aaron,aarona], n=>[a,aa,naa,onaa,ronaa,aronaa] , r = Math.max(a.length,aa.length) = 2 aaronaac p=>[a,aa,aar,aaro,aaron,aarona], n=>[c,ac,aac,naac,onaac,ronaac] r = 0終於找到了看着比較舒服的完整代碼了,很少說直接上代碼
const getNext = str => { let next = [-1] let k = -1 for (let i = 1; i < str.length; i++) { //第一次不執行且從前綴開始,判斷不一樣的把-1賦值上 while (k != -1 && str[k + 1] != str[i]) { k = next[k] } //而後判斷相同的,讓k自增 if (str[k + 1] == str[i]) { k++ } //這是最開始將k賦值到數組中,而後依次判斷把值賦值上 next[i] = k } return next } const KMP = (str1, str2) => { let next = getNext(str2) let j = 0 for (let i = 0; i < str1.length; i++) { while (j > 0 && str1[i] != str2[j]) { j = next[j - 1] + 1 // j 更新爲最長可匹配前綴子串的長度 k } if (str1[i] == str2[j]) j++ if (j == str2.length) return i - str2.length + 1 } return -1 } console.log(KMP('abcdacbcdababc', 'ababc'))
..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................