剑指offer--c++--最长不含重复字符的子字符串

题目:

       找出一个字符序列中一个最长的包含不重复字符的子字符串,比如在字符串“arabcacfr”中,最长的不含重复字符的子字符串是“acfr”,长度为4。

 

题目分析:

       1.首先判断是否是DP问题。两个条件:1.最优子结构;2.重复子问题;本题需要根据前面的不重复子字符串及现在的字符进行一个判断和统计,所以符合上述条件。

       2.写出状态转移方程。这个是本题的难点。分析一下,首先考虑两种情况,就是前面子字符串里面有没有和当前字符相同的字符,如果没有,那很显然状态方程为f(n) = f(n-1)+1;另外一种情况就是遇到相同的字符,在此基础上考虑一下,是不是有要分为两种情况,一种是遇到的前一个重复字符不在当前子字符串里面,那不是很happy,和前面第一种情况一样,不用管它,继续f(n) = f(n-1)+1;另外一种情况就是当前字符的前一个重复字符的位置在当前子字符串之内,那么是不是应该提出那个重复字符及之前的字符,那么f(n) = n - position;这就完成了状态转移方程。

       3.这题的另外一个难点,就是选择数据结构。之前的DP可能只要选择一个一维数组或者二维数组。根据本题的情况,涉及到要统计字符是否重复,那么显然要用到哈希表,计数的话只需用到一个整型变量即可。这里的哈希表不能用来计数,而是要记位置,涉及到状态方程里面的position。

       4.状态转移方程初始化。这里的初始化也很讲究。计数初始化为0即可。哈希表初始化,既然是记录位置的,而且位置是从0开始的,所以建议初始化赋值为-1.

最终编写代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <list>
#include <unordered_map>
#include <cstring>
#include <map>
#include <stdexcept>

using namespace std;

class MyClass
{
public:
	int max_len_str(const string& str)
	{
		if (str.empty())
			return 0;
		int hash_map[256];
		memset(hash_map, -1, 256);

		int count = 0;
		int max;
		for (int i = 0; i < str.size(); i++)
		{
			int position = hash_map[str[i]];
			//如果该字母没有出现过或者在最长子字符串之外,f(n)=f(n-1)+1
			if (position < 0 || (i - position) > count)
			{
				count++;
			}
			else
			{
				if (max < count)
					max = count;
				count = i - position;
			}
			hash_map[str[i]] = i;
		}
		return count;
	}
};



int main()
{
	MyClass my_class;
	string str = "arabcacfrfc";
//	cout << my_class.getTranslationCount(1223425237) << endl;
	int arr[] = { 1, 10, 3, 8, 12, 2, 9, 6, 5, 7, 4, 11, 3, 7, 16, 5 };
	cout << my_class.max_len_str(str) << endl;

	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值