Algorithm leetcode|68. Left and right alignment of text (rust punches hard)



68. Align text left and right:

Given an array of words wordsand a length maxWidth, reformat the words into maxWidthtext with exactly characters per line, justified left and right.

You should use a "greedy algorithm" to place the given words; that is, put as many words as possible into each line. Pad with spaces if necessary ' 'so that each line has exactly maxWidth characters.

The requirement is to distribute the amount 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 wordscontains at least one word.

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                  "
	]

hint:

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

analyze:

  • Facing this algorithm problem, the second leader fell into deep thought again.
  • First of all, we must carefully understand the meaning of the title.
  • Each line has a maximum width, place as many words as possible within the width range, and the spaces between words are as even as possible, that is, the maximum difference is one space, and the most spaces must be between the words on the left.
  • It is not difficult to understand, but there are many details in the implementation, which is cumbersome and error-prone. You should try to reuse methods or functions.
  • We need a method or function that fills a specified number of spaces between words, which can be split into a method or function that assembles a specified number of spaces into a string, and a method or function that inserts a specified string between words, so that Can be reused in many places.

answer:

rust:

impl Solution {
    
    
    pub fn full_justify(words: Vec<String>, max_width: i32) -> Vec<String> {
    
    
        // blank 返回长度为 n 的由空格组成的字符串
        fn blank(n: usize) -> String {
    
    
            (0..n).map(|_| {
    
    
                ' '
            }).collect()
        }

        // join 返回用 sep 拼接 [left, right) 范围内的 words 组成的字符串
        fn join(words: &Vec<String>, left: usize, right: usize, sep: &str) -> String {
    
    
            let mut str = String::from(words[left].as_str());
            (left + 1..right).for_each(|i| {
    
    
                str.push_str(sep);
                str.push_str(words[i].as_str());
            });
            return str;
        }

        let max_width = max_width as usize;
        let mut ans = Vec::new();
        let (mut right, n) = (0, words.len());
        loop {
    
    
            let left = right; // 当前行的第一个单词在 words 的位置
            let mut sum_len = 0; // 统计这一行单词长度之和
            // 循环确定当前行可以放多少单词,注意单词之间应至少有一个空格
            while right < n && sum_len + words[right].len() + right - left <= max_width {
    
    
                sum_len += words[right].len();
                right += 1;
            }

            // 当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格
            if right == n {
    
    
                let mut row = join(&words, left, n, " ");
                row.push_str(blank(max_width - row.len()).as_str());
                ans.push(row);
                return ans;
            }

            let num_words = right - left;
            let num_spaces = max_width - sum_len;

            // 当前行只有一个单词:该单词左对齐,在行末填充剩余空格
            if num_words == 1 {
    
    
                let mut row = String::from(words[left].as_str());
                row.push_str(blank(num_spaces).as_str());
                ans.push(row);
                continue;
            }

            // 当前行不只一个单词
            let avg_spaces = num_spaces / (num_words - 1);
            let extra_spaces = num_spaces % (num_words - 1);
            let mut row = String::new();
            row.push_str(join(&words, left, left + extra_spaces + 1, blank(avg_spaces + 1).as_str()).as_str()); // 拼接额外加一个空格的单词
            row.push_str(blank(avg_spaces).as_str());
            row.push_str(join(&words, left + extra_spaces + 1, right, blank(avg_spaces).as_str()).as_str()); // 拼接其余单词
            ans.push(row);
        }
    }
}

go:

func fullJustify(words []string, maxWidth int) (ans []string) {
    
    
    blank := func(n int) string {
    
    
		return strings.Repeat(" ", n)
	}

	right, n := 0, len(words)
	for {
    
    
		left := right // 当前行的第一个单词在 words 的位置
		sumLen := 0   // 统计这一行单词长度之和
		// 循环确定当前行可以放多少单词,注意单词之间应至少有一个空格
		for right < n && sumLen+len(words[right])+right-left <= maxWidth {
    
    
			sumLen += len(words[right])
			right++
		}

		// 当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格
		if right == n {
    
    
			s := strings.Join(words[left:], " ")
			ans = append(ans, s+blank(maxWidth-len(s)))
			return
		}

		numWords := right - left
		numSpaces := maxWidth - sumLen

		// 当前行只有一个单词:该单词左对齐,在行末填充剩余空格
		if numWords == 1 {
    
    
			ans = append(ans, words[left]+blank(numSpaces))
			continue
		}

		// 当前行不只一个单词
		avgSpaces := numSpaces / (numWords - 1)
		extraSpaces := numSpaces % (numWords - 1)
		s1 := strings.Join(words[left:left+extraSpaces+1], blank(avgSpaces+1)) // 拼接额外加一个空格的单词
		s2 := strings.Join(words[left+extraSpaces+1:right], blank(avgSpaces))  // 拼接其余单词
		ans = append(ans, s1+blank(avgSpaces)+s2)
	}
}

c++:

class Solution {
    
    
private:
    // blank 返回长度为 n 的由空格组成的字符串
    string blank(int n) {
    
    
        return string(n, ' ');
    }

