LeetCode - #68 Align text left and right

Get into the habit of writing together! This is the 14th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .

foreword

Our community will successively organize Gu Yi ( Netflix growth hacker, author of "The Way of the iOS Interview", ACE professional fitness coach. )'s Swift algorithm problem solutions into a text version for everyone to learn and read.

We have updated 67 issues of the LeetCode algorithm so far, and we will keep the update time and progress ( released at 9:00 am on Monday, Wednesday, and Friday ). There will be a big improvement.

If you don't accumulate a small step, you can't go a thousand miles; if you don't accumulate a small stream, you can't make a river. The Swift community accompanies you to move forward. If you have suggestions and comments, please leave a message at the end of the article, we will try our best to meet your needs.

Difficulty Level: Difficult

1. Description

Given an array of words wordsand a length maxWidth, rearrange the words to be text with exactly characters maxWidthper , justified left and right.

You should use a " greedy algorithm " to place a given word; that is, put as many words as possible on each line. It can be ' 'padded so that each line has exactly maxWidth characters.

It is required to distribute the number of spaces between words as evenly as possible. If the spaces between words on a line are not evenly distributed, place more spaces on the left than on the right.

The last line of text should be left-aligned with no extra spaces inserted between words.

Notice:

  • A word is a sequence of characters consisting of non-space characters.
  • The length of each word is greater than 0 and less than or equal to maxWidth .
  • The input word array contains wordsat least one word.

2. Example

Example 1

输入: words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16
输出:
[
   "This    is    an",
   "example  of text",
   "justification.  "
]
复制代码

Example 2

输入:words = ["What","must","be","acknowledgment","shall","be"], maxWidth = 16
输出:
[
  "What   must   be",
  "acknowledgment  ",
  "shall be        "
]
解释: 注意最后一行的格式应为 "shall be    " 而不是 "shall     be",
     因为最后一行应为左对齐,而不是左右两端对齐。       
     第二行同样为左对齐,这是因为这行只包含一个单词。
复制代码

Example 3

输入:words = ["Science","is","what","we","understand","well","enough","to","explain","to","a","computer.","Art","is","everything","else","we","do"],maxWidth = 20
输出:
[
  "Science  is  what we",
  "understand      well",
  "enough to explain to",
  "a  computer.  Art is",
  "everything  else  we",
  "do                  "
]
复制代码

Restrictions:

  • 1 <= words.length <= 300
  • 1 <= words[i].length <= 20
  • words[i]Consists of lowercase English letters and symbols
  • 1 <= maxWidth <= 100
  • words[i].length <= maxWidth

3. Answers

class TextJustification {
    func fullJustify(_ words: [String], _ maxWidth: Int) -> [String] {
        var res = [String]()
        var last = 0, currentLineLength = 0
        
        for (i, word) in words.enumerated() {
            if currentLineLength + word.count + (i - last) > maxWidth {
                
                res.append(buildLine(words, last, i - 1, maxWidth, currentLineLength))
                
                last = i
                currentLineLength = 0   
            }
            
            currentLineLength += word.count
        }
        
        res.append(buildLastLine(words, last, words.count - 1, maxWidth))
        
        return res
    }
    
    fileprivate func buildLine(_ words: [String], _ start: Int, _ end: Int, _ maxWidth: Int, _ currentLineLength: Int) -> String {
        var line = ""
        var extraSpaceNum = 0, spaceNum = 0
        
        if end > start {
            extraSpaceNum = (maxWidth - currentLineLength) % (end - start)
            spaceNum = (maxWidth - currentLineLength) / (end - start)
        } else {
            spaceNum = maxWidth - currentLineLength
        }
        
        for i in start...end {
            line.append(words[i])
            
            if start != end && i == end {
                break
            } 
            
            for _ in 0..<spaceNum {
                line.append(" ")
            }
            
            if extraSpaceNum > 0 {
                line.append(" ")
                extraSpaceNum -= 1
            }
        }
        
        return line
    }
    
    fileprivate func buildLastLine(_ words: [String], _ start: Int, _ end: Int, _ maxWidth: Int) -> String {
        var line = ""
        
        for i in start...end {
            line.append(words[i])
            
            if i < end {
                line.append(" ")
            }
        }
        
        while line.count < maxWidth {
            line.append(" ")
        }
        
        return line
    }
}
复制代码
  • Main idea: Iterate over words, keeping track of the index of the first word and the length of the line. Insert spaces with fixed spaces and extra spaces. .
  • Time Complexity: O(n)
  • Space Complexity: O(n)

Repository for the algorithm solution: LeetCode-Swift

Click to go to LeetCode practice

about us

We are jointly maintained by Swift enthusiasts. We will share the technical content centered on Swift combat, SwiftUI, and Swift foundation, and also organize and collect excellent learning materials.

Guess you like

Origin juejin.im/post/7087524356015783950