mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-24 04:54:21 +08:00
Change project structure to a Maven Java project + Refactor (#2816)
This commit is contained in:

committed by
GitHub

parent
8e533d2617
commit
9fb3364ccc
@ -0,0 +1,83 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/*
|
||||
* this is an important Algo in which
|
||||
* we have starting and ending of board and we have to reach
|
||||
* we have to count no. of ways
|
||||
* that help to reach end point i.e number by rolling dice
|
||||
* which have 1 to 6 digits
|
||||
|
||||
Test Case:
|
||||
here target is 10
|
||||
|
||||
int n=10;
|
||||
startAlgo();
|
||||
System.out.println(bpR(0,n));
|
||||
System.out.println(endAlgo()+"ms");
|
||||
int[] strg=new int [n+1];
|
||||
startAlgo();
|
||||
System.out.println(bpRS(0,n,strg));
|
||||
System.out.println(endAlgo()+"ms");
|
||||
startAlgo();
|
||||
System.out.println(bpIS(0,n,strg));
|
||||
System.out.println(endAlgo()+"ms");
|
||||
|
||||
|
||||
|
||||
*/
|
||||
public class BoardPath {
|
||||
|
||||
public static long startTime;
|
||||
public static long endTime;
|
||||
|
||||
public static void startAlgo() {
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static long endAlgo() {
|
||||
endTime = System.currentTimeMillis();
|
||||
return endTime - startTime;
|
||||
}
|
||||
|
||||
public static int bpR(int start, int end) {
|
||||
if (start == end) {
|
||||
return 1;
|
||||
} else if (start > end) {
|
||||
return 0;
|
||||
}
|
||||
int count = 0;
|
||||
for (int dice = 1; dice <= 6; dice++) {
|
||||
count += bpR(start + dice, end);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static int bpRS(int curr, int end, int strg[]) {
|
||||
if (curr == end) {
|
||||
return 1;
|
||||
} else if (curr > end) {
|
||||
return 0;
|
||||
}
|
||||
if (strg[curr] != 0) {
|
||||
return strg[curr];
|
||||
}
|
||||
int count = 0;
|
||||
for (int dice = 1; dice <= 6; dice++) {
|
||||
count += bpRS(curr + dice, end, strg);
|
||||
}
|
||||
strg[curr] = count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public static int bpIS(int curr, int end, int[] strg) {
|
||||
strg[end] = 1;
|
||||
for (int i = end - 1; i >= 0; i--) {
|
||||
int count = 0;
|
||||
for (int dice = 1; dice <= 6 && dice + i < strg.length; dice++) {
|
||||
count += strg[i + dice];
|
||||
}
|
||||
strg[i] = count;
|
||||
}
|
||||
return strg[0];
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/* A Naive recursive implementation
|
||||
of 0-1 Knapsack problem */
|
||||
public class BruteForceKnapsack {
|
||||
|
||||
// A utility function that returns
|
||||
// maximum of two integers
|
||||
static int max(int a, int b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
// Returns the maximum value that
|
||||
// can be put in a knapsack of
|
||||
// capacity W
|
||||
static int knapSack(int W, int wt[], int val[], int n) {
|
||||
// Base Case
|
||||
if (n == 0 || W == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If weight of the nth item is
|
||||
// more than Knapsack capacity W,
|
||||
// then this item cannot be included
|
||||
// in the optimal solution
|
||||
if (wt[n - 1] > W) {
|
||||
return knapSack(W, wt, val, n - 1);
|
||||
} // Return the maximum of two cases:
|
||||
// (1) nth item included
|
||||
// (2) not included
|
||||
else {
|
||||
return max(val[n - 1] + knapSack(W - wt[n - 1], wt, val, n - 1), knapSack(W, wt, val, n - 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Driver code
|
||||
public static void main(String args[]) {
|
||||
int val[] = new int[]{60, 100, 120};
|
||||
int wt[] = new int[]{10, 20, 30};
|
||||
int W = 50;
|
||||
int n = val.length;
|
||||
System.out.println(knapSack(W, wt, val, n));
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* This file contains an implementation of finding the nth CATALAN NUMBER using
|
||||
* dynamic programming Wikipedia: https://en.wikipedia.org/wiki/Catalan_number
|
||||
*
|
||||
* Time Complexity: O(n^2) Space Complexity: O(n)
|
||||
*
|
||||
* @author AMRITESH ANAND (https://github.com/amritesh19)
|
||||
*/
|
||||
import java.util.Scanner;
|
||||
|
||||
public class CatalanNumber {
|
||||
|
||||
/**
|
||||
* This method finds the nth Catalan number
|
||||
*
|
||||
* @param n input n which determines the nth Catalan number n should be less
|
||||
* than equal to 50 as 50th Catalan number is 6,533,841,209,031,609,592 for
|
||||
* n > 50, BigInteger class should be used instead long
|
||||
*
|
||||
* @return catalanArray[n] the nth Catalan number
|
||||
*/
|
||||
static long findNthCatalan(int n) {
|
||||
|
||||
// Array to store the results of subproblems i.e Catalan numbers from [1...n-1]
|
||||
long catalanArray[] = new long[n + 1];
|
||||
|
||||
// Initialising C₀ = 1 and C₁ = 1
|
||||
catalanArray[0] = 1;
|
||||
catalanArray[1] = 1;
|
||||
|
||||
/**
|
||||
* The Catalan numbers satisfy the recurrence relation C₀=1 and Cn = Σ
|
||||
* (Ci * Cn-1-i), i = 0 to n-1 , n > 0
|
||||
*/
|
||||
for (int i = 2; i <= n; i++) {
|
||||
catalanArray[i] = 0;
|
||||
for (int j = 0; j < i; j++) {
|
||||
catalanArray[i] += catalanArray[j] * catalanArray[i - j - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return catalanArray[n];
|
||||
}
|
||||
|
||||
// Main method
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
|
||||
System.out.println("Enter the number n to find nth Catalan number (n <= 50)");
|
||||
int n = sc.nextInt();
|
||||
System.out.println(n + "th Catalan number is " + findNthCatalan(n));
|
||||
|
||||
sc.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* @author Varun Upadhyay (https://github.com/varunu28)
|
||||
*/
|
||||
public class CoinChange {
|
||||
|
||||
// Driver Program
|
||||
public static void main(String[] args) {
|
||||
|
||||
int amount = 12;
|
||||
int[] coins = {2, 4, 5};
|
||||
|
||||
System.out.println(
|
||||
"Number of combinations of getting change for " + amount + " is: " + change(coins, amount));
|
||||
System.out.println(
|
||||
"Minimum number of coins required for amount :"
|
||||
+ amount
|
||||
+ " is: "
|
||||
+ minimumCoins(coins, amount));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method finds the number of combinations of getting change for a
|
||||
* given amount and change coins
|
||||
*
|
||||
* @param coins The list of coins
|
||||
* @param amount The amount for which we need to find the change Finds the
|
||||
* number of combinations of change
|
||||
*/
|
||||
public static int change(int[] coins, int amount) {
|
||||
|
||||
int[] combinations = new int[amount + 1];
|
||||
combinations[0] = 1;
|
||||
|
||||
for (int coin : coins) {
|
||||
for (int i = coin; i < amount + 1; i++) {
|
||||
combinations[i] += combinations[i - coin];
|
||||
}
|
||||
// Uncomment the below line to see the state of combinations for each coin
|
||||
// printAmount(combinations);
|
||||
}
|
||||
|
||||
return combinations[amount];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method finds the minimum number of coins needed for a given amount.
|
||||
*
|
||||
* @param coins The list of coins
|
||||
* @param amount The amount for which we need to find the minimum number of
|
||||
* coins. Finds the the minimum number of coins that make a given value.
|
||||
*/
|
||||
public static int minimumCoins(int[] coins, int amount) {
|
||||
// minimumCoins[i] will store the minimum coins needed for amount i
|
||||
int[] minimumCoins = new int[amount + 1];
|
||||
|
||||
minimumCoins[0] = 0;
|
||||
|
||||
for (int i = 1; i <= amount; i++) {
|
||||
minimumCoins[i] = Integer.MAX_VALUE;
|
||||
}
|
||||
for (int i = 1; i <= amount; i++) {
|
||||
for (int coin : coins) {
|
||||
if (coin <= i) {
|
||||
int sub_res = minimumCoins[i - coin];
|
||||
if (sub_res != Integer.MAX_VALUE && sub_res + 1 < minimumCoins[i]) {
|
||||
minimumCoins[i] = sub_res + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Uncomment the below line to see the state of combinations for each coin
|
||||
// printAmount(minimumCoins);
|
||||
return minimumCoins[amount];
|
||||
}
|
||||
|
||||
// A basic print method which prints all the contents of the array
|
||||
public static void printAmount(int[] arr) {
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
// Given N dice each with M faces, numbered from 1 to M, find the number of ways to get sum X.
|
||||
// X is the summation of values on each face when all the dice are thrown.
|
||||
|
||||
/* The Naive approach is to find all the possible combinations of values from n dice and
|
||||
keep on counting the results that sum to X. This can be done using recursion. */
|
||||
// The above recursion solution exhibits overlapping subproblems.
|
||||
|
||||
/* Hence, storing the results of the solved sub-problems saves time.
|
||||
And it can be done using Dynamic Programming(DP).
|
||||
Following is implementation of Dynamic Programming approach. */
|
||||
// Code ---->
|
||||
// Java program to find number of ways to get sum 'x' with 'n'
|
||||
// dice where every dice has 'm' faces
|
||||
class DP {
|
||||
|
||||
/* The main function that returns the number of ways to get sum 'x' with 'n' dice and 'm' with m faces. */
|
||||
public static long findWays(int m, int n, int x) {
|
||||
|
||||
/* Create a table to store the results of subproblems.
|
||||
One extra row and column are used for simplicity
|
||||
(Number of dice is directly used as row index and sum is directly used as column index).
|
||||
The entries in 0th row and 0th column are never used. */
|
||||
long[][] table = new long[n + 1][x + 1];
|
||||
|
||||
/* Table entries for only one dice */
|
||||
for (int j = 1; j <= m && j <= x; j++) {
|
||||
table[1][j] = 1;
|
||||
}
|
||||
|
||||
/* Fill rest of the entries in table using recursive relation
|
||||
i: number of dice, j: sum */
|
||||
for (int i = 2; i <= n; i++) {
|
||||
for (int j = 1; j <= x; j++) {
|
||||
for (int k = 1; k < j && k <= m; k++) {
|
||||
table[i][j] += table[i - 1][j - k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return table[n][x];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(findWays(4, 2, 1));
|
||||
System.out.println(findWays(2, 2, 3));
|
||||
System.out.println(findWays(6, 3, 8));
|
||||
System.out.println(findWays(4, 2, 5));
|
||||
System.out.println(findWays(4, 3, 5));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
OUTPUT:
|
||||
0
|
||||
2
|
||||
21
|
||||
4
|
||||
6
|
||||
*/
|
||||
// Time Complexity: O(m * n * x) where m is number of faces, n is number of dice and x is given sum.
|
||||
|
@ -0,0 +1,41 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
// A Dynamic Programming based solution
|
||||
// for 0-1 Knapsack problem
|
||||
public class DyanamicProgrammingKnapsack {
|
||||
|
||||
static int max(int a, int b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
// Returns the maximum value that can
|
||||
// be put in a knapsack of capacity W
|
||||
static int knapSack(int W, int wt[], int val[], int n) {
|
||||
int i, w;
|
||||
int K[][] = new int[n + 1][W + 1];
|
||||
|
||||
// Build table K[][] in bottom up manner
|
||||
for (i = 0; i <= n; i++) {
|
||||
for (w = 0; w <= W; w++) {
|
||||
if (i == 0 || w == 0) {
|
||||
K[i][w] = 0;
|
||||
} else if (wt[i - 1] <= w) {
|
||||
K[i][w] = max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]);
|
||||
} else {
|
||||
K[i][w] = K[i - 1][w];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return K[n][W];
|
||||
}
|
||||
|
||||
// Driver code
|
||||
public static void main(String args[]) {
|
||||
int val[] = new int[]{60, 100, 120};
|
||||
int wt[] = new int[]{10, 20, 30};
|
||||
int W = 50;
|
||||
int n = val.length;
|
||||
System.out.println(knapSack(W, wt, val, n));
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* A DynamicProgramming based solution for Edit Distance problem In Java
|
||||
* Description of Edit Distance with an Example:
|
||||
*
|
||||
* <p>
|
||||
* Edit distance is a way of quantifying how dissimilar two strings (e.g.,
|
||||
* words) are to one another, by counting the minimum number of operations
|
||||
* required to transform one string into the other. The distance operations are
|
||||
* the removal, insertion, or substitution of a character in the string.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* <p>
|
||||
* The Distance between "kitten" and "sitting" is 3. A minimal edit script that
|
||||
* transforms the former into the latter is:
|
||||
*
|
||||
* <p>
|
||||
* kitten → sitten (substitution of "s" for "k") sitten → sittin (substitution
|
||||
* of "i" for "e") sittin → sitting (insertion of "g" at the end).
|
||||
*
|
||||
* @author SUBHAM SANGHAI
|
||||
*/
|
||||
import java.util.Scanner;
|
||||
|
||||
public class EditDistance {
|
||||
|
||||
public static int minDistance(String word1, String word2) {
|
||||
int len1 = word1.length();
|
||||
int len2 = word2.length();
|
||||
// len1+1, len2+1, because finally return dp[len1][len2]
|
||||
int[][] dp = new int[len1 + 1][len2 + 1];
|
||||
/* If second string is empty, the only option is to
|
||||
insert all characters of first string into second*/
|
||||
for (int i = 0; i <= len1; i++) {
|
||||
dp[i][0] = i;
|
||||
}
|
||||
/* If first string is empty, the only option is to
|
||||
insert all characters of second string into first*/
|
||||
for (int j = 0; j <= len2; j++) {
|
||||
dp[0][j] = j;
|
||||
}
|
||||
// iterate though, and check last char
|
||||
for (int i = 0; i < len1; i++) {
|
||||
char c1 = word1.charAt(i);
|
||||
for (int j = 0; j < len2; j++) {
|
||||
char c2 = word2.charAt(j);
|
||||
// if last two chars equal
|
||||
if (c1 == c2) {
|
||||
// update dp value for +1 length
|
||||
dp[i + 1][j + 1] = dp[i][j];
|
||||
} else {
|
||||
/* if two characters are different ,
|
||||
then take the minimum of the various operations(i.e insertion,removal,substitution)*/
|
||||
int replace = dp[i][j] + 1;
|
||||
int insert = dp[i][j + 1] + 1;
|
||||
int delete = dp[i + 1][j] + 1;
|
||||
|
||||
int min = replace > insert ? insert : replace;
|
||||
min = delete > min ? min : delete;
|
||||
dp[i + 1][j + 1] = min;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* return the final answer , after traversing through both the strings*/
|
||||
return dp[len1][len2];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner input = new Scanner(System.in);
|
||||
String s1, s2;
|
||||
System.out.println("Enter the First String");
|
||||
s1 = input.nextLine();
|
||||
System.out.println("Enter the Second String");
|
||||
s2 = input.nextLine();
|
||||
// ans stores the final Edit Distance between the two strings
|
||||
int ans = minDistance(s1, s2);
|
||||
System.out.println(
|
||||
"The minimum Edit Distance between \"" + s1 + "\" and \"" + s2 + "\" is " + ans);
|
||||
input.close();
|
||||
}
|
||||
|
||||
// edit distance problem
|
||||
public static int editDistance(String s1, String s2) {
|
||||
int[][] storage = new int[s1.length() + 1][s2.length() + 1];
|
||||
return editDistance(s1, s2, storage);
|
||||
|
||||
}
|
||||
|
||||
public static int editDistance(String s1, String s2, int[][] storage) {
|
||||
int m = s1.length();
|
||||
int n = s2.length();
|
||||
if (storage[m][n] > 0) {
|
||||
return storage[m][n];
|
||||
|
||||
}
|
||||
if (m == 0) {
|
||||
storage[m][n] = n;
|
||||
return storage[m][n];
|
||||
|
||||
}
|
||||
if (n == 0) {
|
||||
storage[m][n] = m;
|
||||
return storage[m][n];
|
||||
|
||||
}
|
||||
if (s1.charAt(0) == s2.charAt(0)) {
|
||||
storage[m][n] = editDistance(s1.substring(1), s2.substring(1), storage);
|
||||
return storage[m][n];
|
||||
|
||||
} else {
|
||||
int op1 = editDistance(s1, s2.substring(1), storage);
|
||||
int op2 = editDistance(s1.substring(1), s2, storage);
|
||||
int op3 = editDistance(s1.substring(1), s2.substring(1), storage);
|
||||
storage[m][n] = 1 + Math.min(op1, Math.min(op2, op3));
|
||||
return storage[m][n];
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* DynamicProgramming solution for the Egg Dropping Puzzle
|
||||
*/
|
||||
public class EggDropping {
|
||||
|
||||
// min trials with n eggs and m floors
|
||||
private static int minTrials(int n, int m) {
|
||||
|
||||
int[][] eggFloor = new int[n + 1][m + 1];
|
||||
int result, x;
|
||||
|
||||
for (int i = 1; i <= n; i++) {
|
||||
eggFloor[i][0] = 0; // Zero trial for zero floor.
|
||||
eggFloor[i][1] = 1; // One trial for one floor
|
||||
}
|
||||
|
||||
// j trials for only 1 egg
|
||||
for (int j = 1; j <= m; j++) {
|
||||
eggFloor[1][j] = j;
|
||||
}
|
||||
|
||||
// Using bottom-up approach in DP
|
||||
for (int i = 2; i <= n; i++) {
|
||||
for (int j = 2; j <= m; j++) {
|
||||
eggFloor[i][j] = Integer.MAX_VALUE;
|
||||
for (x = 1; x <= j; x++) {
|
||||
result = 1 + Math.max(eggFloor[i - 1][x - 1], eggFloor[i][j - x]);
|
||||
|
||||
// choose min of all values for particular x
|
||||
if (result < eggFloor[i][j]) {
|
||||
eggFloor[i][j] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eggFloor[n][m];
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
int n = 2, m = 4;
|
||||
// result outputs min no. of trials in worst case for n eggs and m floors
|
||||
int result = minTrials(n, m);
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @author Varun Upadhyay (https://github.com/varunu28)
|
||||
*/
|
||||
public class Fibonacci {
|
||||
|
||||
private static Map<Integer, Integer> map = new HashMap<>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Methods all returning [0, 1, 1, 2, 3, 5, ...] for n = [0, 1, 2, 3, 4, 5, ...]
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int n = sc.nextInt();
|
||||
|
||||
System.out.println(fibMemo(n));
|
||||
System.out.println(fibBotUp(n));
|
||||
System.out.println(fibOptimized(n));
|
||||
sc.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method finds the nth fibonacci number using memoization technique
|
||||
*
|
||||
* @param n The input n for which we have to determine the fibonacci number
|
||||
* Outputs the nth fibonacci number
|
||||
*/
|
||||
public static int fibMemo(int n) {
|
||||
if (map.containsKey(n)) {
|
||||
return map.get(n);
|
||||
}
|
||||
|
||||
int f;
|
||||
|
||||
if (n <= 1) {
|
||||
f = n;
|
||||
} else {
|
||||
f = fibMemo(n - 1) + fibMemo(n - 2);
|
||||
map.put(n, f);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method finds the nth fibonacci number using bottom up
|
||||
*
|
||||
* @param n The input n for which we have to determine the fibonacci number
|
||||
* Outputs the nth fibonacci number
|
||||
*/
|
||||
public static int fibBotUp(int n) {
|
||||
|
||||
Map<Integer, Integer> fib = new HashMap<>();
|
||||
|
||||
for (int i = 0; i <= n; i++) {
|
||||
int f;
|
||||
if (i <= 1) {
|
||||
f = i;
|
||||
} else {
|
||||
f = fib.get(i - 1) + fib.get(i - 2);
|
||||
}
|
||||
fib.put(i, f);
|
||||
}
|
||||
|
||||
return fib.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method finds the nth fibonacci number using bottom up
|
||||
*
|
||||
* @param n The input n for which we have to determine the fibonacci number
|
||||
* Outputs the nth fibonacci number
|
||||
* <p>
|
||||
* This is optimized version of Fibonacci Program. Without using Hashmap and
|
||||
* recursion. It saves both memory and time. Space Complexity will be O(1)
|
||||
* Time Complexity will be O(n)
|
||||
* <p>
|
||||
* Whereas , the above functions will take O(n) Space.
|
||||
* @author Shoaib Rayeen (https://github.com/shoaibrayeen)
|
||||
*/
|
||||
public static int fibOptimized(int n) {
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
int prev = 0, res = 1, next;
|
||||
for (int i = 2; i <= n; i++) {
|
||||
next = prev + res;
|
||||
prev = res;
|
||||
res = next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Vector;
|
||||
|
||||
public class FordFulkerson {
|
||||
|
||||
static final int INF = 987654321;
|
||||
// edges
|
||||
static int V;
|
||||
static int[][] capacity, flow;
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("V : 6");
|
||||
V = 6;
|
||||
capacity = new int[V][V];
|
||||
|
||||
capacity[0][1] = 12;
|
||||
capacity[0][3] = 13;
|
||||
capacity[1][2] = 10;
|
||||
capacity[2][3] = 13;
|
||||
capacity[2][4] = 3;
|
||||
capacity[2][5] = 15;
|
||||
capacity[3][2] = 7;
|
||||
capacity[3][4] = 15;
|
||||
capacity[4][5] = 17;
|
||||
|
||||
System.out.println("Max capacity in networkFlow : " + networkFlow(0, 5));
|
||||
}
|
||||
|
||||
private static int networkFlow(int source, int sink) {
|
||||
flow = new int[V][V];
|
||||
int totalFlow = 0;
|
||||
while (true) {
|
||||
Vector<Integer> parent = new Vector<>(V);
|
||||
for (int i = 0; i < V; i++) {
|
||||
parent.add(-1);
|
||||
}
|
||||
Queue<Integer> q = new LinkedList<>();
|
||||
parent.set(source, source);
|
||||
q.add(source);
|
||||
while (!q.isEmpty() && parent.get(sink) == -1) {
|
||||
int here = q.peek();
|
||||
q.poll();
|
||||
for (int there = 0; there < V; ++there) {
|
||||
if (capacity[here][there] - flow[here][there] > 0 && parent.get(there) == -1) {
|
||||
q.add(there);
|
||||
parent.set(there, here);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent.get(sink) == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
int amount = INF;
|
||||
String printer = "path : ";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int p = sink; p != source; p = parent.get(p)) {
|
||||
amount = Math.min(capacity[parent.get(p)][p] - flow[parent.get(p)][p], amount);
|
||||
sb.append(p + "-");
|
||||
}
|
||||
sb.append(source);
|
||||
for (int p = sink; p != source; p = parent.get(p)) {
|
||||
flow[parent.get(p)][p] += amount;
|
||||
flow[p][parent.get(p)] -= amount;
|
||||
}
|
||||
totalFlow += amount;
|
||||
printer += sb.reverse() + " / max flow : " + totalFlow;
|
||||
System.out.println(printer);
|
||||
}
|
||||
|
||||
return totalFlow;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* Program to implement Kadane’s Algorithm to calculate maximum contiguous
|
||||
* subarray sum of an array Time Complexity: O(n)
|
||||
*
|
||||
* @author Nishita Aggarwal
|
||||
*/
|
||||
public class KadaneAlgorithm {
|
||||
|
||||
/**
|
||||
* This method implements Kadane's Algorithm
|
||||
*
|
||||
* @param arr The input array
|
||||
* @return The maximum contiguous subarray sum of the array
|
||||
*/
|
||||
static int largestContiguousSum(int arr[]) {
|
||||
int i, len = arr.length, cursum = 0, maxsum = Integer.MIN_VALUE;
|
||||
if (len == 0) // empty array
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
cursum += arr[i];
|
||||
if (cursum > maxsum) {
|
||||
maxsum = cursum;
|
||||
}
|
||||
if (cursum <= 0) {
|
||||
cursum = 0;
|
||||
}
|
||||
}
|
||||
return maxsum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method
|
||||
*
|
||||
* @param args Command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int n, arr[], i;
|
||||
n = sc.nextInt();
|
||||
arr = new int[n];
|
||||
for (i = 0; i < n; i++) {
|
||||
arr[i] = sc.nextInt();
|
||||
}
|
||||
int maxContSum = largestContiguousSum(arr);
|
||||
System.out.println(maxContSum);
|
||||
sc.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* A DynamicProgramming based solution for 0-1 Knapsack problem
|
||||
*/
|
||||
public class Knapsack {
|
||||
|
||||
private static int knapSack(int W, int wt[], int val[], int n) throws IllegalArgumentException {
|
||||
if (wt == null || val == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
int i, w;
|
||||
int rv[][] = new int[n + 1][W + 1]; // rv means return value
|
||||
|
||||
// Build table rv[][] in bottom up manner
|
||||
for (i = 0; i <= n; i++) {
|
||||
for (w = 0; w <= W; w++) {
|
||||
if (i == 0 || w == 0) {
|
||||
rv[i][w] = 0;
|
||||
} else if (wt[i - 1] <= w) {
|
||||
rv[i][w] = Math.max(val[i - 1] + rv[i - 1][w - wt[i - 1]], rv[i - 1][w]);
|
||||
} else {
|
||||
rv[i][w] = rv[i - 1][w];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv[n][W];
|
||||
}
|
||||
|
||||
// Driver program to test above function
|
||||
public static void main(String args[]) {
|
||||
int val[] = new int[]{50, 100, 130};
|
||||
int wt[] = new int[]{10, 20, 40};
|
||||
int W = 50;
|
||||
System.out.println(knapSack(W, wt, val, val.length));
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Recursive Solution for 0-1 knapsack with memoization
|
||||
*/
|
||||
public class KnapsackMemoization {
|
||||
|
||||
private static int[][] t;
|
||||
|
||||
// Returns the maximum value that can
|
||||
// be put in a knapsack of capacity W
|
||||
public static int knapsack(int[] wt, int[] value, int W, int n) {
|
||||
if (t[n][W] != -1) {
|
||||
return t[n][W];
|
||||
}
|
||||
if (n == 0 || W == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (wt[n - 1] <= W) {
|
||||
t[n - 1][W - wt[n - 1]] = knapsack(wt, value, W - wt[n - 1], n - 1);
|
||||
// Include item in the bag. In that case add the value of the item and call for the remaining items
|
||||
int tmp1 = value[n - 1] + t[n - 1][W - wt[n - 1]];
|
||||
// Don't include the nth item in the bag anl call for remaining item without reducing the weight
|
||||
int tmp2 = knapsack(wt, value, W, n - 1);
|
||||
t[n - 1][W] = tmp2;
|
||||
// include the larger one
|
||||
int tmp = tmp1 > tmp2 ? tmp1 : tmp2;
|
||||
t[n][W] = tmp;
|
||||
return tmp;
|
||||
// If Weight for the item is more than the desired weight then don't include it
|
||||
// Call for rest of the n-1 items
|
||||
} else if (wt[n - 1] > W) {
|
||||
t[n][W] = knapsack(wt, value, W, n - 1);
|
||||
return t[n][W];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Driver code
|
||||
public static void main(String args[]) {
|
||||
int[] wt = {1, 3, 4, 5};
|
||||
int[] value = {1, 4, 5, 7};
|
||||
int W = 10;
|
||||
t = new int[wt.length + 1][W + 1];
|
||||
Arrays.stream(t).forEach(a -> Arrays.fill(a, -1));
|
||||
int res = knapsack(wt, value, W, wt.length);
|
||||
System.out.println("Maximum knapsack value " + res);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* @author Kshitij VERMA (github.com/kv19971) LEVENSHTEIN DISTANCE dyamic
|
||||
* programming implementation to show the difference between two strings
|
||||
* (https://en.wikipedia.org/wiki/Levenshtein_distance)
|
||||
*/
|
||||
public class LevenshteinDistance {
|
||||
|
||||
private static int minimum(int a, int b, int c) {
|
||||
if (a < b && a < c) {
|
||||
return a;
|
||||
} else if (b < a && b < c) {
|
||||
return b;
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
private static int calculate_distance(String a, String b) {
|
||||
int len_a = a.length() + 1;
|
||||
int len_b = b.length() + 1;
|
||||
int[][] distance_mat = new int[len_a][len_b];
|
||||
for (int i = 0; i < len_a; i++) {
|
||||
distance_mat[i][0] = i;
|
||||
}
|
||||
for (int j = 0; j < len_b; j++) {
|
||||
distance_mat[0][j] = j;
|
||||
}
|
||||
for (int i = 0; i < len_a; i++) {
|
||||
for (int j = 0; j < len_b; j++) {
|
||||
int cost;
|
||||
if (a.charAt(i) == b.charAt(j)) {
|
||||
cost = 0;
|
||||
} else {
|
||||
cost = 1;
|
||||
}
|
||||
distance_mat[i][j]
|
||||
= minimum(distance_mat[i - 1][j], distance_mat[i - 1][j - 1], distance_mat[i][j - 1])
|
||||
+ cost;
|
||||
}
|
||||
}
|
||||
return distance_mat[len_a - 1][len_b - 1];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String a = ""; // enter your string here
|
||||
String b = ""; // enter your string here
|
||||
|
||||
System.out.print("Levenshtein distance between " + a + " and " + b + " is: ");
|
||||
System.out.println(calculate_distance(a, b));
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/*
|
||||
|
||||
* Problem Statement: -
|
||||
* Find Longest Alternating Subsequence
|
||||
|
||||
* A sequence {x1, x2, .. xn} is alternating sequence if its elements satisfy one of the following relations :
|
||||
|
||||
x1 < x2 > x3 < x4 > x5 < …. xn or
|
||||
x1 > x2 < x3 > x4 < x5 > …. xn
|
||||
*/
|
||||
public class LongestAlternatingSubsequence {
|
||||
|
||||
/* Function to return longest alternating subsequence length*/
|
||||
static int AlternatingLength(int arr[], int n) {
|
||||
/*
|
||||
|
||||
las[i][0] = Length of the longest
|
||||
alternating subsequence ending at
|
||||
index i and last element is
|
||||
greater than its previous element
|
||||
|
||||
las[i][1] = Length of the longest
|
||||
alternating subsequence ending at
|
||||
index i and last element is
|
||||
smaller than its previous
|
||||
element
|
||||
|
||||
*/
|
||||
int las[][] = new int[n][2]; // las = LongestAlternatingSubsequence
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
las[i][0] = las[i][1] = 1;
|
||||
}
|
||||
|
||||
int result = 1; // Initialize result
|
||||
|
||||
/* Compute values in bottom up manner */
|
||||
for (int i = 1; i < n; i++) {
|
||||
|
||||
/* Consider all elements as previous of arr[i]*/
|
||||
for (int j = 0; j < i; j++) {
|
||||
|
||||
/* If arr[i] is greater, then check with las[j][1] */
|
||||
if (arr[j] < arr[i] && las[i][0] < las[j][1] + 1) {
|
||||
las[i][0] = las[j][1] + 1;
|
||||
}
|
||||
|
||||
/* If arr[i] is smaller, then check with las[j][0]*/
|
||||
if (arr[j] > arr[i] && las[i][1] < las[j][0] + 1) {
|
||||
las[i][1] = las[j][0] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pick maximum of both values at index i */
|
||||
if (result < Math.max(las[i][0], las[i][1])) {
|
||||
result = Math.max(las[i][0], las[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int arr[] = {10, 22, 9, 33, 49, 50, 31, 60};
|
||||
int n = arr.length;
|
||||
System.out.println("Length of Longest " + "alternating subsequence is " + AlternatingLength(arr, n));
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
class LongestCommonSubsequence {
|
||||
|
||||
public static String getLCS(String str1, String str2) {
|
||||
|
||||
// At least one string is null
|
||||
if (str1 == null || str2 == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// At least one string is empty
|
||||
if (str1.length() == 0 || str2.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String[] arr1 = str1.split("");
|
||||
String[] arr2 = str2.split("");
|
||||
|
||||
// lcsMatrix[i][j] = LCS of first i elements of arr1 and first j characters of arr2
|
||||
int[][] lcsMatrix = new int[arr1.length + 1][arr2.length + 1];
|
||||
|
||||
for (int i = 0; i < arr1.length + 1; i++) {
|
||||
lcsMatrix[i][0] = 0;
|
||||
}
|
||||
for (int j = 1; j < arr2.length + 1; j++) {
|
||||
lcsMatrix[0][j] = 0;
|
||||
}
|
||||
for (int i = 1; i < arr1.length + 1; i++) {
|
||||
for (int j = 1; j < arr2.length + 1; j++) {
|
||||
if (arr1[i - 1].equals(arr2[j - 1])) {
|
||||
lcsMatrix[i][j] = lcsMatrix[i - 1][j - 1] + 1;
|
||||
} else {
|
||||
lcsMatrix[i][j]
|
||||
= lcsMatrix[i - 1][j] > lcsMatrix[i][j - 1] ? lcsMatrix[i - 1][j] : lcsMatrix[i][j - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return lcsString(str1, str2, lcsMatrix);
|
||||
}
|
||||
|
||||
public static String lcsString(String str1, String str2, int[][] lcsMatrix) {
|
||||
StringBuilder lcs = new StringBuilder();
|
||||
int i = str1.length(), j = str2.length();
|
||||
while (i > 0 && j > 0) {
|
||||
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
|
||||
lcs.append(str1.charAt(i - 1));
|
||||
i--;
|
||||
j--;
|
||||
} else if (lcsMatrix[i - 1][j] > lcsMatrix[i][j - 1]) {
|
||||
i--;
|
||||
} else {
|
||||
j--;
|
||||
}
|
||||
}
|
||||
return lcs.reverse().toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String str1 = "DSGSHSRGSRHTRD";
|
||||
String str2 = "DATRGAGTSHS";
|
||||
String lcs = getLCS(str1, str2);
|
||||
|
||||
// Print LCS
|
||||
if (lcs != null) {
|
||||
System.out.println("String 1: " + str1);
|
||||
System.out.println("String 2: " + str2);
|
||||
System.out.println("LCS: " + lcs);
|
||||
System.out.println("LCS length: " + lcs.length());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @author Afrizal Fikri (https://github.com/icalF)
|
||||
*/
|
||||
public class LongestIncreasingSubsequence {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int n = sc.nextInt();
|
||||
|
||||
int arr[] = new int[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
arr[i] = sc.nextInt();
|
||||
}
|
||||
|
||||
System.out.println(LIS(arr));
|
||||
System.out.println(findLISLen(arr));
|
||||
sc.close();
|
||||
}
|
||||
|
||||
private static int upperBound(int[] ar, int l, int r, int key) {
|
||||
while (l < r - 1) {
|
||||
int m = (l + r) >>> 1;
|
||||
if (ar[m] >= key) {
|
||||
r = m;
|
||||
} else {
|
||||
l = m;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private static int LIS(int[] array) {
|
||||
int N = array.length;
|
||||
if (N == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int[] tail = new int[N];
|
||||
|
||||
// always points empty slot in tail
|
||||
int length = 1;
|
||||
|
||||
tail[0] = array[0];
|
||||
for (int i = 1; i < N; i++) {
|
||||
|
||||
// new smallest value
|
||||
if (array[i] < tail[0]) {
|
||||
tail[0] = array[i];
|
||||
} // array[i] extends largest subsequence
|
||||
else if (array[i] > tail[length - 1]) {
|
||||
tail[length++] = array[i];
|
||||
} // array[i] will become end candidate of an existing subsequence or
|
||||
// Throw away larger elements in all LIS, to make room for upcoming grater elements than
|
||||
// array[i]
|
||||
// (and also, array[i] would have already appeared in one of LIS, identify the location and
|
||||
// replace it)
|
||||
else {
|
||||
tail[upperBound(tail, -1, length - 1, array[i])] = array[i];
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Alon Firestein (https://github.com/alonfirestein)
|
||||
*/
|
||||
// A function for finding the length of the LIS algorithm in O(nlogn) complexity.
|
||||
public static int findLISLen(int a[]) {
|
||||
int size = a.length;
|
||||
int arr[] = new int[size];
|
||||
arr[0] = a[0];
|
||||
int lis = 1;
|
||||
for (int i = 1; i < size; i++) {
|
||||
int index = binarySearchBetween(arr, lis, a[i]);
|
||||
arr[index] = a[i];
|
||||
if (index > lis) {
|
||||
lis++;
|
||||
}
|
||||
}
|
||||
return lis;
|
||||
}
|
||||
// O(logn)
|
||||
|
||||
private static int binarySearchBetween(int[] t, int end, int key) {
|
||||
int left = 0;
|
||||
int right = end;
|
||||
if (key < t[0]) {
|
||||
return 0;
|
||||
}
|
||||
if (key > t[end]) {
|
||||
return end + 1;
|
||||
}
|
||||
while (left < right - 1) {
|
||||
int middle = (left + right) / 2;
|
||||
if (t[middle] < key) {
|
||||
left = middle;
|
||||
} else {
|
||||
right = middle;
|
||||
}
|
||||
}
|
||||
return right;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* Algorithm explanation
|
||||
* https://www.educative.io/edpresso/longest-palindromic-subsequence-algorithm
|
||||
*/
|
||||
public class LongestPalindromicSubsequence {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String a = "BBABCBCAB";
|
||||
String b = "BABCBAB";
|
||||
|
||||
String aLPS = LPS(a);
|
||||
String bLPS = LPS(b);
|
||||
|
||||
System.out.println(a + " => " + aLPS);
|
||||
System.out.println(b + " => " + bLPS);
|
||||
}
|
||||
|
||||
public static String LPS(String original) throws IllegalArgumentException {
|
||||
StringBuilder reverse = new StringBuilder(original);
|
||||
reverse = reverse.reverse();
|
||||
return recursiveLPS(original, reverse.toString());
|
||||
}
|
||||
|
||||
private static String recursiveLPS(String original, String reverse) {
|
||||
String bestResult = "";
|
||||
|
||||
// no more chars, then return empty
|
||||
if (original.length() == 0 || reverse.length() == 0) {
|
||||
bestResult = "";
|
||||
} else {
|
||||
|
||||
// if the last chars match, then remove it from both strings and recur
|
||||
if (original.charAt(original.length() - 1) == reverse.charAt(reverse.length() - 1)) {
|
||||
String bestSubResult
|
||||
= recursiveLPS(
|
||||
original.substring(0, original.length() - 1),
|
||||
reverse.substring(0, reverse.length() - 1));
|
||||
|
||||
bestResult = reverse.charAt(reverse.length() - 1) + bestSubResult;
|
||||
} else {
|
||||
// otherwise (1) ignore the last character of reverse, and recur on original and updated
|
||||
// reverse again
|
||||
// (2) ignore the last character of original and recur on the updated original and reverse
|
||||
// again
|
||||
// then select the best result from these two subproblems.
|
||||
|
||||
String bestSubResult1 = recursiveLPS(original, reverse.substring(0, reverse.length() - 1));
|
||||
String bestSubResult2 = recursiveLPS(original.substring(0, original.length() - 1), reverse);
|
||||
if (bestSubResult1.length() > bestSubResult2.length()) {
|
||||
bestResult = bestSubResult1;
|
||||
} else {
|
||||
bestResult = bestSubResult2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/*
|
||||
* Algorithm explanation https://leetcode.com/problems/longest-palindromic-substring/
|
||||
*/
|
||||
public class LongestPalindromicSubstring {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String a = "babad";
|
||||
String b = "cbbd";
|
||||
|
||||
String aLPS = LPS(a);
|
||||
String bLPS = LPS(b);
|
||||
|
||||
System.out.println(a + " => " + aLPS);
|
||||
System.out.println(b + " => " + bLPS);
|
||||
}
|
||||
|
||||
private static String LPS(String input) {
|
||||
if (input == null || input.length() == 0) {
|
||||
return input;
|
||||
}
|
||||
boolean arr[][] = new boolean[input.length()][input.length()];
|
||||
int start = 0, end = 0;
|
||||
for (int g = 0; g < input.length(); g++) {
|
||||
for (int i = 0, j = g; j < input.length(); i++, j++) {
|
||||
|
||||
if (g == 0) {
|
||||
arr[i][j] = true;
|
||||
} else if (g == 1) {
|
||||
if (input.charAt(i) == input.charAt(j)) {
|
||||
arr[i][j] = true;
|
||||
} else {
|
||||
arr[i][j] = false;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (input.charAt(i) == input.charAt(j) && arr[i + 1][j - 1]) {
|
||||
arr[i][j] = true;
|
||||
} else {
|
||||
arr[i][j] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (arr[i][j]) {
|
||||
start = i;
|
||||
end = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
return input.substring(start, end + 1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* Given a string containing just the characters '(' and ')', find the length of
|
||||
* the longest valid (well-formed) parentheses substring.
|
||||
*
|
||||
* @author Libin Yang (https://github.com/yanglbme)
|
||||
* @since 2018/10/5
|
||||
*/
|
||||
public class LongestValidParentheses {
|
||||
|
||||
public static int getLongestValidParentheses(String s) {
|
||||
if (s == null || s.length() < 2) {
|
||||
return 0;
|
||||
}
|
||||
char[] chars = s.toCharArray();
|
||||
int n = chars.length;
|
||||
int[] res = new int[n];
|
||||
res[0] = 0;
|
||||
res[1] = chars[1] == ')' && chars[0] == '(' ? 2 : 0;
|
||||
|
||||
int max = res[1];
|
||||
|
||||
for (int i = 2; i < n; ++i) {
|
||||
if (chars[i] == ')') {
|
||||
if (chars[i - 1] == '(') {
|
||||
res[i] = res[i - 2] + 2;
|
||||
} else {
|
||||
int index = i - res[i - 1] - 1;
|
||||
if (index >= 0 && chars[index] == '(') {
|
||||
// ()(())
|
||||
res[i] = res[i - 1] + 2 + (index - 1 >= 0 ? res[index - 1] : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
max = Math.max(max, res[i]);
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
|
||||
while (true) {
|
||||
String str = sc.nextLine();
|
||||
if ("quit".equals(str)) {
|
||||
break;
|
||||
}
|
||||
|
||||
System.out.println("Len is: " + getLongestValidParentheses(str));
|
||||
}
|
||||
|
||||
sc.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class MatrixChainMultiplication {
|
||||
|
||||
private static Scanner scan = new Scanner(System.in);
|
||||
private static ArrayList<Matrix> mArray = new ArrayList<>();
|
||||
private static int size;
|
||||
private static int[][] m;
|
||||
private static int[][] s;
|
||||
private static int[] p;
|
||||
|
||||
public static void main(String[] args) {
|
||||
int count = 1;
|
||||
while (true) {
|
||||
String[] mSize = input("input size of matrix A(" + count + ") ( ex. 10 20 ) : ");
|
||||
int col = Integer.parseInt(mSize[0]);
|
||||
if (col == 0) {
|
||||
break;
|
||||
}
|
||||
int row = Integer.parseInt(mSize[1]);
|
||||
|
||||
Matrix matrix = new Matrix(count, col, row);
|
||||
mArray.add(matrix);
|
||||
count++;
|
||||
}
|
||||
for (Matrix m : mArray) {
|
||||
System.out.format("A(%d) = %2d x %2d%n", m.count(), m.col(), m.row());
|
||||
}
|
||||
|
||||
size = mArray.size();
|
||||
m = new int[size + 1][size + 1];
|
||||
s = new int[size + 1][size + 1];
|
||||
p = new int[size + 1];
|
||||
|
||||
for (int i = 0; i < size + 1; i++) {
|
||||
Arrays.fill(m[i], -1);
|
||||
Arrays.fill(s[i], -1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < p.length; i++) {
|
||||
p[i] = i == 0 ? mArray.get(i).col() : mArray.get(i - 1).row();
|
||||
}
|
||||
|
||||
matrixChainOrder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
System.out.print("-------");
|
||||
}
|
||||
System.out.println();
|
||||
printArray(m);
|
||||
for (int i = 0; i < size; i++) {
|
||||
System.out.print("-------");
|
||||
}
|
||||
System.out.println();
|
||||
printArray(s);
|
||||
for (int i = 0; i < size; i++) {
|
||||
System.out.print("-------");
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Optimal solution : " + m[1][size]);
|
||||
System.out.print("Optimal parens : ");
|
||||
printOptimalParens(1, size);
|
||||
}
|
||||
|
||||
private static void printOptimalParens(int i, int j) {
|
||||
if (i == j) {
|
||||
System.out.print("A" + i);
|
||||
} else {
|
||||
System.out.print("(");
|
||||
printOptimalParens(i, s[i][j]);
|
||||
printOptimalParens(s[i][j] + 1, j);
|
||||
System.out.print(")");
|
||||
}
|
||||
}
|
||||
|
||||
private static void printArray(int[][] array) {
|
||||
for (int i = 1; i < size + 1; i++) {
|
||||
for (int j = 1; j < size + 1; j++) {
|
||||
System.out.print(String.format("%7d", array[i][j]));
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private static void matrixChainOrder() {
|
||||
for (int i = 1; i < size + 1; i++) {
|
||||
m[i][i] = 0;
|
||||
}
|
||||
|
||||
for (int l = 2; l < size + 1; l++) {
|
||||
for (int i = 1; i < size - l + 2; i++) {
|
||||
int j = i + l - 1;
|
||||
m[i][j] = Integer.MAX_VALUE;
|
||||
|
||||
for (int k = i; k < j; k++) {
|
||||
int q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
|
||||
if (q < m[i][j]) {
|
||||
m[i][j] = q;
|
||||
s[i][j] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] input(String string) {
|
||||
System.out.print(string);
|
||||
return (scan.nextLine().split(" "));
|
||||
}
|
||||
}
|
||||
|
||||
class Matrix {
|
||||
|
||||
private int count;
|
||||
private int col;
|
||||
private int row;
|
||||
|
||||
Matrix(int count, int col, int row) {
|
||||
this.count = count;
|
||||
this.col = col;
|
||||
this.row = row;
|
||||
}
|
||||
|
||||
int count() {
|
||||
return count;
|
||||
}
|
||||
|
||||
int col() {
|
||||
return col;
|
||||
}
|
||||
|
||||
int row() {
|
||||
return row;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
// Matrix-chain Multiplication
|
||||
// Problem Statement
|
||||
// we have given a chain A1,A2,...,Ani of n matrices, where for i = 1,2,...,n,
|
||||
// matrix Ai has dimension pi−1 ×pi
|
||||
// , fully parenthesize the product A1A2 ···An in a way that
|
||||
// minimizes the number of scalar multiplications.
|
||||
public class MatrixChainRecursiveTopDownMemoisation {
|
||||
|
||||
static int Memoized_Matrix_Chain(int p[]) {
|
||||
int n = p.length;
|
||||
int m[][] = new int[n][n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
m[i][j] = Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
return Lookup_Chain(m, p, 1, n - 1);
|
||||
}
|
||||
|
||||
static int Lookup_Chain(int m[][], int p[], int i, int j) {
|
||||
if (i == j) {
|
||||
m[i][j] = 0;
|
||||
return m[i][j];
|
||||
}
|
||||
if (m[i][j] < Integer.MAX_VALUE) {
|
||||
return m[i][j];
|
||||
} else {
|
||||
for (int k = i; k < j; k++) {
|
||||
int q = Lookup_Chain(m, p, i, k) + Lookup_Chain(m, p, k + 1, j) + (p[i - 1] * p[k] * p[j]);
|
||||
if (q < m[i][j]) {
|
||||
m[i][j] = q;
|
||||
}
|
||||
}
|
||||
}
|
||||
return m[i][j];
|
||||
}
|
||||
|
||||
// in this code we are taking the example of 4 matrixes whose orders are 1x2,2x3,3x4,4x5 respectively
|
||||
// output should be Minimum number of multiplications is 38
|
||||
public static void main(String[] args) {
|
||||
|
||||
int arr[] = {1, 2, 3, 4, 5};
|
||||
System.out.println("Minimum number of multiplications is " + Memoized_Matrix_Chain(arr));
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
// Here is the top-down approach of
|
||||
// dynamic programming
|
||||
|
||||
public class MemoizationTechniqueKnapsack {
|
||||
|
||||
// A utility function that returns
|
||||
// maximum of two integers
|
||||
static int max(int a, int b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
// Returns the value of maximum profit
|
||||
static int knapSackRec(int W, int wt[], int val[], int n, int[][] dp) {
|
||||
|
||||
// Base condition
|
||||
if (n == 0 || W == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dp[n][W] != -1) {
|
||||
return dp[n][W];
|
||||
}
|
||||
|
||||
if (wt[n - 1] > W) // Store the value of function call
|
||||
// stack in table before return
|
||||
{
|
||||
return dp[n][W] = knapSackRec(W, wt, val, n - 1, dp);
|
||||
} else // Return value of table after storing
|
||||
{
|
||||
return dp[n][W]
|
||||
= max(
|
||||
(val[n - 1] + knapSackRec(W - wt[n - 1], wt, val, n - 1, dp)),
|
||||
knapSackRec(W, wt, val, n - 1, dp));
|
||||
}
|
||||
}
|
||||
|
||||
static int knapSack(int W, int wt[], int val[], int N) {
|
||||
|
||||
// Declare the table dynamically
|
||||
int dp[][] = new int[N + 1][W + 1];
|
||||
|
||||
// Loop to initially filled the
|
||||
// table with -1
|
||||
for (int i = 0; i < N + 1; i++) {
|
||||
for (int j = 0; j < W + 1; j++) {
|
||||
dp[i][j] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return knapSackRec(W, wt, val, N, dp);
|
||||
}
|
||||
|
||||
// Driver Code
|
||||
public static void main(String[] args) {
|
||||
int val[] = {60, 100, 120};
|
||||
int wt[] = {10, 20, 30};
|
||||
|
||||
int W = 50;
|
||||
int N = val.length;
|
||||
|
||||
System.out.println(knapSack(W, wt, val, N));
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/*
|
||||
Given the following grid with length m and width n:
|
||||
\---\---\---\ (n)
|
||||
\ 1 \ 3 \ 1 \
|
||||
\---\---\---\
|
||||
\ 1 \ 5 \ 1 \
|
||||
\---\---\---\
|
||||
\ 4 \ 2 \ 1 \
|
||||
\---\---\---\
|
||||
(m)
|
||||
Find the path where its sum is the smallest.
|
||||
|
||||
All numbers given are positive.
|
||||
The Time Complexity of your algorithm should be smaller than or equal to O(mn).
|
||||
The Space Complexity of your algorithm should be smaller than or equal to O(mn).
|
||||
You can only move from the top left corner to the down right corner.
|
||||
You can only move one step down or right.
|
||||
|
||||
EXAMPLE:
|
||||
INPUT: grid = [[1,3,1],[1,5,1],[4,2,1]]
|
||||
OUTPUT: 7
|
||||
EXPLANATIONS: 1 + 3 + 1 + 1 + 1 = 7
|
||||
|
||||
For more information see https://www.geeksforgeeks.org/maximum-path-sum-matrix/
|
||||
*/
|
||||
public class MinimumPathSum {
|
||||
|
||||
public void testRegular() {
|
||||
int[][] grid = {
|
||||
{1, 3, 1},
|
||||
{1, 5, 1},
|
||||
{4, 2, 1}
|
||||
};
|
||||
System.out.println(minimumPathSum(grid));
|
||||
}
|
||||
|
||||
public void testLessColumns() {
|
||||
int[][] grid = {
|
||||
{1, 2},
|
||||
{5, 6},
|
||||
{1, 1}
|
||||
};
|
||||
System.out.println(minimumPathSum(grid));
|
||||
}
|
||||
|
||||
public void testLessRows() {
|
||||
int[][] grid = {
|
||||
{2, 3, 3},
|
||||
{7, 2, 1}
|
||||
};
|
||||
System.out.println(minimumPathSum(grid));
|
||||
}
|
||||
|
||||
public void testOneRowOneColumn() {
|
||||
int[][] grid = {{2}};
|
||||
System.out.println(minimumPathSum(grid));
|
||||
}
|
||||
|
||||
public static int minimumPathSum(int[][] grid) {
|
||||
int m = grid.length, n = grid[0].length;
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
int[][] dp = new int[m][n];
|
||||
dp[0][0] = grid[0][0];
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
dp[0][i + 1] = dp[0][i] + grid[0][i + 1];
|
||||
}
|
||||
for (int i = 0; i < m - 1; i++) {
|
||||
dp[i + 1][0] = dp[i][0] + grid[i + 1][0];
|
||||
}
|
||||
for (int i = 1; i < m; i++) {
|
||||
for (int j = 1; j < n; j++) {
|
||||
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
|
||||
}
|
||||
}
|
||||
return dp[m - 1][n - 1];
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
// Partition a set into two subsets such that the difference of subset sums is minimum
|
||||
|
||||
/*
|
||||
Input: arr[] = {1, 6, 11, 5}
|
||||
Output: 1
|
||||
Explanation:
|
||||
Subset1 = {1, 5, 6}, sum of Subset1 = 12
|
||||
Subset2 = {11}, sum of Subset2 = 11
|
||||
|
||||
Input: arr[] = {36, 7, 46, 40}
|
||||
Output: 23
|
||||
Explanation:
|
||||
Subset1 = {7, 46} ; sum of Subset1 = 53
|
||||
Subset2 = {36, 40} ; sum of Subset2 = 76
|
||||
*/
|
||||
public class MinimumSumPartition {
|
||||
|
||||
public static int subSet(int[] arr) {
|
||||
int n = arr.length;
|
||||
int sum = getSum(arr);
|
||||
boolean[][] dp = new boolean[n + 1][sum + 1];
|
||||
for (int i = 0; i <= n; i++) {
|
||||
dp[i][0] = true;
|
||||
}
|
||||
for (int j = 0; j <= sum; j++) {
|
||||
dp[0][j] = false;
|
||||
}
|
||||
|
||||
// fill dp array
|
||||
for (int i = 1; i <= n; i++) {
|
||||
for (int j = 1; j <= sum; j++) {
|
||||
if (arr[i - 1] < j) {
|
||||
dp[i][j] = dp[i - 1][j - arr[i - 1]] || dp[i - 1][j];
|
||||
} else if (arr[i - 1] == j) {
|
||||
dp[i][j] = true;
|
||||
} else {
|
||||
dp[i][j] = dp[i - 1][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill the index array
|
||||
int[] index = new int[sum];
|
||||
int p = 0;
|
||||
for (int i = 0; i <= sum / 2; i++) {
|
||||
if (dp[n][i]) {
|
||||
index[p++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
return getMin(index, sum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate sum of array elements
|
||||
*
|
||||
* @param arr the array
|
||||
* @return sum of given array
|
||||
*/
|
||||
public static int getSum(int[] arr) {
|
||||
int sum = 0;
|
||||
for (int temp : arr) {
|
||||
sum += temp;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static int getMin(int[] arr, int sum) {
|
||||
if (arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (int temp : arr) {
|
||||
min = Math.min(min, sum - 2 * temp);
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Driver Code
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
assert subSet(new int[]{1, 6, 11, 5}) == 1;
|
||||
assert subSet(new int[]{36, 7, 46, 40}) == 23;
|
||||
assert subSet(new int[]{1, 2, 3, 9}) == 3;
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @file @brief Implements [Palindrome
|
||||
* Partitioning](https://leetcode.com/problems/palindrome-partitioning-ii/)
|
||||
* algorithm, giving you the minimum number of partitions you need to make
|
||||
*
|
||||
* @details palindrome partitioning uses dynamic programming and goes to all the
|
||||
* possible partitions to find the minimum you are given a string and you need
|
||||
* to give minimum number of partitions needed to divide it into a number of
|
||||
* palindromes [Palindrome Partitioning]
|
||||
* (https://www.geeksforgeeks.org/palindrome-partitioning-dp-17/) overall time
|
||||
* complexity O(n^2) For example: example 1:- String : "nitik" Output : 2 => "n
|
||||
* | iti | k" For example: example 2:- String : "ababbbabbababa" Output : 3 =>
|
||||
* "aba | b | bbabb | ababa"
|
||||
* @author [Syed] (https://github.com/roeticvampire)
|
||||
*/
|
||||
public class PalindromicPartitioning {
|
||||
|
||||
public static int minimalpartitions(String word) {
|
||||
int len = word.length();
|
||||
/* We Make two arrays to create a bottom-up solution.
|
||||
minCuts[i] = Minimum number of cuts needed for palindrome partitioning of substring word[0..i]
|
||||
isPalindrome[i][j] = true if substring str[i..j] is palindrome
|
||||
Base Condition: C[i] is 0 if P[0][i]= true
|
||||
*/
|
||||
int[] minCuts = new int[len];
|
||||
boolean[][] isPalindrome = new boolean[len][len];
|
||||
|
||||
int i, j, L; // different looping variables
|
||||
|
||||
// Every substring of length 1 is a palindrome
|
||||
for (i = 0; i < len; i++) {
|
||||
isPalindrome[i][i] = true;
|
||||
}
|
||||
|
||||
/* L is substring length. Build the solution in bottom up manner by considering all substrings of length starting from 2 to n. */
|
||||
for (L = 2; L <= len; L++) {
|
||||
// For substring of length L, set different possible starting indexes
|
||||
for (i = 0; i < len - L + 1; i++) {
|
||||
j = i + L - 1; // Ending index
|
||||
// If L is 2, then we just need to
|
||||
// compare two characters. Else need to
|
||||
// check two corner characters and value
|
||||
// of P[i+1][j-1]
|
||||
if (L == 2) {
|
||||
isPalindrome[i][j] = (word.charAt(i) == word.charAt(j));
|
||||
} else {
|
||||
if ((word.charAt(i) == word.charAt(j)) && isPalindrome[i + 1][j - 1]) {
|
||||
isPalindrome[i][j] = true;
|
||||
} else {
|
||||
isPalindrome[i][j] = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//We find the minimum for each index
|
||||
for (i = 0; i < len; i++) {
|
||||
if (isPalindrome[0][i] == true) {
|
||||
minCuts[i] = 0;
|
||||
} else {
|
||||
minCuts[i] = Integer.MAX_VALUE;
|
||||
for (j = 0; j < i; j++) {
|
||||
if (isPalindrome[j + 1][i] == true && 1 + minCuts[j] < minCuts[i]) {
|
||||
minCuts[i] = 1 + minCuts[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the min cut value for complete
|
||||
// string. i.e., str[0..n-1]
|
||||
return minCuts[len - 1];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner input = new Scanner(System.in);
|
||||
String word;
|
||||
System.out.println("Enter the First String");
|
||||
word = input.nextLine();
|
||||
// ans stores the final minimal cut count needed for partitioning
|
||||
int ans = minimalpartitions(word);
|
||||
System.out.println(
|
||||
"The minimum cuts needed to partition \"" + word + "\" into palindromes is " + ans);
|
||||
input.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* Given a text and wildcard pattern implement a wildcard pattern matching
|
||||
* algorithm that finds if wildcard is matched with text. The matching should
|
||||
* cover the entire text ?-> matches single characters *-> match the sequence of
|
||||
* characters
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* For calculation of Time and Space Complexity. Let N be length of src and M be
|
||||
* length of pat
|
||||
*
|
||||
*/
|
||||
public class RegexMatching {
|
||||
|
||||
// Method 1: Using Recursion
|
||||
// Time Complexity=0(2^(N+M)) Space Complexity=Recursion Extra Space
|
||||
static boolean regexRecursion(String src, String pat) {
|
||||
if (src.length() == 0 && pat.length() == 0) {
|
||||
return true;
|
||||
}
|
||||
if (src.length() != 0 && pat.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (src.length() == 0 && pat.length() != 0) {
|
||||
for (int i = 0; i < pat.length(); i++) {
|
||||
if (pat.charAt(i) != '*') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
char chs = src.charAt(0);
|
||||
char chp = pat.charAt(0);
|
||||
|
||||
String ros = src.substring(1);
|
||||
String rop = pat.substring(1);
|
||||
|
||||
boolean ans;
|
||||
if (chs == chp || chp == '?') {
|
||||
ans = regexRecursion(ros, rop);
|
||||
} else if (chp == '*') {
|
||||
boolean blank = regexRecursion(src, rop);
|
||||
boolean multiple = regexRecursion(ros, pat);
|
||||
ans = blank || multiple;
|
||||
} else {
|
||||
ans = false;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// Method 2: Using Recursion and breaking string using virtual index
|
||||
// Time Complexity=0(2^(N+M)) Space Complexity=Recursion Extra Space
|
||||
static boolean regexRecursion(String src, String pat, int svidx, int pvidx) {
|
||||
if (src.length() == svidx && pat.length() == pvidx) {
|
||||
return true;
|
||||
}
|
||||
if (src.length() != svidx && pat.length() == pvidx) {
|
||||
return false;
|
||||
}
|
||||
if (src.length() == svidx && pat.length() != pvidx) {
|
||||
for (int i = pvidx; i < pat.length(); i++) {
|
||||
if (pat.charAt(i) != '*') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
char chs = src.charAt(svidx);
|
||||
char chp = pat.charAt(pvidx);
|
||||
|
||||
boolean ans;
|
||||
if (chs == chp || chp == '?') {
|
||||
ans = regexRecursion(src, pat, svidx + 1, pvidx + 1);
|
||||
} else if (chp == '*') {
|
||||
boolean blank = regexRecursion(src, pat, svidx, pvidx + 1);
|
||||
boolean multiple = regexRecursion(src, pat, svidx + 1, pvidx);
|
||||
ans = blank || multiple;
|
||||
} else {
|
||||
ans = false;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// Method 3: Top-Down DP(Memoization)
|
||||
// Time Complexity=0(N*M) Space Complexity=0(N*M)+Recursion Extra Space
|
||||
static boolean regexRecursion(String src, String pat, int svidx, int pvidx, int[][] strg) {
|
||||
if (src.length() == svidx && pat.length() == pvidx) {
|
||||
return true;
|
||||
}
|
||||
if (src.length() != svidx && pat.length() == pvidx) {
|
||||
return false;
|
||||
}
|
||||
if (src.length() == svidx && pat.length() != pvidx) {
|
||||
for (int i = pvidx; i < pat.length(); i++) {
|
||||
if (pat.charAt(i) != '*') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (strg[svidx][pvidx] != 0) {
|
||||
return strg[svidx][pvidx] == 1 ? false : true;
|
||||
}
|
||||
char chs = src.charAt(svidx);
|
||||
char chp = pat.charAt(pvidx);
|
||||
|
||||
boolean ans;
|
||||
if (chs == chp || chp == '?') {
|
||||
ans = regexRecursion(src, pat, svidx + 1, pvidx + 1, strg);
|
||||
} else if (chp == '*') {
|
||||
boolean blank = regexRecursion(src, pat, svidx, pvidx + 1, strg);
|
||||
boolean multiple = regexRecursion(src, pat, svidx + 1, pvidx, strg);
|
||||
ans = blank || multiple;
|
||||
} else {
|
||||
ans = false;
|
||||
}
|
||||
strg[svidx][pvidx] = ans == false ? 1 : 2;
|
||||
return ans;
|
||||
}
|
||||
|
||||
// Method 4: Bottom-Up DP(Tabulation)
|
||||
// Time Complexity=0(N*M) Space Complexity=0(N*M)
|
||||
static boolean regexBU(String src, String pat) {
|
||||
|
||||
boolean strg[][] = new boolean[src.length() + 1][pat.length() + 1];
|
||||
strg[src.length()][pat.length()] = true;
|
||||
for (int row = src.length(); row >= 0; row--) {
|
||||
for (int col = pat.length() - 1; col >= 0; col--) {
|
||||
if (row == src.length()) {
|
||||
if (pat.charAt(col) == '*') {
|
||||
strg[row][col] = strg[row][col + 1];
|
||||
} else {
|
||||
strg[row][col] = false;
|
||||
}
|
||||
} else {
|
||||
char chs = src.charAt(row);
|
||||
char chp = pat.charAt(col);
|
||||
|
||||
boolean ans;
|
||||
if (chs == chp || chp == '?') {
|
||||
ans = strg[row + 1][col + 1];
|
||||
} else if (chp == '*') {
|
||||
boolean blank = strg[row][col + 1];
|
||||
boolean multiple = strg[row + 1][col];
|
||||
ans = blank || multiple;
|
||||
} else {
|
||||
ans = false;
|
||||
}
|
||||
strg[row][col] = ans;
|
||||
}
|
||||
}
|
||||
}
|
||||
return strg[0][0];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
String src = "aa";
|
||||
String pat = "*";
|
||||
System.out.println("Method 1: " + regexRecursion(src, pat));
|
||||
System.out.println("Method 2: " + regexRecursion(src, pat, 0, 0));
|
||||
System.out.println("Method 3: " + regexRecursion(src, pat, 0, 0, new int[src.length()][pat.length()]));
|
||||
System.out.println("Method 4: " + regexBU(src, pat));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// Memoization vs Tabulation : https://www.geeksforgeeks.org/tabulation-vs-memoization/
|
||||
// Question Link : https://practice.geeksforgeeks.org/problems/wildcard-pattern-matching/1
|
@ -0,0 +1,32 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* A DynamicProgramming solution for Rod cutting problem Returns the best
|
||||
* obtainable price for a rod of length n and price[] as prices of different
|
||||
* pieces
|
||||
*/
|
||||
public class RodCutting {
|
||||
|
||||
private static int cutRod(int[] price, int n) {
|
||||
int val[] = new int[n + 1];
|
||||
val[0] = 0;
|
||||
|
||||
for (int i = 1; i <= n; i++) {
|
||||
int max_val = Integer.MIN_VALUE;
|
||||
for (int j = 0; j < i; j++) {
|
||||
max_val = Math.max(max_val, price[j] + val[i - j - 1]);
|
||||
}
|
||||
|
||||
val[i] = max_val;
|
||||
}
|
||||
|
||||
return val[n];
|
||||
}
|
||||
|
||||
// main function to test
|
||||
public static void main(String args[]) {
|
||||
int[] arr = new int[]{2, 5, 13, 19, 20};
|
||||
int result = cutRod(arr, arr.length);
|
||||
System.out.println("Maximum Obtainable Value is " + result);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
// Java program to find length of the shortest supersequence
|
||||
class ShortestSuperSequence {
|
||||
|
||||
// Function to find length of the
|
||||
// shortest supersequence of X and Y.
|
||||
static int shortestSuperSequence(String X, String Y) {
|
||||
int m = X.length();
|
||||
int n = Y.length();
|
||||
|
||||
// find lcs
|
||||
int l = lcs(X, Y, m, n);
|
||||
|
||||
// Result is sum of input string
|
||||
// lengths - length of lcs
|
||||
return (m + n - l);
|
||||
}
|
||||
|
||||
// Returns length of LCS
|
||||
// for X[0..m - 1], Y[0..n - 1]
|
||||
static int lcs(String X, String Y, int m, int n) {
|
||||
int[][] L = new int[m + 1][n + 1];
|
||||
int i, j;
|
||||
|
||||
// Following steps build L[m + 1][n + 1]
|
||||
// in bottom up fashion. Note that
|
||||
// L[i][j] contains length of LCS
|
||||
// of X[0..i - 1]and Y[0..j - 1]
|
||||
for (i = 0; i <= m; i++) {
|
||||
for (j = 0; j <= n; j++) {
|
||||
if (i == 0 || j == 0) {
|
||||
L[i][j] = 0;
|
||||
} else if (X.charAt(i - 1) == Y.charAt(j - 1)) {
|
||||
L[i][j] = L[i - 1][j - 1] + 1;
|
||||
} else {
|
||||
L[i][j] = Math.max(L[i - 1][j],
|
||||
L[i][j - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// L[m][n] contains length of LCS
|
||||
// for X[0..n - 1] and Y[0..m - 1]
|
||||
return L[m][n];
|
||||
}
|
||||
|
||||
// Driver code
|
||||
public static void main(String args[]) {
|
||||
String X = "AGGTAB";
|
||||
String Y = "GXTXAYB";
|
||||
|
||||
System.out.println("Length of the shortest "
|
||||
+ "supersequence is "
|
||||
+ shortestSuperSequence(X, Y));
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
public class SubsetSum {
|
||||
|
||||
/**
|
||||
* Driver Code
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
int[] arr = new int[]{50, 4, 10, 15, 34};
|
||||
assert subsetSum(arr, 64);
|
||||
/* 4 + 10 + 15 + 34 = 64 */
|
||||
assert subsetSum(arr, 99);
|
||||
/* 50 + 15 + 34 = 99 */
|
||||
assert !subsetSum(arr, 5);
|
||||
assert !subsetSum(arr, 66);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a set of integers contains a subset that sum to a given integer.
|
||||
*
|
||||
* @param arr the array contains integers.
|
||||
* @param sum target sum of subset.
|
||||
* @return {@code true} if subset exists, otherwise {@code false}.
|
||||
*/
|
||||
private static boolean subsetSum(int[] arr, int sum) {
|
||||
int n = arr.length;
|
||||
boolean[][] isSum = new boolean[n + 2][sum + 1];
|
||||
|
||||
isSum[n + 1][0] = true;
|
||||
for (int i = 1; i <= sum; i++) {
|
||||
isSum[n + 1][i] = false;
|
||||
}
|
||||
|
||||
for (int i = n; i > 0; i--) {
|
||||
isSum[i][0] = true;
|
||||
for (int j = 1; j <= arr[i - 1] - 1; j++) {
|
||||
if (j <= sum) {
|
||||
isSum[i][j] = isSum[i + 1][j];
|
||||
}
|
||||
}
|
||||
for (int j = arr[i - 1]; j <= sum; j++) {
|
||||
isSum[i][j] = (isSum[i + 1][j] || isSum[i + 1][j - arr[i - 1]]);
|
||||
}
|
||||
}
|
||||
|
||||
return isSum[1][sum];
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
public class Sum_Of_Subset {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
int[] arr = {7, 3, 2, 5, 8};
|
||||
int Key = 14;
|
||||
|
||||
if (subsetSum(arr, arr.length - 1, Key)) {
|
||||
System.out.print("Yes, that sum exists");
|
||||
} else {
|
||||
System.out.print("Nope, that number does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean subsetSum(int[] arr, int num, int Key) {
|
||||
if (Key == 0) {
|
||||
return true;
|
||||
}
|
||||
if (num < 0 || Key < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean include = subsetSum(arr, num - 1, Key - arr[num]);
|
||||
boolean exclude = subsetSum(arr, num - 1, Key);
|
||||
|
||||
return include || exclude;
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.thealgorithms.dynamicprogramming;
|
||||
|
||||
/**
|
||||
* Imagine you have a collection of N wines placed next to each other on the
|
||||
* shelf. The price of ith wine is pi(Prices of different wines are different).
|
||||
* Because wine gets better every year supposing today is year 1, on year y the
|
||||
* price would be y*pi i.e y times the value of the initial year. You want to
|
||||
* sell all wines but you have to sell one wine per year. One more constraint on
|
||||
* each year you are allowed to sell either leftmost or rightmost wine on the
|
||||
* shelf. You are not allowed to reorder. You have to find the maximum profit
|
||||
*
|
||||
*/
|
||||
public class WineProblem {
|
||||
|
||||
// Method 1: Using Recursion
|
||||
// Time Complexity=0(2^N) Space Complexity=Recursion extra space
|
||||
public static int WPRecursion(int[] arr, int si, int ei) {
|
||||
int n = arr.length;
|
||||
int year = (n - (ei - si + 1)) + 1;
|
||||
if (si == ei) {
|
||||
return arr[si] * year;
|
||||
}
|
||||
|
||||
int start = WPRecursion(arr, si + 1, ei) + arr[si] * year;
|
||||
int end = WPRecursion(arr, si, ei - 1) + arr[ei] * year;
|
||||
|
||||
int ans = Math.max(start, end);
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
// Method 2: Top-Down DP(Memoization)
|
||||
// Time Complexity=0(N*N) Space Complexity=0(N*N)+Recursion extra space
|
||||
public static int WPTD(int[] arr, int si, int ei, int[][] strg) {
|
||||
int n = arr.length;
|
||||
int year = (n - (ei - si + 1)) + 1;
|
||||
if (si == ei) {
|
||||
return arr[si] * year;
|
||||
}
|
||||
|
||||
if (strg[si][ei] != 0) {
|
||||
return strg[si][ei];
|
||||
}
|
||||
int start = WPTD(arr, si + 1, ei, strg) + arr[si] * year;
|
||||
int end = WPTD(arr, si, ei - 1, strg) + arr[ei] * year;
|
||||
|
||||
int ans = Math.max(start, end);
|
||||
|
||||
strg[si][ei] = ans;
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
// Method 3: Bottom-Up DP(Tabulation)
|
||||
// Time Complexity=0(N*N/2)->0(N*N) Space Complexity=0(N*N)
|
||||
public static int WPBU(int[] arr) {
|
||||
int n = arr.length;
|
||||
int[][] strg = new int[n][n];
|
||||
|
||||
for (int slide = 0; slide <= n - 1; slide++) {
|
||||
for (int si = 0; si <= n - slide - 1; si++) {
|
||||
int ei = si + slide;
|
||||
int year = (n - (ei - si + 1)) + 1;
|
||||
if (si == ei) {
|
||||
strg[si][ei] = arr[si] * year;
|
||||
} else {
|
||||
int start = strg[si + 1][ei] + arr[si] * year;
|
||||
int end = strg[si][ei - 1] + arr[ei] * year;
|
||||
|
||||
strg[si][ei] = Math.max(start, end);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return strg[0][n - 1];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = {2, 3, 5, 1, 4};
|
||||
System.out.println("Method 1: " + WPRecursion(arr, 0, arr.length - 1));
|
||||
System.out.println("Method 2: " + WPTD(arr, 0, arr.length - 1, new int[arr.length][arr.length]));
|
||||
System.out.println("Method 3: " + WPBU(arr));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// Memoization vs Tabulation : https://www.geeksforgeeks.org/tabulation-vs-memoization/
|
||||
// Question Link : https://www.geeksforgeeks.org/maximum-profit-sale-wines/
|
Reference in New Issue
Block a user