1. 程式人生 > 其它 >C++24小時制轉換成12小時制

C++24小時制轉換成12小時制

最長迴文子序列

題目:給定一個字串s,找到其中最長的迴文子序列(注意,子序列跟子串是不一樣的。子序列是從字串中取出元素,相對順序不變,但是可以不挨著。子串肯定是擷取一段)

解法

  • 遞迴
  • 自頂向下的備忘錄
  • 自底向上的動態規劃
    - 狀態定義:dp[i][j]表示s的第i個字元到第j個字元之間組成的子序列中,最長的迴文子序列的長度是多少?
    - 狀態轉移方程:(然後注意遍歷順序,i 從最後一個字元開始往前遍歷,j 從 i + 1 開始往後遍歷,這樣可以保證每個子問題都已經算好了)
    ---> dp[i][j] = dp[i+1][j-1] +2; if s[i] == s[j]
    ---> dp[i][j] = max{dp[i+1][j] , dp[i][j-1]} ,else if s[i] != s[j]
    - 初始化:dp[i][i] == 1
    - 結果:dp[0][n-1]

動態規劃求解的過程

All Coding

import java.util.*;
class Solution{
	/**
	給定一個字串s,找到其中最長的迴文子序列
	注意,子序列跟子串是不一樣的。子序列是從字串中取出元素,相對順序不變,但是可以不挨著。子串肯定是擷取一段。
	*/
	public static void main(String[] args) {
		String s = "bbbab";
		System.out.println("-------------------");
		System.out.println(lps1(s));
		System.out.println("-------------------");
		System.out.println(lps2(s));
		System.out.println("-------------------");
		System.out.println(lps3(s));
	}
	/**
	遞迴
	*/
	public static int lps1(String s){
		if(s == null || s.length() == 0) return 0;
		int len = s.length();
		char[] str = s.toCharArray();
		return helper1(str,0,len-1);

	}
	public static int helper1(char[] str,int i,int j){
		if(i==j) return 1;
		if(i==j-1) return str[i] == str[j]?2:1;
		if(str[i] == str[j]) return 2 + helper1(str,i+1,j-1);
		else return Math.max(helper1(str,i,j-1),helper1(str,i+1,j));

	}
	/**
	備忘錄
	*/
	public static int lps2(String s){
		if(s == null || s.length() == 0) return 0;
		int len = s.length();
		char[] str = s.toCharArray();
		int[][] re = new int[len][len];
		return helper2(str,0,len-1,re);

	}
	public static int helper2(char[] str,int i,int j,int[][] re){
		if(re[i][j]!=0) return re[i][j];
		if(i==j) return re[i][j] = 1;
		if(i==j-1) return re[i][j] = str[i] == str[j]?2:1;
		if(str[i] == str[j]) return re[i][j] =  2 + helper1(str,i+1,j-1);
		else return re[i][j] =  Math.max(helper1(str,i,j-1),helper1(str,i+1,j));
	}
	/**
	dp,也就是自底向上
	狀態定義:dp[i][j]表示s的第i個字元到第j個字元之間組成的子序列中,最長的迴文子序列的長度是多少?
	狀態轉移方程:(然後注意遍歷順序,i 從最後一個字元開始往前遍歷,j 從 i + 1 開始往後遍歷,這樣可以保證每個子問題都已經算好了。)
		dp[i][j] = dp[i+1][j-1] +2; if s[i] == s[j]
		dp[i][j] = max{dp[i+1][j] , dp[i][j-1]} ,else if s[i] != s[j]
	初始化:dp[i][i] == 1
	結果:dp[0][n-1]

	*/
	public static int lps3(String s){
		if(s==null || s.length() == 0) return 0;
		int len = s.length();
		char[] str = s.toCharArray();
		int[][] dp = new int[len][len];
		for(int i = len-1;i>=0;i--){
			dp[i][i] = 1;
			for(int j = i+1;j<len;j++){
				if(str[i] == str[j]) dp[i][j] = dp[i+1][j-1] +2;
				else dp[i][j] = Math.max(dp[i+1][j],dp[i][j-1]);
			}
		}
		return dp[0][len-1];

	}
}