    // join 返回用 sep 拼接 [left, right) 范围内的 words 组成的字符串
    string join(vector<string> &words, int left, int right, string sep) {
    
    
        string s = words[left];
        for (int i = left + 1; i < right; ++i) {
    
    
            s += sep + words[i];
        }
        return s;
    }
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
    
    
        vector<string> ans;
        int right = 0, n = words.size();
        while (true) {
    
    
            int left = right; // 当前行的第一个单词在 words 的位置
            int sumLen = 0; // 统计这一行单词长度之和
            // 循环确定当前行可以放多少单词,注意单词之间应至少有一个空格
            while (right < n && sumLen + words[right].length() + right - left <= maxWidth) {
    
    
                sumLen += words[right++].length();
            }

            // 当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格
            if (right == n) {
    
    
                string s = join(words, left, n, " ");
                ans.emplace_back(s + blank(maxWidth - s.length()));
                return ans;
            }

            int numWords = right - left;
            int numSpaces = maxWidth - sumLen;

            // 当前行只有一个单词:该单词左对齐,在行末填充剩余空格
            if (numWords == 1) {
    
    
                ans.emplace_back(words[left] + blank(numSpaces));
                continue;
            }

            // 当前行不只一个单词
            int avgSpaces = numSpaces / (numWords - 1);
            int extraSpaces = numSpaces % (numWords - 1);
            string s1 = join(words, left, left + extraSpaces + 1, blank(avgSpaces + 1)); // 拼接额外加一个空格的单词
            string s2 = join(words, left + extraSpaces + 1, right, blank(avgSpaces)); // 拼接其余单词
            ans.emplace_back(s1 + blank(avgSpaces) + s2);
        }
    }
};

python:

class Solution:
    def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
        def blank(n: int) -> str:
            return ' ' * n

        ans = []
        right, n = 0, len(words)
        while True:
            left = right  # 当前行的第一个单词在 words 的位置
            sum_len = 0  # 统计这一行单词长度之和
            # 循环确定当前行可以放多少单词,注意单词之间应至少有一个空格
            while right < n and sum_len + len(words[right]) + right - left <= maxWidth:
                sum_len += len(words[right])
                right += 1

            # 当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格
            if right == n:
                s = " ".join(words[left:])
                ans.append(s + blank(maxWidth - len(s)))
                break

            num_words = right - left
            num_spaces = maxWidth - sum_len

            # 当前行只有一个单词:该单词左对齐,在行末填充空格
            if num_words == 1:
                ans.append(words[left] + blank(num_spaces))
                continue

            # 当前行不只一个单词
            avg_spaces = num_spaces // (num_words - 1)
            extra_spaces = num_spaces % (num_words - 1)
            s1 = blank(avg_spaces + 1).join(words[left:left + extra_spaces + 1])  # 拼接额外加一个空格的单词
            s2 = blank(avg_spaces).join(words[left + extra_spaces + 1:right])  # 拼接其余单词
            ans.append(s1 + blank(avg_spaces) + s2)

        return ans


java:

class Solution {
    
    
    public List<String> fullJustify(String[] words, int maxWidth) {
    
    
        List<String> ans   = new ArrayList<String>();
        int          right = 0, n = words.length;
        while (true) {
    
    
            int left   = right; // 当前行的第一个单词在 words 的位置
            int sumLen = 0; // 统计这一行单词长度之和
            // 循环确定当前行可以放多少单词,注意单词之间应至少有一个空格
            while (right < n && sumLen + words[right].length() + right - left <= maxWidth) {
    
    
                sumLen += words[right++].length();
            }

            // 当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格
            if (right == n) {
    
    
                StringBuilder sb = join(words, left, n, " ");
                sb.append(blank(maxWidth - sb.length()));
                ans.add(sb.toString());
                return ans;
            }

            int numWords  = right - left;
            int numSpaces = maxWidth - sumLen;

            // 当前行只有一个单词:该单词左对齐,在行末填充剩余空格
            if (numWords == 1) {
    
    
                StringBuilder sb = new StringBuilder(words[left]);
                sb.append(blank(numSpaces));
                ans.add(sb.toString());
                continue;
            }

            // 当前行不只一个单词
            int           avgSpaces   = numSpaces / (numWords - 1);
            int           extraSpaces = numSpaces % (numWords - 1);
            StringBuilder sb          = new StringBuilder();
            sb.append(join(words, left, left + extraSpaces + 1, blank(avgSpaces + 1))); // 拼接额外加一个空格的单词
            sb.append(blank(avgSpaces));
            sb.append(join(words, left + extraSpaces + 1, right, blank(avgSpaces))); // 拼接其余单词
            ans.add(sb.toString());
        }
    }

    // blank 返回长度为 n 的由空格组成的字符串
    private StringBuilder blank(int n) {
    
    
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; ++i) {
    
    
            sb.append(' ');
        }
        return sb;
    }

    // join 返回用 sep 拼接 [left, right) 范围内的 words 组成的字符串
    private StringBuilder join(String[] words, int left, int right, CharSequence sep) {
    
    
        StringBuilder sb = new StringBuilder(words[left]);
        for (int i = left + 1; i < right; ++i) {
    
    
            sb.append(sep);
            sb.append(words[i]);
        }
        return sb;
    }
}

Thank you very much for reading this article~
Welcome to [Like][Favorite][Comment] Go three times in a row~It’s
not difficult to give up, but it must be cool~
I hope we all can improve a little every day~
This article is written by the white hat of the second master: https://le-yi.blog.csdn.net/Blog original~


Guess you like

Origin blog.csdn.net/leyi520/article/details/132143428