雙指針技巧
167 兩數之和
輸入一個升序的有序數組,找到兩數的和等於目標值
const twoSum = (numbers, target) => {
let start = 0
let end = numbers.length - 1
while (start < end) {
let sum = numbers[start] + numbers[end]
if (sum == target) {
return [start + 1, end + 1]
}
if (sum > target) {
end--
continue
}
if (sum < target) {
start++
continue
}
}
}
console.log(twoSum([1, 2, 3, 4, 5, 6], 11))
125 驗證回文串
只考慮數字和字母
//如果遇到不是數字后者字母直接跳過
const isPalindrome = s => {
let start = 0,
end = s.length - 1;
let reg = /[a-z0-9]/
while (start < end) {
const pre = s[start].toLowerCase()
const suf = s[end].toLowerCase()
if (!reg.test(pre)) {
start++
continue
}
if (!reg.test(suf)) {
end--
continue
}
if (pre !== suf) {
return false
}
start++
end--
}
return true
}
console.log(isPalindrome('abba'))
雙向冒泡排序
const bubbleSort = arr => {
let isSwap = '',tail=arr.length-1
for (let i = 0; i < tail; i++) {
isSwap = false
for (let j = tail; j > i; j--) {
if (arr[j] > arr[j + 1]) {
isSwap = true
swap(j, j + 1, arr)
}
}
for (let j = i; j < tail; j++) {
if (arr[j] > arr[j + 1]) {
isSwap = true
swap(j, j + 1, arr)
}
}
if (!isSwap) {
break
}
}
return arr
}
console.log(bubbleSort([1, 10, 3, 4, 5, 6, 1221, 1, 2, 3, 4, 4, 5]))
41 給定一個未排序的整數數組,找出其中沒有出現的最小的正整數
輸入: [1,2,0]
輸出: 3
示例 2:
輸入: [3,4,-1,1]
輸出: 2
示例 3:
輸入: [7,8,9,11,12]
輸出: 1
采用集合
const firstMissing = nums => {
const set = new Set()
for (let i = 0; i < nums.length; i++) {
if (nums[i] >= 0&& nums[i] <= nums.length) {
set.add(nums[i])
}
}
for (let i = 0; i <= nums.length; i++) {
if (!set.has(i)) {
return i
}
}
return nums.length
}
我自己改的
const firstMissing = nums => {
if (nums == null || nums.length < 1)
return 1
let a = nums.filter(v => v > 0).sort((a, b) => a - b)
let s = 1
while (s < a.length) {
if (s < a[s - 1]) {
return s
}
s++
}
}
如何在 10 億數中找出前 1000 大的數
const firstMissing = nums => {
let i = 1
while (1) {
if (nums[i] > 1000) {
return nums[i]
}
if (!(typeof nums[i] == "number")) {
return '不好意思沒有找到'
}
i++
}
}
貪心算法
中心思想: 大事化小,小事化了
動態規划
通過把原問題分解為相對簡單的子問題的方式求解復雜問題的方法
總結就是:
有最優解的結構
找到子問題
以"自底向上"的方式計算最優解的值
可以從已計算的信息中構建出最優的路徑
最少硬幣數
確定狀態
最后一步(最優策略種使用的最后一枚硬幣ak)
化成子問題(最少的硬幣拼出最小的面值27-ak)
轉移方程
f[x]=Math.min(f[x-2]+1,f[x-5]+1,f[x-7]+1)
初始化條件和邊界情況
f[0]=0,如果不能評出Y,f[Y]=正無窮
計算順序
從小到大
const coinChange = (A, M) => {
let n = A.length;
let f = [];
f[0]=0
for (let i = 1; i <= M; i++) {
//選擇硬幣
f[i] = Infinity
for (let j = 0; j < n; j++) {
//i>=A[j] 你的硬幣不能大於我的目標值,相當於我要拼出10塊錢,你不能為11塊錢
//i-A[j] 11-1,-3,-5 的值
if (i >= A[j] && f[i - A[j]] != Infinity && f[i - A[j]] + 1 < f[i]) {
f[i] = f[i - A[j]] + 1
}
console.log(f)
}
}
if (f[M] == Infinity) {
return -1
} else {
return f[M]
}
}
console.log(coinChange([1,2,5], 15))
114
給定m行n列的網格,有一個機器人從左上角(0,0)出發,每一步可以向下或者向有走一步,
問有多少種不同的方式
確定狀態
- 左下角左邊設為(m-1,n-1)
- 那么前一步機器人一定是再(m-2,n-1)或者(m-1,n-2)
子問題
那么機器人有x種方式從左上角走到(m-2,n-1)
有y種方式從左上角走到(m-1,n-2)
則機器人有x+y種方式走到(m-1,n-1)
轉化方程
對於任意一個格子(i,j)
f[i][j]=f[i-1][j]+f[i][j-1]
有多少種方式走到
(i,j)
=(i-1,j)
+(i,j-1)
初始條件和邊界情況
- 初始條件:
f[0][0]=1
因為機器人只有一種方式到左上角- 邊界情況: i=0 或 j=0 則前一步只能有一個方向過程
f[i][j]=1
計算順序
const Solution = (m, n) => { let f = Array.from({length:m},v=>[]) for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { //按照行列的情況進行循環 if (i == 0 || j == 0) { f[i][j] = 1; } else { f[i][j] = f[i - 1][j] + f[i][j - 1] } } } return f[m - 1][n - 1] } console.log(Solution(3, 3))
116
有n塊石頭分別在x軸的0,1,...n-1位置
一只青蛙在石頭0,想跳到石頭n-1
如果青蛙在第i塊石頭上,他最多可以向右跳距離a[j]
問青蛙能夠跳到石頭n-1
例子 [2,3,1,1,4] true [3,2,1,0,1] false
存在型動態規划
確定狀態
最后一步:如果青蛙能跳到最后一塊石頭n-1,那我們考慮他跳的最后一步
這一步是從石頭i調過來,i<n-1
需要兩個條件同時滿足:
- 青蛙可以跳到石頭i
- 最后一步不超過跳躍的最大距離:n-1-i<a[j]
子問題
狀態:設f[j]表示青蛙能不能跳到石頭j
轉移方程
計算順序
const Solution = A => { if (A == null || A.length == 0) { return false } let f = [true,] for (let i = 1; i < A.length; i++) { f[i] = false for (let j = 0; j < i; j++) { if (f[j] && (j + A[j]) >= i) { f[i] = true break } } } return f[A.length-1] } console.log(Solution([2, 3, 1, 1, 4])) console.log(Solution([3,2,1,0,4]))
###########################...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................