Leetcode 38:报数

题目描述

报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

  1. 1
  2. 11
  3. 21
  4. 1211
  5. 111221

1 被读作 “one 1” (“一个一”) , 即 11。
11 被读作 “two 1s” (“两个一”), 即 21。
21 被读作 “one 2”, “one 1” (“一个二” , “一个一”) , 即 1211。

给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

注意:整数顺序将表示为一个字符串。

示例 1:

输入: 1
输出: “1”
示例 2:

输入: 4
输出: “1211”

我的解法

string countAndSay(int n) {
	string last_count;
	string now_count;
	if (n == 1){ return "1"; }
	if (n == 2){ return "11"; }
	last_count = "11";
	for (int i = 3; i <= n; i++) //第几次报数的循环
	{
		int j = 0;  // 慢指针

		now_count = "";
		while (j < last_count.size() - 1)
		{
			int temp = 1;  // 重复个数
			int k = j + 1;  // 快指针
			while (last_count[j] == last_count[k])
			{
				temp++;
				k++;
			}
			char temp_char[10];
			sprintf_s(temp_char, "%d", temp);
			now_count = now_count + temp_char;
			now_count.push_back(last_count[j]);
			j = k;
		}

		// 处理最后一位
		if (last_count[last_count.size() - 1] != last_count[last_count.size() - 2])
		{
			now_count.push_back('1');
			now_count.push_back(last_count[last_count.size() - 1]);
		}
		last_count = now_count;
	}
	return now_count;
}
  • 思考延伸
  1. sprintf和sprintf_s
    sprintf_s是sprintf的安全版本,指定缓冲区长度来避免sprintf()存在的溢出风险,主要差在sprintf_s第二个参数,可以控制缓冲区大小
  2. strlen(*char) 和sizeof()
    strlen(*char)函数求是字符串的实际长度,它可以用来获取动态实际字符数组的长度,是从开始到遇到第一个“\0”,如果只是定义没有赋予初始值,这个结果是不确定的,它会从数组的首地址开始一直找下去,直到遇到“\0”停止查找。
    sizeof()求所占总空间的字节数,静态的,跟初始状态字符数组的大小有关系,大小等于初始时字符数组的大小或者等于初始时字符数组的大小+1。
  3. C++中char类型可以自动转换成string类型,即你可以用char类型字符串直接给string类型变量赋值。但反过来是不行的。

递归解法

思路:用的递归思想,观察发现每一个结果和前一个结果有关,出口是第一个报数。

string countAndSay1(int n)
{
	if (n == 1){ return "1"; }
	string str_last = countAndSay(n - 1);
	string str_now;
	int count = 1;
	for (int i = 0; i < str_last.size(); i++)
	{
		if (str_last[i] == str_last[i + 1])
		{
			count++;
		}
		else
		{
			str_now += to_string(count) + str_last[i];
			count = 1;
		}
	}
	return str_now;
}
  • 我的疑惑
    对于字符串strlast访问到第strlast.size()个元素不会报数组溢出bug吗?

  • 解答
    字符串实际上是使用 null 字符 ‘\0’ 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。
    因此最后字符串的末尾还是会有一个‘\0’字符,因此不会有溢出的bug,当然再往后访问一个就出错了。

  • 其它收获

  1. 递归思想:程序的下一层输入为上一层的输出,即函数参数为上一次函数运算的返回值
  2. to_string函数:.c++11标准增加了全局函数std::to_string
发布了23 篇原创文章 · 获赞 9 · 访问量 1438

猜你喜欢

转载自blog.csdn.net/IcdKnight/article/details/102565834