栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

左神算法中级班第八课[C++代码]

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

左神算法中级班第八课[C++代码]

左神算法中级班第八课[C++代码]
  • 第三题:纯code递归[百度原题,难]
    • 代码
  • 第四题:最长无重复字符串的长度
    • 代码
  • 第五题:字符转换最小代价
    • 代码
  • 第六题:最小字典序
    • 代码

声明:博客根据左神在毕站的讲课视频整理,代码是根据左神的java代码版本改写为c++版本
代码为自己动手改写,未经应用不能转载

github代码链接:
https://github.com/hjfenghj/zuoshen_middlecalss

第三题:纯code递归[百度原题,难]

递归,把把问题分为小问题

  • 思路
    假设数组Arr=[a,b,c,…,z],然后a为位置1,z为位置26

f(i,len)表示从位置i的字符出发,长度len的字符串的种类数
g(len)表示长度为len的字符串种类数

所以给一个字符串str
首先计算长度小于str.size()的字符串有多少个;
然后根据str的首字符在Arr的位置k1,计算位置k以前的字符为起始,长度为str.size()的字符串个数;
然后根据字符串str的第二个字符位置k2,计算以位置k2以前的字符为起始,长度为str.size()-1的字符个数;依次类推

代码
  • code
#include
#include
#include

using namespace std;

class PROBLEM03
{
public:
	//以idx字符开始,长度为Len的字符串的数量,,idx表示字符在[a,...,Z]中的位置
	int f(int idx, int Len)
	{
		int sum = 0;
		if (Len == 1)
			return 1;

		for (int i = idx+1; i <= 26; i++)
		{
			sum += f(i, Len-1);
		}
		return sum;
	}
	//得到长度为len的字符串有几个
	int g(int len)
	{
		int sum = 0;
		for (int i = 1; i <= 26; i++)
			sum += f(i, len);
		return sum;
	}
	int process(string str)
	{
		int ans = 0;
		int L = str.size();
		for (int i = 1; i < L; i++)
		{
			ans += g(i);
		}

		int first = str[0] - 'a' + 1;
		for (int i = 1; i < first; i++)
			ans += f(i,L);


		int pre = first;
		for (int i = 1; i < L; i++)
		{
			int newL = str[i] - 'a' + 1;
			for (int j = pre + 1; j < newL; j++)
			{
				ans += f(j, L - i);
			}
			pre = newL;
		}
		return ans + 1;
	}
};

int main()
{
	string str = "ab";
	PROBLEM03 P;
	int ans = P.process(str);
	cout << ans << endl;
	return 0;
}
第四题:最长无重复字符串的长度

技巧:动态规划,类似于最长有效括号字符串

  • 思路
    看代码了解思想把,很简单的思路,但是不好描述
代码
  • code
#include
#include
#include
using namespace std;

class PROBLEM03_1
{
public:
	int get_res(string str)
	{
		vector dp(str.size(), 0);
		dp[0] = 1;
		int ans = INT_MIN;
		for (int i = 1; i < str.size(); i++)
		{
			int j = 1;
			bool flag = true;//是否在dp[i-1]的影响范围内,找到Arr[i]
			while (j <= dp[i-1])
			{
				if (str[i - j] == str[i])
				{
					dp[i] = j;
					flag = false;
					break;
				}
				j++;
			}
			if(flag)
				dp[i] = dp[i - 1] + 1;

			ans = max(ans, dp[i]);
		}
		return ans;
	}
};

//pre代表i-1结尾的最长无重复字串的长度,在i位置更新dp[i]的时候
//如果dp[i-1]影响的范围内出现了arr[i].那么dp[i] = i - temp;
//如果dp[i-1]影响的范围内没有出现arr[i],那么dp[i] = i-temp,这时候的temp就是dp[i-1]包含的小区域前的一个,i位置的dp[i]也不能跳过影响
class PROBLEM03_2
{
public:
	int get_res(string str)
	{
		map M; //储存每一个字符上一个出现的位置,所有字符的ascii范围是0-255
		for (int i = 0; i < 256 ; i++)
		{
			M[i] = -1;
		}

		int pre = -1;//i位置往前跳dp[i]步到达的位置
		int cur = 0;//字符上一次出现的位置
		int ans = INT_MIN;
		for (int i = 0; i < str.size(); i++)
		{
			pre = max(pre, M[str[i]]);//距离i位置近的位置,作为新的pre
			ans = max(ans, i - pre);
			M[str[i]] = i;
		}
		return ans;
	}
};

int main()
{
	string str = "abcabcbb";
	PROBLEM03_2 P;
	int ans = P.get_res(str);
	cout << ans << endl;
	return 0;
}
第五题:字符转换最小代价

动态规划,力扣72的变种

代码
  • code
#include
#include
#include

using namespace std;

class PROBLEM05
{
public:
	int ic;
	int dc;
	int rc;
	PROBLEM05(int i, int d, int r)
	{
		ic = i;
		dc = d;
		rc = r;
	}

	int get_res(string str1, string str2)
	{
		int L1 = str1.size();
		int L2 = str2.size();
		vector> dp(L1+1, vector(L2+1, 0));
		dp[0][0] = 0;

		for (int i = 1; i <= L2; i++)
			dp[0][i] = ic * i;
		for (int i = 1; i <= L1; i++)
			dp[i][0] = dc * i;

		for (int i = 1; i <= L1; i++)
		{
			for (int j = 1; j <= L2; j++)
			{
				
				//仿照力扣72题的思路,力扣72是求操作数;
				if (str1[i-1]-str2[j-1] == 0)
					dp[i][j] = min(dp[i - 1][j] + dc, min(dp[i][j - 1] + ic, dp[i - 1][j - 1]));
				else
					dp[i][j] = min(dp[i - 1][j] + dc, min(dp[i][j - 1] + ic, dp[i - 1][j - 1]+rc));
			}
		}
		return dp[L1][L2];
	}
};

int main()
{
	string s1 = "abd";
	string s2 = "add";
	PROBLEM05 P(5,3,2);
	int ans = P.get_res(s1,s2);
	cout << ans << endl;
	return 0;
}
第六题:最小字典序

  • 思路
    1)遍历字符串,记录词频
    2)重新遍历,词频表实时显示剩余没遍历的字符中的词频,当词频表中某字符词频变为零的时候停止遍历,去遍历过的元素中ACSII最小的字符ch,并删除整个数组中的字符ch
    3)重复1和2
代码
#include
#include
#include
#include

using namespace std;

class PROBLEM06
{
public:
	string process(string str)
	{
		if (str.size() == 1)
			return str;

		//统计词频
		map M;
		for (char s : str)
		{
			M[s]++;
		}

		int idx = 0;

		for (int i=0;i
			idx = str[idx] - '0' > str[i] - '0' ? i : idx;//记录经过的字符中acsii最小的字符的位置
			if (--M[str[i]] == 0)
				break;
		}
		string s(1, str[idx]);
		string new_str(str.begin() + idx + 1, str.end());
		new_str.erase(remove(new_str.begin(), new_str.end(), str[idx]), new_str.end());
		return  s + process(new_str);
	}
};

int main()
{
	string str = "dbcacbca";
	PROBLEM06 P;
	string ans = P.process(str);
	cout << ans << endl;
	return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/980338.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号