《剑指Offer——把数字翻译成字符串;最长不含重复字符的子字符串》代码

Posted 穿迷彩服的鲨鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指Offer——把数字翻译成字符串;最长不含重复字符的子字符串》代码相关的知识,希望对你有一定的参考价值。


前言

//==================================================================
// 《剑指Offer——把数字翻译成字符串;最长不含重复字符的子字符串》代码
//==================================================================
// 题目:给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成"a",1翻
// 译成"b",……,11翻译成"l",……,25翻译成"z"。一个数字可能有多个翻译。例
// 如12258有5种不同的翻译,它们分别是"bccfi"、“bwfi”、“bczi”、"mcfi"和
// “mzi”。请编程实现一个函数用来计算一个数字有多少种不同的翻译方法。
//==================================================================
// 题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子
// 字符串的长度。假设字符串中只包含从’a’到’z’的字符。
//==================================================================


一、示例

1.把数字翻译成字符串

/*********************************************************************
/*
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,
1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。
一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
*/
***********************************************************************/

2.最长不含重复字符的子字符串

/******************************************************************************
/*
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
*/
*************************************************************************/

二、代码解析

1.新建.cpp文件

代码如下(示例):

//==================================================================
// 《剑指Offer——把数字翻译成字符串;最长不含重复字符的子字符串》代码
//==================================================================
// 题目:给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成"a",1翻
// 译成"b",……,11翻译成"l",……,25翻译成"z"。一个数字可能有多个翻译。例
// 如12258有5种不同的翻译,它们分别是"bccfi"、"bwfi"、"bczi"、"mcfi"和
// "mzi"。请编程实现一个函数用来计算一个数字有多少种不同的翻译方法。
//==================================================================
// 题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子
// 字符串的长度。假设字符串中只包含从'a'到'z'的字符。
//==================================================================


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

/*
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,
1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。
一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
*/

/*法一--------自下而上循环*/
int GetTranslationCount(string numStr)
{
	int len = numStr.length();
	int* counts = new int[len];
	int count = 0;

	for (int i = len - 1; i >= 0; --i)
	{
		count = 0;
		if (i < len - 1)
		{
			count = counts[i + 1];
		}
		else
		{
			count = 1;
		}
		//1 2 2 5 8
		if (i < len - 1)
		{
			int digit1 = numStr[i] - '0';
			int digit2 = numStr[i + 1] - '0';
			int converted = digit1 * 10 + digit2;
			if (converted >= 10 && converted <= 25)
			{
				if (i < len - 2)
				{
					count += counts[i + 2];
				}
				else
				{
					count += 1;
				}
			}
		}

		counts[i] = count;
	}
	//[0,0,0,0,1]-->[0,0,0,1,1]-->[0,0,2,1,1]-->[0,3,2,1,1]-->[5,3,2,1,1]

	count = counts[0];
	delete[] counts;

	return count;
}

int translateNum1(int num)
{
	if (num < 0)
	{
		return 0;
	}

	string numStr = to_string(num);
	return GetTranslationCount(numStr);
}

/*法二--------无脑dp*///12258-->1225-->12+122-->1+1+122-->1+1+1+12-->1+1+1+1+1
int translateNum2(int num)
{
	if (num < 10)
	{
		return 1;
	}
	if (num % 100 > 9 && num % 100 < 26)
	{
		return translateNum2(num / 100) + translateNum2(num / 10);
	}
	else
	{
		return translateNum2(num / 10);
	}
}

/*
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
*/
/*法一----------暴力解法*/
bool hasDuplication(string str, int position[])
{
	for (int i = 0; i < 27; ++i)
	{
		position[i] = -1;
	}

	for (int i = 0; i < str.length(); ++i)
	{
		int indexInPosition;
		if (str[i] == ' ')//考虑空格
		{
			indexInPosition = 26;
		}
		else
		{
			indexInPosition = str[i] - 'a';
		}


		if (position[indexInPosition] >= 0)
		{
			return true;
		}

		position[indexInPosition] = indexInPosition;
	}
	return false;
}

int lengthOfLongestSubstring1(string s)
{
	int longest = 0;
	int* position = new int[27];
	for (int start = 0; start < s.length(); ++start)
	{
		for (int end = start; end < s.length(); ++end)
		{
			int count = end - start + 1;
			string subString = s.substr(start, count);
			if (!hasDuplication(subString, position))
			{
				if (count > longest)
				{
					longest = count;
				}
			}
			else
			{
				break;
			}
		}
	}
	delete[] position;
	return longest;
}

/*法二----------动态规划*/
int lengthOfLongestSubstring2(string s)
{
	int curLength = 0;
	int maxLength = 0;

	int* position = new int[26];
	for (int i = 0; i < 26; ++i)
		position[i] = -1;

	for (int i = 0; i < s.length(); ++i)
	{
		int prevIndex = position[s[i] - 'a'];
		if (prevIndex < 0 || i - prevIndex > curLength)
			++curLength;
		else
		{
			if (curLength > maxLength)
				maxLength = curLength;

			curLength = i - prevIndex;
		}
		position[s[i] - 'a'] = i;
	}

	if (curLength > maxLength)
		maxLength = curLength;

	delete[] position;
	return maxLength;
}

int lengthOfLongestSubstring3(string s)
{
	unordered_map<char, int> StrMap;
	int res = 0, temp = 0;
	for (int j = 0; j < s.length(); ++j)
	{
		int i = StrMap.count(s[j]) ? i = StrMap[s[j]] : -1;

		StrMap[s[j]] = j;
		temp = temp < j - i ? temp + 1 : j - i;
		res = max(res, temp);
	}

	return res;
}

int main()
{
	cout << "把数字翻译成字符串" << endl;
	cout << "法一------->" << translateNum1(12258) << endl << endl;
	cout << "法二------->" << translateNum2(12258) << endl << endl;

	cout << "最长不含重复字符的子字符串" << endl;
	cout << "法一---->暴力解法--->" << lengthOfLongestSubstring1("abcabcbb") << endl << endl;
	cout << "法二---->动态规划--->" << lengthOfLongestSubstring2("abcabcbb") << endl << endl;
	cout << "法三---->动态规划+哈希表--->" << lengthOfLongestSubstring3("abcabcbb") << endl << endl;
	return 0;
}



三,测试

以上是关于《剑指Offer——把数字翻译成字符串;最长不含重复字符的子字符串》代码的主要内容,如果未能解决你的问题,请参考以下文章

算法剑指 Offer 46. 把数字翻译成字符串

剑指offer:把数字翻译成字符串

剑指offer 把数字翻译成字符串

剑指Offer对答如流系列 - 把数字翻译成字符串

剑指offer——48把数字翻译成字符串

剑指Offer面试题46. 把数字翻译成字符串