出题:求数组中最长递增子序列的长度(递增子序列的元素可以不相连);

分析:

  • 解法1:应用DP之前需要确定当前问题是否具有无后效性,也就是每个状态都是对之前状态的一个总结,之后的状态仅会受到前一个状态的影响;对于递增子序列 而言,可以首先确定前面k个元素的最长子序列,然后计算增加一个元素之后的最长子序列。由于每个位置i都会与0-i的每个位置之前的LIS进行比较,并选 择保持递增的一个序列,所以总能找到LIS,但是时间复杂度为O(N^2),空间复杂度为O(N);
  • 此解法的性能的瓶颈在于对于位置为i+1的元素,都会遍历0到i内的每一个元素,比较元素本身,以及其位置上的record值;但问题的核心是找到一个最长的LIS,并且其序列中最后一个元素的值比array[i+1]小就可以;

解题:

 int version1(int *array, int length) {
/**
* record记录每个元素位置之前的LIS数
* */
int *record=new int[length];
for(int i=;i<length;i++) {
/**
* 将当前元素的LIS初始化为1
* */
record[i]=;
for(int j=;j<i;j++) {
/**
* 遍历元素i之前的所有元素j,判断j与i是否组成递增序列
* 如果是,则比较对应的record[j]是否比record[i]大1
* 如果是,则更新record[i]的值为record[j]+1
* 这样的策略则总能保证,record[i]的值是0到i区间最大
* 的LIS
* */
if(array[i]>array[j] && record[j]+>record[i]) {
record[i]=record[j]+;
}
}
} /**
* 从record中找出最大的LIS
* */
int max=record[];
for(int i=;i<length;i++) {
if(max<record[i])
max=record[i];
} return max;
} int main() {
int array[]={,-,,-,,-,,-,-};
printf("%d\n",version1(array, ));
return ;
}

出题:给定两个字符串S1和S2,要求判定S2是否可以通过S1做循环移位(rotate)得到的新字符串包含。(S1=AABCD和S2=CDAA,就是包含;S1=ABCD和S2=ACBD,不包含);

分析:

  • S2是移位之后的字符串,则S2的第一个字符对应到S1中的字符位置之前的字符肯定已经被rotate到后面;可以首先从S1中查找S2,如果某个字符不 相同,则跳到下一个可能的查找位置;如果S1到达末尾,则rotate前面的字符,继续对比;如果S2到达末尾,则说明包含;如果rotate之后对比的 字符不同,则不包含。此方法时间复杂度为O(MN);
  • 另外一个解法为将S1转变为SS1=AABCDAABCD,这样子在SS1上寻找S2,时间复杂度仍旧为O(MN),其实与上述方法策略相同;

解题:

 /**
* 翻转字符串,注意length为字符串长度,
* 而不是字符索引
* */
void Reverse(char *s, int length) {
char temp;
for(int i=;i<length/;i++) {
temp=s[i];
s[i]=s[length-i-];
s[length-i-]=temp;
}
}
/**
* 下面的方法实现以s2为分界的旋转,比如
* 字符串abcdef,s1指向a,s2指向d
* 则经过方法处理之后为defabc
* */
void HalfReverse(char *s1, char *s2) {
char *t=s1;
char length=, halflength=;
while(*t!='\0') {
if(*t==*s2)
halflength=length;
length++;
t++;
}
Reverse(s1,halflength);
Reverse(s2,length-halflength);
Reverse(s1,length);
};
/**
* 将s1作为循环主体,每一个字符作为比较的开始字符;
* s2平行在s1上移动比较
* s1仅可以进行一次旋转
* */
bool RotateContain(char *s1, char *s2, bool isRotate) {
char *s1t=s1, *s2t=s2; while(*s1t) {
char *s1tt=s1t;
char *s2tt=s2t; while(*s1tt!='\0' && *s2tt!='\0') {
if(*s1tt!=*s2tt)
break;
s1tt++;s2tt++;
}
/**
* 当s2到达末尾,表示成功匹配,返回true
* */
if(*s2tt=='\0')
return true;
/**
* 当s1到达末尾,有两种情况
* 如果isRotate为false,则可以进行一次旋转
* 如果isRotate为true,说明已经进行了一次旋转
* */
if(*s1tt=='\0') {
if(isRotate)
return false;
else {
isRotate=true;
HalfReverse(s1, s1t);
return RotateContain(s1,s2,isRotate);
}
}
s1t++;
}
return false;
} int main() { char s1[]="abcdefg";
char s2[]="defgabc";
bool isRotate=false;
if(RotateContain(s1,s2,isRotate))
printf("true");
else
printf("false");
return ;
}

