《剑指Offer——把数字翻译成字符串;最长不含重复字符的子字符串》代码
Posted 穿迷彩服的鲨鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指Offer——把数字翻译成字符串;最长不含重复字符的子字符串》代码相关的知识,希望对你有一定的参考价值。
46.把数字翻译成字符串;48.最长不含重复字符的子字符串
前言
//==================================================================
// 《剑指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——把数字翻译成字符串;最长不含重复字符的子字符串》代码的主要内容,如果未能解决你的问题,请参考以下文章