算法04-动态规划
1.动态规划-硬币找零
public class CoinChange {
// coin value, used calculateUseBackTracking()
//private final int[] coinValue = {10, 5, 2, 1};
// coin value, used calculateUseDP()
private final int[] coinValue = {1, 2, 5, 10};
// save change
private final List<Integer> coinList = new ArrayList<>();
public boolean calculateUseBackTracking(int value, int total, int coin, int coinValueIndex) {
if (value == total)
return true;
if (value > total) {
// first use max coin value try, not can use less coin value.
for (;coinValueIndex < coinValue.length; coinValueIndex++) {
total += coinValue[coinValueIndex];
coinList.add(coinValue[coinValueIndex]);
boolean result = calculateUseBackTracking(value, total, coinValue[coinValueIndex], coinValueIndex);
if (result) {
return true;
}
// back tracking
total -= coinValue[coinValueIndex];
coinList.remove(coinList.size() - 1);
}
}
return false;
}
public List<Integer> calculateUseBackTracking(int value) {
calculateUseBackTracking(value, 0, coinValue[0], 0);
return coinList;
}
public void calculateUseDP(int[][] checkerboard) {
final int row = checkerboard.length;
final int col = checkerboard[0].length;
for (int i = 1; i < row; i++) {
int temp = i - 1;
for (int j = 1; j < col; j++) {
int t = j % coinValue[temp];
if (t == 0)
// only use max value coin for current money
checkerboard[i][j] = j / coinValue[temp];
else if (j <= coinValue[temp])
// money <= coin for current row, so previous row
checkerboard[i][j] = checkerboard[temp][j];
else
// use current row coin value, remaining money divided use previous row save value
// for example, money is 13, first 13/5=2, next 13-(2*5)=3, go previous find 3
checkerboard[i][j] = j / coinValue[temp] + checkerboard[temp][t];
}
}
}
public List<Integer> calculateUseDP(int value) {
// length add 1, and zero not use, avoid each add calculate
int[][] checkerboard = new int[coinValue.length + 1][value + 1];
calculateUseDP(checkerboard);
for (int[] ints : checkerboard) {
for (int num : ints) {
System.out.print(num + "\t");
}
System.out.println();
}
// calculate i value, and i max is coinValue.length
int i = 0;
for (int money : coinValue) {
if (value >= money)
i++;
}
int j = value;
while (i > 0) {
int temp = i - 1;
// coin total number
int coinNumber = checkerboard[i][j];
// real coin total number
int realCoinNumber = j / coinValue[temp];
// remainingMoney
int remainingMoney = j % coinValue[temp];
// j is next calculate money
if (remainingMoney != 0)
j -= coinValue[temp] * realCoinNumber;
while (realCoinNumber-- > 0)
coinList.add(coinValue[temp]);
if (remainingMoney == 0)
break;
i--;
}
return coinList;
}
public static void main(String[] args) {
CoinChange change = new CoinChange();
//List<Integer> list = change.calculateUseBackTracking(109);
List<Integer> list = change.calculateUseDP(109);
System.out.println(list);
}
}
2.动态规划-最长子串
public class LongestPalindromeSubString {
public int expandAroundCenter(String s, int left, int right) {
// find is palindrome substring, left and right expand.
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1;
}
public String calculateLongestPalindromeSubStringForExpandAroundCenter(String s) {
if (s == null || s.length() < 2)
return s;
if (s.length() == 2 && s.charAt(0) == s.charAt(1))
return s;
int left = 0, right = 0;
for (int i = 0;i < s.length();i++) {
// i is center, i go expand that towards left and right
int length1 = expandAroundCenter(s, i, i);
// i+1 is center, i=1 go expand that towards left and right
// handle condition that abba
int length2 = expandAroundCenter(s, i, i + 1);
int length = Math.max(length1, length2);
if (right - left < length) {
// calculate left index by is palindrome substring length
left = i - (length - 1) / 2;
// calculate right index by is palindrome substring length
right = i + length / 2;
}
}
return s.substring(left, right + 1);
}
public String calculateLongestPalindromeSubStringForDP(String s) {
if (s == null || s.length() < 2)
return s;
if (s.length() == 2 && s.charAt(0) == s.charAt(1))
return s;
boolean[][] checkerboard = new boolean[s.length()][s.length()];
int maxLength = Integer.MIN_VALUE;
int startIndex = 0;
int endIndex = 0;
for (int i = 0;i < s.length();i++) {
for (int j = i;j >= 0;j--) {
// i - j <= 2 handle three condition.
// one a, two aa,ab, three aaa,abc,aba
// checkerboard[j + 1][i - 1] handle one condition.
// s(i)==s(j) and exclude (s(i) and s(j)) substring is palindrome
if (s.charAt(i) == s.charAt(j) && (i - j <= 2 || checkerboard[j + 1][i - 1])) {
checkerboard[j][i] = true;
if (i - j > maxLength) {
maxLength = i - j;
startIndex = j;
endIndex = i;
}
}
}
}
return s.substring(startIndex, endIndex + 1);
}
public static void main(String[] args) {
LongestPalindromeSubString calculate = new LongestPalindromeSubString();
String s = "aabaac";
//String result = calculate.calculateLongestPalindromeSubStringForDP(s);
String result = calculate.calculateLongestPalindromeSubStringForExpandAroundCenter(s);
System.out.println(result);
}
}