腾讯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;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值