笔试题81. 腾讯2017暑期实习生笔试题

今天有点累,不如来个刷个题吧,记得参加腾讯在线笔试的时候遇到过一道题,确实比较懵,所以今天就好好的想了想,这个题来自牛客网...

看到这个图的时候相信大家明白了吧,就是这个题,我一直没有思路,今天突然想起来了,所以就准备解决它。其实这个题主要是运用一个算法思路来解决,最长公共子序列。

仔细想一想,将字符串逆序后与原来的字符串求最长公共子序列不就是这个构造回文吗?这应该很好理解吧,下面简单科普一下最长公共子序列:这中序列不是连续的,意思是可以有间隔,去掉那些干扰项以后,两个序列完全相同,而且要求这个子序列最长。

这类问题和之前 leetcode 上机器人跳到最右下角那个题一样,是一种动态规划的题。而且这种问题的当前位置的解受前面位置的解的影响,假设 s1,s2为两个字符串,i表示s1中第i个字符,j表示s2中第j个字符,那么:

再一次说明一下解题思路:输入字符串S,将字符串S逆序,逆序后的字符串为tmp,然后求S与tmp的最长公共子序列,最后用S的长度减去最长公共子序列的长度,就是需要删除的元素的个数。 相信思路大家明白思路了,下面给出代码。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int LongestStrHui(string &s)
{
	string tmp = s;
	//逆序
	reverse(tmp.begin(), tmp.end());
	int len = s.size();

	//初始化二维数组,数组多开辟了一些空间,是为了优化
	vector<vector<int>> V(len + 1, vector<int>(len + 1, 0));

	//根据"公式"开始去找各个位置的公共子序列长度
	for (int i = 0; i < len; ++i)
	{
		for (int j = 0; j < len; ++j)
		{
			if (s[i] == tmp[j])
				V[i + 1][j + 1] = 1 + V[i][j];
			else
				V[i + 1][j + 1] = max(V[i][j + 1], V[i + 1][j]);
		}
	}

	//整个序列的最长公共子序列
	return len - V[len][len];
}

int main()
{
	string s;
	while (cin >> s)
	{
		cout << LongestStrHui(s)<<endl;
	}
	return 0;
}
时间: 2024-08-05 23:48:47

笔试题81. 腾讯2017暑期实习生笔试题的相关文章

乐视2017暑期实习生笔试题(二)

第二题: 传送门 [编程题] 困兽之斗 经过深思熟虑之后,小贱君打算去M国闯一闯,那是一个古老的东方国度,传说有很多高阶魔法师,他想成为一名伟大的魔法师,将来征服星辰大海.经过千辛万苦,小贱君终于来到了M国,不幸的是刚进城门小贱君就被M国的守城士兵困在了一种叫做“困兽之斗”的阵法之中.士兵对小贱君说:“看到漂浮在你身边的宝石了吗?彩虹连接的两颗宝石可以任意交换位置,你需要通过一系列交换后使得宝石组成的字符串的字典序最小.若不能破阵,那还是请回吧!”小贱君观察了一下周围的宝石,只见每颗宝石上标有一

腾讯2017暑期实习生编程题

1.构造回文 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串.如何删除才能使得回文串最长呢? 输出需要删除的字符个数. 输入描述: 输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000. 输出描述: 对于每组数据,输出一个整数,代表最少需要删除的字符个数. 输入例子: abcda google 输出例子: 2 2 代码如下: #include <iostream> #include <string.h> #include

腾讯2017暑期实习生编程题(3题)

第一题:给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串.如何删除才能使得回文串最长呢?输出需要删除的字符个数. 思路:区间DP即可.我一开始想的是统计i~j内可以回文的字符个数,然后ans=len-dp[1][len]; 后来发现没法实现,即使是一个字符也是回文的这种情况也考虑到了也没办法做,因为我的思路是在dp[i][j]和dp[i+1][j-1]上进行,这样没有包括边界,这样做肯定是错的.比方说aab,在考虑外边的a和b时,如果这么转移应该是得到答案是2的,却得到了1(中

腾讯2017暑期实习生编程

传送门 第一题不说了,区间dp 1 #include<cstdio> 2 #include<cstdlib> 3 #include<string> 4 #include<cstring> 5 6 using namespace std; 7 8 #define N 1005 9 10 int dp[N][N]; 11 char s[N]; 12 int le; 13 14 int dfs(int l,int r) 15 { 16 if(dp[l][r] !=

腾讯2017暑期实习生编程题 第一题 构造回文

给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串.如何删除才能使得回文串最长呢? 输出需要删除的字符个数. 输入描述: 输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000. 输出描述: 对于每组数据,输出一个整数,代表最少需要删除的字符个数. 输入例子1: abcda google 输出例子1: 2 2 import java.util.ArrayList; import java.util.LinkedList; import java.uti

腾讯2017暑期实习生编程题 第二题 字符移位

小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间. 你能帮帮小Q吗? 输入描述: 输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000. 输出描述: 对于每组数据,输出移位后的字符串. 输入例子1: AkleBiCeilD 输出例子1: kleieilABCD import java.util.ArrayList; import java.util.LinkedList; import java.util.

趋势科技2014年暑期实习生笔试题

题目: 有81匹赛马,9个赛道可以利用,每匹赛马的速度是恒定的,不计时但记录每场的名次,请问,赛几次可以得到前5名? 解答: 首先把81匹马分为9组,赛九场,然后把每场的第一名拿出来(刚好9匹),赛一场,得到前五名所在的组(后四名的组果断排除).此时可以确定第一名.然后在第一名的组中抽取2-5名(共四匹马),在第二名的组中抽取2-4名(共三匹马),在第三名的组中抽取2-3(共两匹马),在第四名的组中抽取第2名(共一匹马),此时剩下的马匹有(4+3+2+1+4=14匹),取14中的9匹赛一场,得到

诺基亚(Microsoft Devices Group)2014暑期实习生笔试题知识点

总结一下Microsoft Devices Group的软件类笔试题,所有笔试题分两份试卷,逻辑题一份和软件测试题一份,只总结技术题喽~题目全英文,只包含选择题和填空题,选择题居多,分单选和多选,多选题题目会标注出来.总体来说考察的很基础也很细节,难度适中.下面把记得的一些知识点总结一下下: *命名管道的定义. *主机A发送IP数据报给主机B,途中经过了5个路由器.试问在IP数据报的发送过程总共使用几次ARP(6次) *Linux系统下,给一个文件重命名(mv A,B) *考察无符号整型数和有符

腾讯2016年实习生笔试题-蛇形数组-循环枚举遍历

在n*n方阵里填入1,2···,n*n,要求天成蛇形,如n=4时. 10  11  12      1 9   16   13     2 8   15   14     3 7     6    5     4