————2020.1.16————

算法 || 记一次递归到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

————2020.1.16————的相关文章

每日思考(2020/01/16)

题目概览 html和html5有什么区别? 用CSS绘制一个三角形 对this的理解 题目解答 html和html5有什么区别? 文档声明区别:HTML是超文本标记语言,一种纯文本类型的语言.HTML5文档声明(<!DOCTYPE html>)方便书写,精简,有利于程序员快速的阅读和开发. 结构语义区别:html没有体现结构语义化的标签,如:<div id="nav"></div>,html5添加了许多具有语义化的标签,如:<article&g

2020.3.16 Luogu1004方格取数

显然DP 与传纸条类似,拆成两个人 方法尽量变简单,即把A出发,B出发合并成两个A出发,两个A同时走,这样可以避免A取完B再取的无法判断的情况 状态转移方程: 1.\(x == z \; and \;y == d\),\(f[x][y][z][t] = max(f[x - 1][y][z - 1][t], f[x - 1][y][z][t - 1], f[x][y - 1][z - 1][t], f[x][y - 1][z][t - 1]) + a[x][y]\) 2.else,\(f[x][y

Java 对不同类型的数据文件的读写操作整合器[JSON,XML,CSV]-[经过设计模式改造](2020年寒假小目标03)

日期:2020.01.16 博客期:125 星期四 我想说想要构造这样一个通用文件读写器确实不容易,嗯~以后会添加更多的文件类型,先来熟悉一下文件内容样式: 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beangroup> 3 <javabean> 4 <data name='code'>A001</data> 5 <data name='name'>

软路由OpenWrt(LEDE)2020.4.4编译 UnPnP+NAS+多拨+网盘+DNS优化

近期更新:2020.04.24编译-基于OpenWrt R2020.3.19版本. 2020.04.04更新记录: 修正国内域名加速脚本部分缺陷 内置打印机共享,ZeroTier 新增多套主题 SMARTDNS LUCI缺陷修正 UPNP 升级至2.1.20191006 Mount.CIFS升级至6.10 PSW升级 移除了影响docker自动创建防火墙规则的软件包 2020.03.19更新记录: 增加了IPSec 方案,便于苹果.安卓手机连入家庭网络 内核版小版本升级,必备软件缺陷修正 按大家

C++学习 8.2 - 类及类成员

C++学习系列文章均翻译自learncpp.com,一个非常好的C++学习网站,这个网站让我领悟到原来深奥的道理也可以讲的如此浅显易懂, 如果所有的软件都有类似的网站该多好啊,为了加深印象,我决定逐章翻译一下这个网站,哎,我自己都不相信我能做到... C++提供了一些基本的数据类型(例如:char, int, long, float, double, 等等...),这些类型在处理相对简单的问题时通常是可以满足需要的,但是仅仅使用这些类型在解决复杂的问题时就会比较困难.C++的一个常用的特性就是可

REM+SVG Sprite,web app案例

REM+SVG Sprite,构建新时代web app <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewpo

13. 查看数据库对象间的依赖关系

在SQL Server中,(可编程)对象间的引用即依赖关系,有多种方式可以检查,随着版本变更,方式也有所不同. 父子关系的对象,不通过依赖关系来查询,比如: 1. 外键关系 use tempdb GO --drop table tb1,tb2 create table tb1 ( col1 int Primary key, col2 int ) insert into tb1 values (2,2),(3,2),(4,2),(5,2) GO create table tb2 ( col3 in

在SQL Server中查看对象依赖关系

原文 在SQL Server中查看对象依赖关系 Viewing object dependencies in SQL Server Deleting or changing objects may affect other database objects like views or procedures that depends on them and in certain instances, can “break” the depending object. An example can

查看数据库对象的引用关系,查看数据库对象的依赖关系

转自:https://www.cnblogs.com/seusoftware/p/4858115.html 在SQL Server中,(可编程)对象间的引用即依赖关系,有多种方式可以检查,随着版本变更,方式也有所不同. 父子关系的对象,不通过依赖关系来查询,比如: 1. 外键关系 use tempdb GO --drop table tb1,tb2 create table tb1 ( col1 int Primary key, col2 int ) insert into tb1 values