笔试算法题(35):最长递增子序列 & 判定一个字符串是否可由另一个字符串旋转得到的更多相关文章

  1. Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)

    Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流) Description 问题描述: 给定正整数序列x1,...,xn . (1 ...

  2. 【刷题】LOJ 6005 「网络流 24 题」最长递增子序列

    题目描述 给定正整数序列 \(x_1 \sim x_n\) ,以下递增子序列均为非严格递增. 计算其最长递增子序列的长度 \(s\) . 计算从给定的序列中最多可取出多少个长度为 \(s\) 的递增子 ...

  3. 算法之动态规划(最长递增子序列——LIS)

    最长递增子序列是动态规划中最经典的问题之一,我们从讨论这个问题开始,循序渐进的了解动态规划的相关知识要点. 在一个已知的序列 {a1, a 2,...an}中,取出若干数组成新的序列{ai1, ai ...

  4. 【PowerOJ1741&网络流24题】最长递增子序列问题(最大流)

    题意: 思路: [问题分析] 第一问时LIS,动态规划求解,第二问和第三问用网络最大流解决. [建模方法] 首先动态规划求出F[i],表示以第i位为开头的最长上升序列的长度,求出最长上升序列长度K. ...

  5. [cogs731] [网络流24题#6] 最长递增子序列 [网络流,最大流]

    [转hzwer]第一问是LIS,动态规划求解,第二问和第三问用网络最大流解决.首先动态规划求出F[i],表示以第i位为开头的最长上升序列的长度,求出最长上升序列长度K.1.把序列每位i拆成两个点< ...

  6. 最长公共子序列(LCS)和最长递增子序列(LIS)的求解

    一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...

  7. C++ 求最长递增子序列(动态规划)

    i 0 1 2 3 4 5 6 7 8 a[i] 1 4 7 2 5 8 3 6 9 lis[i] 1 2 3 2 3 4 3 4 5 时间复杂度为n^2的算法: //求最长递增子序列 //2019/ ...

  8. Cogs 731. [网络流24题] 最长递增子序列(最大流)

    [网络流24题] 最长递增子序列 ★★★☆ 输入文件:alis.in 输出文件:alis.out 简单对比 时间限制:1 s 内存限制:128 MB «问题描述: 给定正整数序列x1,-, xn. ( ...

  9. (转载)最长递增子序列 O(NlogN)算法

    原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...

随机推荐

  1. Entity Framework Code First 迁移

    Entity Framework CodeFirst数据迁移 http://www.cnblogs.com/aehyok/p/3325459.html Entity Framework Code Fi ...

  2. ExtJS 4 MVC Viewport和card布局

    http://ext4all.com/post/a-little-bit-strange-navigation 效果图:  app/view/Viewport.js Ext.define('App.v ...

  3. TransposonPSI——转座子分析的入门自学

    最近需要做转座子分析,查找发现可以使用 TransposonPSI 来进行分析.但是登陆官网,该软件 update 时间为 2013 年,但是因为时间紧迫,暂时还没有进行其他方法的调研,所以先选用该软 ...

  4. 洛谷P2254 [NOI2005]瑰丽华尔兹(单调队列)

    传送门 题解 大概就是设$dp[i][x][y]$表示在第$i$个时间段,在$(x,y)$时的最大滑动距离 然后转移是$dp[i][x][y]=max(dp[i-1][x][y],dp[i][x'][ ...

  5. 前端_vue-cli+element-ui+AceEditor+codemirror+electron-vue

    因项目工作需要,目前在研究前端的一些知识.主要想实现一个类似于webstorm,可以实现对本地文件进行增删改查等操作的IDE.下面通过几个专题,循序渐进,对某一些部分进行总结,希望能对你有帮助.(网上 ...

  6. mybatis 批量insert,update报错 The error occurred while setting parameters

    数据脚本执行正常,但是报错,搜索关键信息 The error occurred while setting parameters ,发现了解决帖子: http://blog.csdn.net/jing ...

  7. Errors running builder 'JavaScript Validator'错误处理

    MyEclipse2014编辑代码时,只要保存就会报出如下错误信息: Errors occurred during the build. Errors running builder 'JavaScr ...

  8. 转 PHP in_array() 函数

    实例 在数组中搜索值 "Glenn" ,并输出一些文本: <?php $people = array("Bill", "Steve", ...

  9. UML 顺序图(转载)

    顺序图精确表达用户与系统的复杂交互过程. 顺序图用于描述进出系统的信息流. 顺序图与协作图是同构的,可以互相转换!!! 顺序图:着重体现对象间消息传递的时间顺序.顺序图允许直观的表示出对象的生存期,生 ...

  10. JMeter(十三)进行简单的数据库(mysql)压力测试

    1.点击测试计划,再点击“浏览”,把JDBC驱动添加进来: 注:JDBC驱动一般的位置在java的安装地址下,路径类似于:    \java\jre\lib\ext 文件为:mysql-connect ...