看和说序列
在 Look-and-say(或 Count and Say)序列中找到第 n 项。 Look-and-say 序列是以下整数的序列:
1、11、21、1211、111221、312211、13112221、1113213211、……
上面的序列是如何产生的?
通过读取第 (n-1) 项生成的第 n 项。
The first term is "1"
Second term is "11", generated by reading first term as "One 1"
(There is one 1 in previous term)
Third term is "21", generated by reading second term as "Two 1"
Fourth term is "1211", generated by reading third term as "One 2 One 1"
and so on
如何找到第n个术语?
例子:
Input: n = 3
Output: 21
Input: n = 5
Output: 111221
这个想法很简单,我们生成从 1 到 n 的所有项。前两个术语被初始化为“1”和“11”,所有其他术语都是使用前面的术语生成的。为了使用前一个词生成一个词,我们扫描前一个词。在扫描一个词时,我们只需跟踪所有连续字符的计数。对于相同字符的序列,我们在字符后面附加计数以生成下一个术语。
下面是上述想法的实现。
C++
// C++ program to find n'th term in look and say
// sequence
#include
using namespace std;
// Returns n'th term in look-and-say sequence
string countnndSay(int n)
{
// Base cases
if (n == 1) return "1";
if (n == 2) return "11";
// Find n'th term by generating all terms from 3 to
// n-1. Every term is generated using previous term
string str = "11"; // Initialize previous term
for (int i = 3; i<=n; i++)
{
// In below for loop, previous character
// is processed in current iteration. That
// is why a dummy character is added to make
// sure that loop runs one extra iteration.
str += '$';
int len = str.length();
int cnt = 1; // Initialize count of matching chars
string tmp = ""; // Initialize i'th term in series
// Process previous term to find the next term
for (int j = 1; j < len; j++)
{
// If current character does't match
if (str[j] != str[j-1])
{
// Append count of str[j-1] to temp
tmp += cnt + '0';
// Append str[j-1]
tmp += str[j-1];
// Reset count
cnt = 1;
}
// If matches, then increment count of matching
// characters
else cnt++;
}
// Update str
str = tmp;
}
return str;
}
// Driver program
int main()
{
int N = 3;
cout << countnndSay(N) << endl;
return 0;
}
Java
// Java program to find n'th
// term in look and say sequence
class GFG
{
// Returns n'th term in
// look-and-say sequence
static String countnndSay(int n)
{
// Base cases
if (n == 1) return "1";
if (n == 2) return "11";
// Find n'th term by generating
// all terms from 3 to n-1.
// Every term is generated
// using previous term
// Initialize previous term
String str = "11";
for (int i = 3; i <= n; i++)
{
// In below for loop, previous
// character is processed in
// current iteration. That is
// why a dummy character is
// added to make sure that loop
// runs one extra iteration.
str += '$';
int len = str.length();
int cnt = 1; // Initialize count
// of matching chars
String tmp = ""; // Initialize i'th
// term in series
char []arr = str.toCharArray();
// Process previous term
// to find the next term
for (int j = 1; j < len; j++)
{
// If current character
// does't match
if (arr[j] != arr[j - 1])
{
// Append count of
// str[j-1] to temp
tmp += cnt + 0;
// Append str[j-1]
tmp += arr[j - 1];
// Reset count
cnt = 1;
}
// If matches, then increment
// count of matching characters
else cnt++;
}
// Update str
str = tmp;
}
return str;
}
// Driver Code
public static void main(String[] args)
{
int N = 3;
System.out.println(countnndSay(N));
}
}
// This code is contributed
// by ChitraNayal
C#
// C# program to find n'th
// term in look and say sequence
using System;
class GFG
{
// Returns n'th term in
// look-and-say sequence
static string countnndSay(int n)
{
// Base cases
if (n == 1) return "1";
if (n == 2) return "11";
// Find n'th term by generating
// all terms from 3 to n-1.
// Every term is generated using
// previous term
// Initialize previous term
string str = "11";
for (int i = 3; i <= n; i++)
{
// In below for loop, previous
// character is processed in
// current iteration. That is
// why a dummy character is
// added to make sure that loop
// runs one extra iteration.
str += '$';
int len = str.Length;
int cnt = 1; // Initialize count of
// matching chars
string tmp = ""; // Initialize i'th
// term in series
char []arr = str.ToCharArray();
// Process previous term
// to find the next term
for (int j = 1; j < len; j++)
{
// If current character
// does't match
if (arr[j] != arr[j - 1])
{
// Append count of
// str[j-1] to temp
tmp += cnt + 0;
// Append str[j-1]
tmp += arr[j - 1];
// Reset count
cnt = 1;
}
// If matches, then increment
// count of matching characters
else cnt++;
}
// Update str
str = tmp;
}
return str;
}
// Driver Code
public static void Main()
{
int N = 3;
Console.Write(countnndSay(N));
}
}
// This code is contributed
// by ChitraNayal
Python3
# Python 3 program to find
# n'th term in look and
# say sequence
# Returns n'th term in
# look-and-say sequence
def countnndSay(n):
# Base cases
if (n == 1):
return "1"
if (n == 2):
return "11"
# Find n'th term by generating
# all terms from 3 to n-1.
# Every term is generated using
# previous term
# Initialize previous term
s = "11"
for i in range(3, n + 1):
# In below for loop,
# previous character is
# processed in current
# iteration. That is why
# a dummy character is
# added to make sure that
# loop runs one extra iteration.
s += '$'
l = len(s)
cnt = 1 # Initialize count
# of matching chars
tmp = "" # Initialize i'th
# term in series
# Process previous term to
# find the next term
for j in range(1 , l):
# If current character
# does't match
if (s[j] != s[j - 1]):
# Append count of
# str[j-1] to temp
tmp += str(cnt + 0)
# Append str[j-1]
tmp += s[j - 1]
# Reset count
cnt = 1
# If matches, then increment
# count of matching characters
else:
cnt += 1
# Update str
s = tmp
return s;
# Driver Code
N = 3
print(countnndSay(N))
# This code is contributed
# by ChitraNayal
PHP
Javascript
C++
#include
using namespace std;
// generator function returns int string from prev int
// string e.g. -> it will return '1211' for '21' ( One 2's
// and One 1)
string generator(string str)
{
string ans = "";
unordered_map
tempCount; // It is used to count integer sequence
for (int i = 0; i < str.length() + 1; i++) {
// when current char is different from prev one we
// clear the map and update the ans
if (tempCount.find(str[i]) == tempCount.end()
&& i > 0) {
auto prev = tempCount.find(str[i - 1]);
ans += to_string(prev->second) + prev->first;
tempCount.clear();
}
// when current char is same as prev one we increase
// it's count value
tempCount[str[i]]++;
}
return ans;
}
string countnndSay(int n)
{
string res = "1"; // res variable keep tracks of string
// from 1 to n-1
// For loop iterates for n-1 time and generate strings
// in sequence "1" -> "11" -> "21" -> "1211"
for (int i = 1; i < n; i++) {
res = generator(res);
}
return res;
}
int main()
{
int N = 3;
cout << countnndSay(N) << endl;
return 0;
}
Javascript
输出
21
另一种方法(使用 STL):还有一个想法,我们可以使用 c++ stl 中的 unordered_map 来跟踪位数。基本思想是使用生成器函数,该函数将从前一个字符串。在 count 和 say函数中,我们将遍历从 1 到 n-1 的整数并不断更新我们的结果。
C++
#include
using namespace std;
// generator function returns int string from prev int
// string e.g. -> it will return '1211' for '21' ( One 2's
// and One 1)
string generator(string str)
{
string ans = "";
unordered_map
tempCount; // It is used to count integer sequence
for (int i = 0; i < str.length() + 1; i++) {
// when current char is different from prev one we
// clear the map and update the ans
if (tempCount.find(str[i]) == tempCount.end()
&& i > 0) {
auto prev = tempCount.find(str[i - 1]);
ans += to_string(prev->second) + prev->first;
tempCount.clear();
}
// when current char is same as prev one we increase
// it's count value
tempCount[str[i]]++;
}
return ans;
}
string countnndSay(int n)
{
string res = "1"; // res variable keep tracks of string
// from 1 to n-1
// For loop iterates for n-1 time and generate strings
// in sequence "1" -> "11" -> "21" -> "1211"
for (int i = 1; i < n; i++) {
res = generator(res);
}
return res;
}
int main()
{
int N = 3;
cout << countnndSay(N) << endl;
return 0;
}
Javascript
输出
21