mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-06 09:28:26 +08:00
Merge branch 'master' into add-trapping-water
This commit is contained in:
26
Dynamic-Programming/ClimbingStairs.js
Normal file
26
Dynamic-Programming/ClimbingStairs.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* You are climbing a stair case. It takes n steps to reach to the top.
|
||||
* Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
|
||||
*/
|
||||
|
||||
const climbStairs = (n) => {
|
||||
let prev = 0
|
||||
let cur = 1
|
||||
let temp
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
temp = prev
|
||||
prev = cur
|
||||
cur += temp
|
||||
}
|
||||
return cur
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
const number = 5
|
||||
|
||||
console.log('Number of ways to climb ' + number + ' stairs in ' + climbStairs(5))
|
||||
}
|
||||
|
||||
// testing
|
||||
main()
|
61
Dynamic-Programming/EditDistance.js
Normal file
61
Dynamic-Programming/EditDistance.js
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Wikipedia -> https://en.wikipedia.org/wiki/Edit_distance
|
||||
|
||||
Q. -> Given two strings `word1` and `word2`. You can perform these operations on any of the string to make both strings similar.
|
||||
- Insert
|
||||
- Remove
|
||||
- Replace
|
||||
Find the minimum operation cost required to make both same. Each operation cost is 1.
|
||||
|
||||
Algorithm details ->
|
||||
time complexity - O(n*m)
|
||||
space complexity - O(n*m)
|
||||
*/
|
||||
|
||||
const minimumEditDistance = (word1, word2) => {
|
||||
const n = word1.length
|
||||
const m = word2.length
|
||||
const dp = new Array(m + 1).fill(0).map(item => [])
|
||||
|
||||
/*
|
||||
fill dp matrix with default values -
|
||||
- first row is filled considering no elements in word2.
|
||||
- first column filled considering no elements in word1.
|
||||
*/
|
||||
|
||||
for (let i = 0; i < n + 1; i++) {
|
||||
dp[0][i] = i
|
||||
}
|
||||
|
||||
for (let i = 0; i < m + 1; i++) {
|
||||
dp[i][0] = i
|
||||
}
|
||||
|
||||
/*
|
||||
indexing is 1 based for dp matrix as we defined some known values at first row and first column/
|
||||
*/
|
||||
|
||||
for (let i = 1; i < m + 1; i++) {
|
||||
for (let j = 1; j < n + 1; j++) {
|
||||
const letter1 = word1[j - 1]
|
||||
const letter2 = word2[i - 1]
|
||||
|
||||
if (letter1 === letter2) {
|
||||
dp[i][j] = dp[i - 1][j - 1]
|
||||
} else {
|
||||
dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1], dp[i][j - 1]) + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp[m][n]
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
console.log(minimumEditDistance('horse', 'ros'))
|
||||
console.log(minimumEditDistance('cat', 'cut'))
|
||||
console.log(minimumEditDistance('', 'abc'))
|
||||
console.log(minimumEditDistance('google', 'glgool'))
|
||||
}
|
||||
|
||||
main()
|
18
Dynamic-Programming/FibonacciNumber.js
Normal file
18
Dynamic-Programming/FibonacciNumber.js
Normal file
@ -0,0 +1,18 @@
|
||||
// https://en.wikipedia.org/wiki/Fibonacci_number
|
||||
|
||||
const fibonacci = (N) => {
|
||||
// creating array to store values
|
||||
const memo = new Array(N + 1)
|
||||
memo[0] = 0
|
||||
memo[1] = 1
|
||||
for (let i = 2; i <= N; i++) {
|
||||
memo[i] = memo[i - 1] + memo[i - 2]
|
||||
}
|
||||
return memo[N]
|
||||
}
|
||||
|
||||
// testing
|
||||
(() => {
|
||||
const number = 5
|
||||
console.log(number + 'th Fibonacci number is ' + fibonacci(number))
|
||||
})()
|
33
Dynamic-Programming/LongestCommonSubsequence.js
Normal file
33
Dynamic-Programming/LongestCommonSubsequence.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Given two sequences, find the length of longest subsequence present in both of them.
|
||||
* A subsequence is a sequence that appears in the same relative order, but not necessarily contiguous.
|
||||
* For example, “abc”, “abg”, “bdf”, “aeg”, ‘”acefg”, .. etc are subsequences of “abcdefg”
|
||||
*/
|
||||
|
||||
function longestCommonSubsequence (x, y, str1, str2, dp) {
|
||||
if (x === -1 || y === -1) {
|
||||
return 0
|
||||
} else {
|
||||
if (dp[x][y] !== 0) {
|
||||
return dp[x][y]
|
||||
} else {
|
||||
if (str1[x] === str2[y]) {
|
||||
dp[x][y] = 1 + longestCommonSubsequence(x - 1, y - 1, str1, str2, dp)
|
||||
return dp[x][y]
|
||||
} else {
|
||||
dp[x][y] = Math.max(longestCommonSubsequence(x - 1, y, str1, str2, dp), longestCommonSubsequence(x, y - 1, str1, str2, dp))
|
||||
return dp[x][y]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function main () {
|
||||
const str1 = 'ABCDGH'
|
||||
const str2 = 'AEDFHR'
|
||||
const dp = new Array(str1.length + 1).fill(0).map(x => new Array(str2.length + 1).fill(0))
|
||||
const res = longestCommonSubsequence(str1.length - 1, str2.length - 1, str1, str2, dp)
|
||||
console.log(res)
|
||||
}
|
||||
|
||||
main()
|
27
Dynamic-Programming/LongestIncreasingSubsequence.js
Normal file
27
Dynamic-Programming/LongestIncreasingSubsequence.js
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* A Dynamic Programming based solution for calculating Longest Increasing Subsequence
|
||||
* https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
||||
*/
|
||||
|
||||
function main () {
|
||||
const x = [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]
|
||||
const length = x.length
|
||||
const dp = Array(length).fill(1)
|
||||
|
||||
let res = 1
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
for (let j = 0; j < i; j++) {
|
||||
if (x[i] > x[j]) {
|
||||
dp[i] = Math.max(dp[i], 1 + dp[j])
|
||||
if (dp[i] > res) {
|
||||
res = dp[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Length of Longest Increasing Subsequence is:', res)
|
||||
}
|
||||
|
||||
main()
|
39
Dynamic-Programming/LongestPalindromicSubsequence.js
Normal file
39
Dynamic-Programming/LongestPalindromicSubsequence.js
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
LeetCode -> https://leetcode.com/problems/longest-palindromic-subsequence/
|
||||
|
||||
Given a string s, find the longest palindromic subsequence's length in s.
|
||||
You may assume that the maximum length of s is 1000.
|
||||
|
||||
*/
|
||||
|
||||
const longestPalindromeSubsequence = function (s) {
|
||||
const n = s.length
|
||||
|
||||
const dp = new Array(n).fill(0).map(item => new Array(n).fill(0).map(item => 0))
|
||||
|
||||
// fill predefined for single character
|
||||
for (let i = 0; i < n; i++) {
|
||||
dp[i][i] = 1
|
||||
}
|
||||
|
||||
for (let i = 1; i < n; i++) {
|
||||
for (let j = 0; j < n - i; j++) {
|
||||
const col = j + i
|
||||
if (s[j] === s[col]) {
|
||||
dp[j][col] = 2 + dp[j + 1][col - 1]
|
||||
} else {
|
||||
dp[j][col] = Math.max(dp[j][col - 1], dp[j + 1][col])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp[0][n - 1]
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
console.log(longestPalindromeSubsequence('bbbab')) // 4
|
||||
console.log(longestPalindromeSubsequence('axbya')) // 3
|
||||
console.log(longestPalindromeSubsequence('racexyzcxar')) // 7
|
||||
}
|
||||
|
||||
main()
|
37
Dynamic-Programming/MinimumCostPath.js
Normal file
37
Dynamic-Programming/MinimumCostPath.js
Normal file
@ -0,0 +1,37 @@
|
||||
// youtube Link -> https://www.youtube.com/watch?v=lBRtnuxg-gU
|
||||
|
||||
const minCostPath = (matrix) => {
|
||||
/*
|
||||
Find the min cost path from top-left to bottom-right in matrix
|
||||
>>> minCostPath([[2, 1], [3, 1], [4, 2]])
|
||||
6
|
||||
*/
|
||||
const n = matrix.length
|
||||
const m = matrix[0].length
|
||||
|
||||
// Preprocessing first row
|
||||
for (let i = 1; i < m; i++) {
|
||||
matrix[0][i] += matrix[0][i - 1]
|
||||
}
|
||||
|
||||
// Preprocessing first column
|
||||
for (let i = 1; i < n; i++) {
|
||||
matrix[i][0] += matrix[i - 1][0]
|
||||
}
|
||||
|
||||
// Updating cost to current position
|
||||
for (let i = 1; i < n; i++) {
|
||||
for (let j = 1; j < m; j++) {
|
||||
matrix[i][j] += Math.min(matrix[i - 1][j], matrix[i][j - 1])
|
||||
}
|
||||
}
|
||||
|
||||
return matrix[n - 1][m - 1]
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
console.log(minCostPath([[2, 1], [3, 1], [4, 2]]))
|
||||
console.log(minCostPath([[2, 1, 4], [2, 1, 3], [3, 2, 1]]))
|
||||
}
|
||||
|
||||
main()
|
50
Dynamic-Programming/SudokuSolver.js
Normal file
50
Dynamic-Programming/SudokuSolver.js
Normal file
@ -0,0 +1,50 @@
|
||||
const _board = [
|
||||
['.', '9', '.', '.', '4', '2', '1', '3', '6'],
|
||||
['.', '.', '.', '9', '6', '.', '4', '8', '5'],
|
||||
['.', '.', '.', '5', '8', '1', '.', '.', '.'],
|
||||
['.', '.', '4', '.', '.', '.', '.', '.', '.'],
|
||||
['5', '1', '7', '2', '.', '.', '9', '.', '.'],
|
||||
['6', '.', '2', '.', '.', '.', '3', '7', '.'],
|
||||
['1', '.', '.', '8', '.', '4', '.', '2', '.'],
|
||||
['7', '.', '6', '.', '.', '.', '8', '1', '.'],
|
||||
['3', '.', '.', '.', '9', '.', '.', '.', '.']
|
||||
]
|
||||
|
||||
const isValid = (board, row, col, k) => {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const m = 3 * Math.floor(row / 3) + Math.floor(i / 3)
|
||||
const n = 3 * Math.floor(col / 3) + i % 3
|
||||
if (board[row][i] === k || board[i][col] === k || board[m][n] === k) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const sodokoSolver = (data) => {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
for (let j = 0; j < 9; j++) {
|
||||
if (data[i][j] === '.') {
|
||||
for (let k = 1; k <= 9; k++) {
|
||||
if (isValid(data, i, j, k)) {
|
||||
data[i][j] = `${k}`
|
||||
if (sodokoSolver(data)) {
|
||||
return true
|
||||
} else {
|
||||
data[i][j] = '.'
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// testing
|
||||
(() => {
|
||||
if (sodokoSolver(_board)) {
|
||||
console.log(_board)
|
||||
}
|
||||
})()
|
71
Dynamic-Programming/ZeroOneKnapsack.js
Normal file
71
Dynamic-Programming/ZeroOneKnapsack.js
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* A Dynamic Programming based solution for calculating Zero One Knapsack
|
||||
* https://en.wikipedia.org/wiki/Knapsack_problem
|
||||
*/
|
||||
|
||||
const zeroOneKnapsack = (arr, n, cap, cache) => {
|
||||
if (cap === 0 || n === 0) {
|
||||
cache[n][cap] = 0
|
||||
return cache[n][cap]
|
||||
}
|
||||
if (cache[n][cap] !== -1) {
|
||||
return cache[n][cap]
|
||||
}
|
||||
if (arr[n - 1][0] <= cap) {
|
||||
cache[n][cap] = Math.max(arr[n - 1][1] + zeroOneKnapsack(arr, n - 1, cap - arr[n - 1][0], cache), zeroOneKnapsack(arr, n - 1, cap, cache))
|
||||
return cache[n][cap]
|
||||
} else {
|
||||
cache[n][cap] = zeroOneKnapsack(arr, n - 1, cap, cache)
|
||||
return cache[n][cap]
|
||||
}
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
/*
|
||||
Problem Statement:
|
||||
You are a thief carrying a single bag with limited capacity S. The museum you stole had N artifact that you could steal. Unfortunately you might not be able to steal all the artifact because of your limited bag capacity.
|
||||
You have to cherry pick the artifact in order to maximize the total value of the artifacts you stole.
|
||||
|
||||
Link for the Problem: https://www.hackerrank.com/contests/srin-aadc03/challenges/classic-01-knapsack
|
||||
*/
|
||||
let input = `1
|
||||
4 5
|
||||
1 8
|
||||
2 4
|
||||
3 0
|
||||
2 5
|
||||
2 3`
|
||||
|
||||
input = input.trim().split('\n')
|
||||
input.shift()
|
||||
const length = input.length
|
||||
|
||||
let i = 0
|
||||
while (i < length) {
|
||||
const cap = Number(input[i].trim().split(' ')[0])
|
||||
const currlen = Number(input[i].trim().split(' ')[1])
|
||||
let j = i + 1
|
||||
const arr = []
|
||||
while (j <= i + currlen) {
|
||||
arr.push(input[j])
|
||||
j++
|
||||
}
|
||||
const newArr = []
|
||||
arr.map(e => {
|
||||
newArr.push(e.trim().split(' ').map(Number))
|
||||
})
|
||||
const cache = []
|
||||
for (let i = 0; i <= currlen; i++) {
|
||||
const temp = []
|
||||
for (let j = 0; j <= cap; j++) {
|
||||
temp.push(-1)
|
||||
}
|
||||
cache.push(temp)
|
||||
}
|
||||
const result = zeroOneKnapsack(newArr, currlen, cap, cache)
|
||||
console.log(result)
|
||||
i += currlen + 1
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
Reference in New Issue
Block a user