Title Description
Difficulty: medium
Given a positive integer n, the nth item of the appearance sequence is output.
"Appearance sequence" is a sequence of integers. Starting from the number 1, each item in the sequence is a description of the previous item.
You can think of it as a sequence of numeric strings defined by recursive formulas:
- countAndSay(1) = "1"
- countAndSay(n) is a description of countAndSay(n-1), which is then converted to another numeric string.
The first five items are as follows:
1. 1 2. 11 3. 21 4. 1211 5. 111221 The first item is the number 1 Describe the former item. This number is 1, that is, "a 1", recorded as "11" Describe the former item. The number is 11, that is, "two 1s", recorded as "21" Describe the previous item. The number is 21, that is, "a 2" + A "1" is recorded as "1211" Describe the previous item. The number is 1211, that is, "a 1" + One 2 + The second "1" is recorded as "111221" To describe a numeric string, first divide the string into a minimum number of groups, each consisting of a continuous maximum of the same characters. Then, for each group, first describe the number of characters, and then describe the characters to form a description group. To convert a description to a numeric string, replace the number of characters in each group with a number, and then connect all description groups.
For example, the digital string "3322251" is described as follows:
Example 1:
Input: n = 1 Output:"1" Explanation: This is a basic example.
Example 2:
Input: n = 4 Output:"1211" Explanation: countAndSay(1) = "1" countAndSay(2) = read "1" = One 1 = "11" countAndSay(3) = read "11" = Two 1 = "21" countAndSay(4) = read "21" = One 2 + One 1 = "12" + "11" = "1211"
Tips:
1 <= n <= 30
Problem solving analysis
First, read the question to see that countAndSay(n) is the description of countAndSay(n-1), which is in line with the idea of dynamic programming. It can be defined that the state dp[n] is the description of dp[n-1], and the initial value dp[1] = 1;
The state transition equation is DP [n] = description (DP [n-1]); (Description: noun, description)
So how to describe a numeric string according to the topic logic? Here you need to use double pointer + iteration.
Assuming that there is a numeric string 33 222 55 1, we define two pointers i and j of type int;
i is responsible for recording the initial element subscript of each group of elements, such as 33, 0222 and 2;
j is responsible for running forward. If an element equal to i is encountered, it will continue to run forward. If an element equal to i is encountered, it means that a group has been run. At this time, it is necessary to describe the group just run, and switch i to the beginning of the next group of elements, that is, let i equal j at this time;
How to describe it? After running a group, you will find that J - i at this time is the number of elements with subscript i. for example, in the group of 33, i records subscript 0. When J runs to 2, the elements represented by i and j are not equal, so the number of elements with subscript i is j - i = 2;
For another example, in the 222 group, i records subscript 2. When J runs to 5, the elements represented by i and j are not equal, so the number of occurrences of elements with subscript i is j - i = 3;
After running a group, let i = j to point i to the beginning element of the next group.
Since we only use dp[n] and dp[n-1] in the whole process, we can use the rolling array to optimize the length of dp String[] dp = new String[2];
Problem solving code
public String countAndSay(int n) { String[] dp = new String[2]; // Define status dp[1] = "1"; // boundary for (int i = 2 ; i <= n ; i++){ // dp[i] description dp[i-1] dp[i & 1] = description(dp[(i - 1) & 1]); // & 1 == % 2 } return (n & 1) == 1 ? dp[1] : dp[0]; } // Description numeric string public String description(String temp){ StringBuilder builder = new StringBuilder(); int i = 0 , j = 0; // Double pointer run string char a = temp.charAt(0); // Initializes the character where i is located char b = '0'; // Initialize the character where j is located while (j < temp.length()){ // Using build to describe temp b = temp.charAt(j); if(a == b){ // j encountered an unequal number of additions and characters in the previous run. Switch i to j's position, a to b, representing the beginning of a new group j++; }else { builder.append(j - i).append(a); // Describe the group you ran i = j++; // Complete group switching a = b; } } builder.append(j - i).append(a); // j will cross the boundary, and the last group cannot be described, so the last group is processed separately return builder.toString(); }
summary
This method is very efficient. If it is understandable, it is still relatively easy. If it is difficult to understand, it can be completed by typing a table, that is, list all the possibilities, and then directly look up the table. For details, you can go to the leetcode official solution of this problem;
Years are long, and decay only affects the skin; If enthusiasm is abandoned, decadence will lead to soul