算法04-动态规划

算法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);
    }
}
posted @ 2022-05-28 16:07  行稳致远方  阅读(12)  评论(0)    收藏  举报