Leetcode Weekly – 172 – 2

Time:2020-10-12

1324. Print words vertically

Hi, everyone. I’m a pig. Welcome to the weekly leetcode quiz of the “baby can understand” series.

This is the second question in issue 172 and 1324 in the list of questions – “vertically printed words.”

Title Description

Here’s a string for yous。 Please follow the words in thesThe order in which they appear returns them all vertically.
Words should be returned in the form of a list of strings, with space padding if necessary, but the spaces at the end of the output need to be removed (trailing spaces are not allowed).
Each word can only be placed in one column, and there can be only one word in each column.

Example 1:

Input: S = "how are you"
Output: ["hay", "Oro", "WEU"]
Explanation: every word should be printed vertically.
 "HAY"
 "ORO"
 "WEU"

Example 2:

Input: S = to be or not to be "
Output: [tbontb "," oerooe "," t "]
Explanation: space filling is allowed for the title, but no space is allowed at the end of the output.
"TBONTB"
"OEROOE"
"   T"

Example 3:

Input: s: "content is coming"
Output: ["CIC", "oso", "n m", "t I", "e n", "s g", "t"]

Tips:

  • 1 <= s.length <= 200
  • sCapital letters only.
  • The title data ensures that there is only one space between two words.

Official difficulty

MEDIUM

Solutions

The title is given a string containing multiple words, each of which is made up of uppercase letters and must be separated by a space. However, the returned results look strange directly, because it is a string array formed by arranging each word vertically from top to bottom, and then combining the words from left to right. That is to say, in the returned array, the first string is composed of the first letter of each word in the order that the word appears from left to right, the second string is the second letter of each word, and so on.

It is important to note that since the length of each word is different, the returned string may have padding spaces, but the extra suffix spaces are not reserved. This should be the most easily mistaken part of this question. As for the problem of space, you can see the following example in detail

Leetcode Weekly - 172 - 2

So let’s take a look at the ideas. First of all, from the result, we can see from the above example that the required string array can be directly spliced by the first letter, the second letter of each word. The separator of each word in the original string is fixed as a space. So it is very easy to think that we can first split the original string into word groups, and then traverse the splicing.

Direct scheme

After the general formation of ideas, we need to pay attention to the details, that is, the processing of special spaces.

Since the following words may be longer than the preceding words, we may need to splice the space in front of the words. For example, the one in the example aboveP RYou need to add spaces here.

Does that mean that we can fill in the blanks directly? Of course not. Because when there are no longer words, if we go to splice the space, it will become a space suffix. According to the requirements of the title, this type of space needs to be removed. For example, the one in the example aboveY

I believe it’s easy for my partner to think about this problem. I don’t want to do too much analysis here. That is, we can record the possible spaces first, but do not make splicing. In the follow-up, if necessary, it can be spliced in as a place filling space. Based on this idea, the specific process is as follows:

  1. Split the original string into word groups.
  2. Traverse the word group to get the length of the longest word.
  3. According to the longest word length, traverse the corresponding characters in each word:

    • If it is a letter, it is spliced into the result array together with the padding space, and the padding space is reset to an empty string.
    • If empty, the carry space is recorded.
  4. Returns an array of results.

Based on this process, we can implement code like this:

const printVertically = s => {
  const words = s.split(' ');
  let maxLen = 0;
  for (let i = 0; i < words.length; ++i) {
    if (words[i].length > maxLen) maxLen = words[i].length;
  }
  const ret = new Array(maxLen);
  for (let i = 0; i < maxLen; ++i) {
    ret[i] = '';
    let prevSpace = '';
    for (let j = 0; j < words.length; ++j) {
      words[j][i] === undefined
        ? (prevSpace += ' ')
        : ((ret[i] += prevSpace + words[j][i]), (prevSpace = ''));
    }
  }
  return ret;
};

Change your mind

In the above process, we will find that there are many traversal, and we also need to split the original string into word groups. Is there any way to optimize this part?

Looking back at the idea and code just now, our approach is to take the nth character of each word, and then directly form the nth string in the result. If we think of the result array as a two-dimensional array of characters, it is equivalent to that we are splicing the results line by line. So we need to take out each word first and find the length of the longest word. Speaking of this, some partners may think, in addition to the line by line splicing, can we join the column by column?

Let’s take a look. If it is a column by column splicing, then starting from the first column, it is actually the original order of each word, that is, the original order of our original string. If this is the case, there is no need to split word groups, nor to traverse according to the characters of each word. Let’s just go through the original string from scratch. Wonderful duck.

However, we still need to pay attention to the problem of special spaces. Since we traverse the original string directly, we don’t know whether to fill in the blanks in the process. For example, for the example in the previous figure, for the “R” in “year”, we will directly put it together with “P” to get “PR”, instead of “P R”. So how can we solve this problem?

Take a closer look at the example of “R” above. Why do we need “P R” because the word in the middle is empty here. In other words, there are letters in the first word, vacancies in the second word, and letters in the third word. In other words, for the letter in the third word, it expects that there are already two letters in front of it, that is, the length of the string is 2. So when the length of the preceding string is less than 2, we need to fill it with spaces. Speaking of this, I believe that the partners understand it, we only need to according to the current letter belongs to the word, combined with the length of the preceding string, can complete the complement of the place filling space.

Based on this idea, we need to add a variable to record the current traversal to the number of words. The specific process is as follows:

  1. Initializes the current word to 0 and the character in the word to 0.
  2. Traverse the entire original string:

    • If a space is encountered, the number of words is increased by 1 and the characters in the word are reset to 0.
    • If the length of the result array has not reached this bit, fill in the possible padding space and the current character directly.
    • If the length of the preceding string in the result array does not meet the requirements of this character of the current word, the padding space is filled. Then spell the current character.
  3. Returns an array of results.

Based on this process, we can implement code like this:

const printVertically = s => {
  const ret = [];
  for (let i = 0, idx = 0, word = 0; i < s.length; ++i, ++idx) {
    const char = s[i];
    if (char === ' ') { ++word; idx = -1; continue; }
    if (ret[idx] === undefined) { ret[idx] = ' '.repeat(word) + char; continue; }
    ret[idx].length !== word && (ret[idx] += ' '.repeat(word - ret[idx].length));
    ret[idx] += char;
  }
  return ret;
};

This code temporarily beats 100% at 36ms.

summary

This is not a complicated problem, especially the idea of the direct scheme should be obtained according to the requirements of the topic. In the end, however, we found that the direct plan actually went around. These findings come from our observation and Reflection on the corresponding relationship between some examples and results. So sometimes we might as well write some possible results to Kangkang, and then we will find that it is super brave, because the answer is in it. >.

So, do you want to give Kangkang duck to piggy? Pig is super brave, ha ha ha ha.

Related links

  • Weekly contest 172 question list
  • Repo
  • My segment fault column
  • My Zhihu column

Leetcode Weekly - 172 - 2