943. Find the Shortest Superstring

目录

  • 题目描述
  • 暴力搜索分析
  • 暴力搜索优化
  • 动态规划
  • 参考链接

题目描述

输入:字符串数组String[] A
输出:一个字符串result,A中每一个字符串是result的子串,并且reuslt是符合这个条件的最短的字符串。
举例:
输入: [“alex”,“loves”,“leetcode”]
输出: “alexlovesleetcode”

输入: [“catg”,“ctaagt”,“gcta”,“ttca”,“atgcatc”]
输出: “gctaagttcatgcatc”

暴力搜索分析

分析:result中包含所有A中的字符串,那把A中字符串一次拼接起来肯定满足这个条件。A= [“catg”,“ctaagt”,“gcta”],那么"catgctaagtgcta"符合条件。当然这三个字符串的任意一个排列得到的字符串都符合。

分析条件2:要求result是最短的。例如A[0]A[1]拼接在一起,如果A[1]的前缀是A[0]的后缀,那么它们可以共用这部分字符串,result的长度就会降低。"gcta"和"ctaagt"拼接的时候,“cta”就是公共部分,拼接之后可以是“gctaagt”。

根据这些分析我们写一个暴力搜索的版本(套用排列的代码模板)。

class Solution {private String result = null;private String[] A;public String shortestSuperstring(String[] A) {result = null;this.A = A;boolean[] visited = new boolean[A.length];dfs(A.length,visited,new ArrayList<Integer>());return result;}/*** dfs递归调用* @param m*          还需要取几个元素* @param visited*           哪些元素已经被取了,不能再取* @param path*          按顺序访问的元素下标*/private void dfs(int m,boolean[] visited, ArrayList<Integer> path) {if(m == 0){//注意结果需要完全拷贝String str = contanctString(path);if(result == null || result.length() > str.length()){result = str;}return;}for(int i =0;i<A.length;i++){if(visited[i]==false){visited[i] = true;path.add(i);dfs(m-1,visited,path);path.remove(path.size()-1);visited[i] = false;}}}/***把路径中的字符串拼接起来*/private String contanctString(List<Integer> path){String str = A[path.get(0)];for(int i = 1; i< path.size();i++){str = contanctTwoString(str, A[path.get(i)]);}return str;}/***拼接两个字符串*/private String contanctTwoString(String str1 , String str2){int m = Math.min(str1.length(),str2.length());for(int i = m; i>0;i--){if(str1.endsWith(str2.substring(0,i))){return str1+str2.substring(i);}}return str1+str2;}}

时间复杂度O(n!)。
A的长度范围是[1,12]。这个时间复杂度是不能通过的(花花酱视频中的说明)。12!约等于4亿多。可以考虑剪枝策略和缓存策略。

暴力搜索优化

从递归树中我们可以看到相同位置的字符串拼接会有多次操作。例如路径[1,2,3]、[2,3,1]这两个,A[2]和A[3]就要拼接两次。是不是能提前计算出两两字符串拼接后的字符串,可以少一次。
我们要找的是长度最短的字符串,如果能提前把两两字符串拼接后的字符串的长度记录下来,在dfs过程中发现当前长度大于result(上一个最有结果)的长度就可以停止递归。这样我们需要计算一个数组cost[i][j],表示A[j]拼接在A[i]后面需要增加的长度。
例如 A= [“catg”,“ctaagt”,“gcta”], cost[0][0]=0。cost[0][2]=3,因为合并后的字符串catgcta,需要增加cta三个字符串。
代码链接。

动态规划

我们的目标是要将A中每一个字符串添加到result中。在实际操作过程中,每次添加一个字符串,并且前面的字符串怎么添加不影响后续字符串添加。可以使用动态规划。
定义int s 表示访问了哪些节点。例如s=3,表示访问了A[0],A[1]。对于A= [“catg”,“ctaagt”,“gcta”],s最大值等于7。

定义数组dp[s][i] = 经过路径s,到达i状态,并且是以i结尾,并且每个节点只访问一次的最短字符串长度。目标状态是dp[7][i],从dp[7][0]、dp[7][1]、dp[7][2]中选择最小值作为结果。

这里动态方程,不太好表示。可以使用从下向上的方式。
dp[7][0] = min(dp[6][2] + cost[2][0]
, dp[6][1] + cost[1][0]
, dp[5][0] + cost[0][1]
…)
dp[mask ^ (1<<j)][j] = min{dp[mask][i] + cost[i][j]}

初始化,添加每个单个的字符串到结果中。dp[0][0] = A[0].length(),dp[1][1]=A[1].length(),dp[4][2]=A[2].length()

时间复杂度(2^n)。时间复杂度降低很多。这个代码有很多难点。即使会了递归方程,要想实现出来还是有难度的。
难点1,用int 表示数组中每一位是否被选择 。
难点2,动态规划从s=1开始,逐步递增。
难点3,如果题目求最短字符串的长度的话,只要使用一维数组dp[]即可,这里还要请求输出字符串,所以需要记录下走不通路径到达i状态的长度。
难点4,记录路径需要用到parent数组。

class Solution {public String shortestSuperstring(String[] A) {int n = A.length;int[][] cost = new int[n][n];for(int i=0;i<n;i++){for(int j = 0; j<n;j++){cost[i][j] = minLength(A[i], A[j]);}}int[][] dp = new int[1<<n][n];int[][] parent = new int[1<<n][n];for(int s = 0; s < (1<<n); s++){Arrays.fill(dp[s],10000);Arrays.fill(parent[s],-1);}for(int i=0;i<n;i++){dp[1<<i][i] = A[i].length();}for(int s = 1; s < (1<<n); s++){            for(int j = 0;j<n;j++){//end pointif ((s & (1 << j)) ==0) continue;int pre = s - (1<<j);for(int i =0;i<n;i++){if(dp[pre][i] + cost[i][j] < dp[s][j]){dp[s][j] = dp[pre][i] + cost[i][j];parent[s][j] = i;}}}}int mask = (1<<n)-1;int minCost = dp[mask][0];int endIndex = 0;for(int j =1;j<n;j++){if(dp[mask][j] < minCost){minCost = dp[mask][j] ;endIndex = j;}}String result = "";int cur = endIndex;int s = (1<<n)-1;while(s > 0){int p = parent[s][cur];if(p<0){result = A[cur] + result;break;}else{result = A[cur].substring(A[cur].length()-cost[p][cur]) + result;}s &= ~(1 << cur);cur = p;}return result;}private int minLength(String str1, String str2){int m = Math.min(str1.length(),str2.length());for(int i = m; i>0;i--){if(str1.endsWith(str2.substring(0,i))){return  str2.length()-i;}}return str2.length();}}

参考链接

花花酱,
leetcode

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

install-info - 更新 info/dir 项

SYNOPSIS 总览 install-info [OPTION]... [INFO-FILE [DIR-FILE]] DESCRIPTION 描述 从 Info 目录文件 DIR-FILE 中的文件 INFO-FILE 中安装或删除 dir 目录项。 OPTIONS 选项 --delete删除 DIR-FILE 中的 INFO-FILE 里已有的项&#xff1b;不插入任何新项。--dir-fileNAME指定…

spring学习(47):bean的作用域

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

visual studio 2017 显示行号

1.Tools中选择Options...&#xff0c; Options界面中Test Editor -> All Languages&#xff08;当然也可以设置对应的语言&#xff09; -> General&#xff0c; 在Settings中勾选 Line numbers。 2.行号就显示出来了&#xff0c;便于我们去定位代码。 转载于:https://www…

spring学习(48):自动装配中定义的bean的作用域

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

212. Word Search II:多个单词查找

写在前面&#xff1a;这两周持续看花花酱整理的题目列表和视频讲解&#xff0c;也得益于自己持续多年刷题&#xff0c;今天刷这道题目的想法是&#xff1a;会trie树居然就能攻克hard题目&#xff01;我也离独立攻破hard题目不远了嘛。前段时间看王争在极客时间的系列课程&#…

CNN(卷积神经网络)、RNN(循环神经网络)、DNN(深度神经网络)的内部网络结构区别...

神经网络技术起源于上世纪五、六十年代&#xff0c;当时叫感知机&#xff08;perceptron&#xff09;&#xff0c;拥有输入层、输出层和一个隐含层。输入的特征向量通过隐含层变换达到输出层&#xff0c;在输出层得到分类结果。早期感知机的推动者是Rosenblatt。&#xff08;扯…

在mybatis中调oracle dblink存储过程

写在前面&#xff1a;在mybatis中操作oracle的数据&#xff0c;不复杂&#xff0c;也不困难。只是第一次用&#xff0c;入了很多坑&#xff0c;记录一下。在此之前需要一些简单的配置&#xff0c;此前一篇博客已经做了简单叙述&#xff1a; https://www.cnblogs.com/studentc/p…

spring学习(49):javaconfig里面定义bean的作用域

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

675. Cut Off Trees for Golf Event

这道题目最大的难点是理解题意。 文章目录题目理解题目理解 输入&#xff1a;一个非负的二维数组 输出&#xff1a;一个最短距离 规则&#xff1a;数组中的元素如果是0&#xff0c;表示障碍&#xff0c;不能通过。如果是1&#xff0c;表示可以行走的地面。如果大于1表示树的高…

spring学习(50):延迟加载

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

ansible的错误

错误 [rootbogon ansible]# ansible test -m ping 192.168.16.155 | FAILED! > { "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this hosts finger…

spring学习(51):对象的初始化和销毁

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

282. Expression Add Operators

目录题目理解分析第一步&#xff1a;dfs获得所有表达式第二步&#xff1a;计算结果先计算加减法计算乘法时间复杂度进一步优化题目理解 输入&#xff1a;一个字符串num&#xff0c;一个int target。输入num只包含数字。 规则&#xff1a;可以给num中包含的数字之间任务添加二目…

ubuntu下的对拍

开始用ubuntu祭blog 转载于:https://www.cnblogs.com/123789456ye/p/11094192.html

spring学习(52):工厂方法创建bean对象

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

花花酱leetcode 题目——搜索专题

在刷完极客时间的算法题目之后&#xff0c;偶然看到了花花酱关于leetcode进入千题时代的一些刷题看法。决定跟着他的思路继续刷题。 要刷多少题 1 每个类型 10-20 如何刷题 1 同类型题目一起刷 2 看代码很重要&#xff0c;看至少3-5种不同实现 3 第一遍&#xff1a;5分钟想…

P2058 海港

P2058 海港 题解 这道题就是给出你n艘船&#xff0c;让你看看以当前船停靠时间为截止时间&#xff0c;24h以内乘客来自多少不同的国家 一开始会想到来一艘船就记录下本船的到达时间&#xff0c;到达人数&#xff0c;以及乘客的国籍 但是你会发现这很占空间 而且船只进来的顺序都…

spring mvc学习(1):spring jar包

spring.jar是包含有完整发布的单个jar 包&#xff0c;spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容&#xff0c;因为只有在开发环境下才会用到 spring-mock.jar来进行辅助测试&#xff0c;正式应用系统中是用不得这些类的。 除了spring.jar文件&a…

花花酱leetcode 题目-二分搜索

原链接 IDNamedifficultysimilar Problemscomments35Search Insert Position234 94 781upper_bound33Search in Rotated Sorted Array381 153 154 162rotated/peak69Sqrt(x)

com.alibaba.fastjson.JSONObject cannot be cast to XXX异常解决

项目开发中遇到过几次这个问题&#xff0c;所以记录一下&#xff0c;代码如下&#xff1a; 1 PostMapping("/save-files") 2 public void addFiles(RequestBody List<AddFileRecordRequestDto> fileRecords) 3 { 4 LoginInfo loginInfosession…