# 算法 || 记一次递归到dp优化实例 #
# *leetcode 115
1、暴力递归(Java)
1 public class Solutions { 2 public static int numDistinct(String s, String t) { 3 return dfs (s,t,0,""); 4 } 5 6 public static int dfs(String s, String t, int index, String cur) { 7 if (index == s.length()) { 8 return cur.equals(t) ? 1 : 0; 9 } 10 return dfs(s, t, index+1, cur + s.charAt(index)) + dfs(s, t, index+1, cur); 11 } 12 public static void main(String[] args) { 13 String s = "rabbbbbbbbbbbbiiiiiiit"; 14 String t = "rabbit"; 15 System.out.println(numDistinct(s,t)); 16 } 17 }
长串显然超时(此样例用时1437ms)。
2、记忆化搜索(Java)
1 import java.util.HashMap; 2 3 public class Solutions { 4 static class Returntype{ 5 public int index; 6 public String cur; 7 public Returntype(int index, String cur) { 8 this.cur = cur; 9 this.index = index; 10 } 11 } 12 static HashMap<Returntype,Integer> map = new HashMap<>(); 13 public static int numDistinct(String s, String t) { 14 return dfs (s,t,0,""); 15 } 16 public static int dfs(String s, String t, int index, String cur) { 17 if (index == s.length()) { 18 return cur.equals(t) ? 1 : 0; 19 } 20 Returntype yes = new Returntype(index+1,cur + s.charAt(index)); 21 Returntype no = new Returntype(index+1,cur); 22 int yeS = map.containsKey(yes) ? map.get(yes) : dfs(s, t, index+1, cur + s.charAt(index)); 23 int nO = map.containsKey(no) ? map.get(no) : dfs(s, t, index+1, cur); 24 map.put(new Returntype(index,cur),yeS+nO); 25 return yeS + nO; 26 } 27 public static void main(String[] args) { 28 String s = "rabbbbbbbbbbbbiiiiiiit "; 29 String t = "rabbit"; 30 long startTime = System.currentTimeMillis(); 31 System.out.println(numDistinct(s,t)); 32 long endTime = System.currentTimeMillis(); 33 System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); 34 } 35 }
也许是姿势不对,用时居然比暴力递归还要长(递归思路貌似也和其他人不太一样),具体之后再研究,总之仍然超时。(几万ms)
3、二维动态规划(Java)
终于意识到自己递归的麻烦所在(状态不好表示,其中一个维度即curString量级为指数且要将s所有情况枚举),故改用他人思路,分别用i,j表示匹配到s、t的当前位置。
易得出转移方程为 dp[i][j] = s.charAt(i) == t.charAt(j) ? dp[i-1][j-1] + dp[i-1][j] : dp[i-1][j]
1 public static int numDistinct(String s, String t) { 2 int[][] dp = new int[s.length()+1][t.length()+1]; 3 for(int i =0;i<=s.length();i++) dp[i][0] = 1; 4 for(int i = 1;i<=s.length();i++) { 5 for(int j = 1;j<=t.length();j++) { 6 dp[i][j] = s.charAt(i-1) == t.charAt(j-1) ? dp[i-1][j-1] + dp[i-1][j] : dp[i-1][j]; 7 } 8 } 9 return dp[s.length()][t.length()]; 10 }
同样的样例时间为1ms,效率显著提高。
4、一维动态规划(Java)
继续从空间角度进行优化。
1 public static int numDistinct(String s, String t) { 2 int m = s.length(), n = t.length(); 3 int dp[] = new int[n+1]; 4 int pre = 0, tmp; 5 for(int i = 0; i <= m; i++) 6 for(int j = 0; j <= n; j++) 7 { 8 tmp = dp[j]; 9 if(j == 0) dp[j] = 1; 10 else if(i == 0) dp[j] = 0; 11 else if(s.charAt(i-1) == t.charAt(j-1)) dp[j] += pre; 12 pre = tmp; 13 } 14 return dp[n]; 15 }
# Edit : 2020.1.15
原文地址:https://www.cnblogs.com/zzl1209/p/12203729.html
时间: 2024-11-02 15:57:34