笔试算法题(35):最长递增子序列 & 判定一个字符串是否可由另一个字符串旋转得到
出题:求数组中最长递增子序列的长度(递增子序列的元素可以不相连);
分析:
- 解法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):最长递增子序列 & 判定一个字符串是否可由另一个字符串旋转得到的更多相关文章
- Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)
Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流) Description 问题描述: 给定正整数序列x1,...,xn . (1 ...
- 【刷题】LOJ 6005 「网络流 24 题」最长递增子序列
题目描述 给定正整数序列 \(x_1 \sim x_n\) ,以下递增子序列均为非严格递增. 计算其最长递增子序列的长度 \(s\) . 计算从给定的序列中最多可取出多少个长度为 \(s\) 的递增子 ...
- 算法之动态规划(最长递增子序列——LIS)
最长递增子序列是动态规划中最经典的问题之一,我们从讨论这个问题开始,循序渐进的了解动态规划的相关知识要点. 在一个已知的序列 {a1, a 2,...an}中,取出若干数组成新的序列{ai1, ai ...
- 【PowerOJ1741&网络流24题】最长递增子序列问题(最大流)
题意: 思路: [问题分析] 第一问时LIS,动态规划求解,第二问和第三问用网络最大流解决. [建模方法] 首先动态规划求出F[i],表示以第i位为开头的最长上升序列的长度,求出最长上升序列长度K. ...
- [cogs731] [网络流24题#6] 最长递增子序列 [网络流,最大流]
[转hzwer]第一问是LIS,动态规划求解,第二问和第三问用网络最大流解决.首先动态规划求出F[i],表示以第i位为开头的最长上升序列的长度,求出最长上升序列长度K.1.把序列每位i拆成两个点< ...
- 最长公共子序列(LCS)和最长递增子序列(LIS)的求解
一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...
- 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/ ...
- Cogs 731. [网络流24题] 最长递增子序列(最大流)
[网络流24题] 最长递增子序列 ★★★☆ 输入文件:alis.in 输出文件:alis.out 简单对比 时间限制:1 s 内存限制:128 MB «问题描述: 给定正整数序列x1,-, xn. ( ...
- (转载)最长递增子序列 O(NlogN)算法
原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...
随机推荐
- Excel学习 -- 函数基础
Excel函数基础 1. 单元格是函数的作用对象: 2. 函数由等号.函数表达式.操作符.参数.返回值五部分组成: 3. 商业智能报表中使用的常用函数分类:数学函数.文本函数.逻辑函数.查 ...
- ARC102 C~D
C: 枚举中间点,计算两边点差值,把个数乘起来即可 #include<iostream> #include<cstdio> #include<algorithm> ...
- influxdb数据库增加身份认证(windows)三
接上一节,增加数据库身份认证 1.修改Config配置文件auth-enabled为true 2.然后重新载入最新的config配置文件打开数据库 3.验证身份认证功能是否已打开 说明身份认证功能已打 ...
- Oracle11.2.0.1升级到11.2.0.3
Oracle数据库升级也并非简单的事,这篇博客,博主对Oracle那点事做了较详细的介绍: http://blog.itpub.net/9599/viewspace-473003/ 我还属于Oracl ...
- 题解报告:hdu 2844 & poj 1742 Coins(多重部分和问题)
Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...
- ACM_数数?诶?这么简单?
数数?诶?这么简单? Time Limit: 2000/1000ms (Java/Others) Problem Description: 当看到GDUFE-GAME宣传海报上提到"场内人员 ...
- 171 Excel Sheet Column Number Excel表列序号 26进制转10进制
给定一个Excel表格中的列名称,返回其相应的列序号.示例: A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -&g ...
- MySQL-时间(time、date、datetime、timestamp和year)
情景进入 情境进入: 今天调试某查询页面,偶尔发现一个问题,刚刚插入的数据,没有正常排序显示,经过后台调试sql,发现一个问题??? 经过上面红色对比,不知道你发现问题没,Order by 只是多一个 ...
- 微信小程序flex布局
一.flex布局基础 二.相对定位和绝对定位 flex的容器和元素 主轴(左-右),交叉轴(上-下) flex容器属性详解 flex-direction 决定元素的排列方向(默认row ...
- CF933A/934C A Twisty Movement
思路: 实际上是求原序列中最长的形如1......2......1......2......的子序列的长度.令dp[i][j](1 <= j <= 4)表示在子序列a[1]至a[i]中形如 ...