Skip to content

Latest commit

 

History

History
359 lines (313 loc) · 10.5 KB

File metadata and controls

359 lines (313 loc) · 10.5 KB

English Version

题目描述

给定一个单词数组 words 和一个长度 maxWidth ,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。

你应该使用 “贪心算法” 来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。

要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。

文本的最后一行应为左对齐,且单词之间不插入额外的空格。

注意:

  • 单词是指由非空格字符组成的字符序列。
  • 每个单词的长度大于 0,小于等于 maxWidth
  • 输入单词数组 words 至少包含一个单词。

 

示例 1:

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

示例 2:

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

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

 

提示:

  • 1 <= words.length <= 300
  • 1 <= words[i].length <= 20
  • words[i] 由小写英文字母和符号组成
  • 1 <= maxWidth <= 100
  • words[i].length <= maxWidth

解法

Python3

class Solution:
    def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
        def partition(n, cnt):
            res = []
            base, mod = divmod(n, cnt)
            i = j = 0
            while i < cnt:
                t = [' ' * base]
                if j < mod:
                    t.append(' ')
                res.append(''.join(t))
                i, j = i + 1, j + 1
            return res

        ans = []
        i, n = 0, len(words)
        while i < n:
            t = []
            cnt = len(words[i])
            t.append(words[i])
            i += 1
            while i < n and cnt + 1 + len(words[i]) <= maxWidth:
                cnt += 1 + len(words[i])
                t.append(words[i])
                i += 1
            if i == n or len(t) == 1:
                # this is the last line or only one word in a line
                left = ' '.join(t)
                right = ' ' * (maxWidth - len(left))
                ans.append(left + right)
                if i == n:
                    break
                continue
            words_width = cnt - len(t) + 1
            space_width = maxWidth - words_width
            spaces = partition(space_width, len(t) - 1)
            sb = [t[0]]
            for j in range(len(t) - 1):
                sb.append(spaces[j])
                sb.append(t[j + 1])
            ans.append(''.join(sb))
        return ans

Java

class Solution {
    public List<String> fullJustify(String[] words, int maxWidth) {
        List<String> ans = new ArrayList<>();
        int n = words.length;
        for (int i = 0; i < n;) {
            List<String> t = new ArrayList<>();
            int cnt = words[i].length();
            t.add(words[i++]);
            while (i < n && cnt + 1 + words[i].length() <= maxWidth) {
                cnt += 1 + words[i].length();
                t.add(words[i++]);
            }
            if (i == n || t.size() == 1) {
                // this is the last line or only one word in a line
                String left = String.join(" ", t);
                String right = " ".repeat(maxWidth - left.length());
                ans.add(left + right);
                if (i == n) {
                    break;
                }
                continue;
            }

            int wordsWidth = cnt - t.size() + 1;
            int spaceWidth = maxWidth - wordsWidth;
            List<String> spaces = partition(spaceWidth, t.size() - 1);
            StringBuilder sb = new StringBuilder(t.get(0));
            for (int j = 0; j < t.size() - 1; ++j) {
                sb.append(spaces.get(j));
                sb.append(t.get(j + 1));
            }
            ans.add(sb.toString());
        }
        return ans;
    }

    private List<String> partition(int n, int cnt) {
        List<String> ans = new ArrayList<>();
        int base = n / cnt;
        int mod = n % cnt;
        for (int i = 0, j = 0; i < cnt; ++i, ++j) {
            StringBuilder sb = new StringBuilder(" ".repeat(base));
            if (j < mod) {
                sb.append(' ');
            }
            ans.add(sb.toString());
        }
        return ans;
    }
}

C++

class Solution {
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
        int n = words.size();
        vector<string> result;
        for (int i = 0; i < n; i++) {
            int begin = i;
            int wordLen = words[i].size();
            while (i + 1 < n && words[i + 1].size() + wordLen + 1 <= maxWidth) {
                wordLen += words[++i].size() + 1;
            }
            int numberofWords = i - begin + 1;
            int space = 1;
            int extraSpace = 0;
            if (numberofWords > 1 && i < n - 1) {
                int remaining = maxWidth - wordLen;
                space = remaining / (numberofWords - 1) + 1;
                extraSpace = remaining % (numberofWords - 1);
            }
            string line = words[begin];
            for (int j = 1; j < numberofWords; j++) {
                line.append(space, ' ');
                if (j <= extraSpace) {
                    line.push_back(' ');
                }
                line += words[begin + j];
            }
            if (line.size() < maxWidth) {
                line.append(maxWidth - line.size(), ' ');
            }
            result.emplace_back(line);
        }
        return result;
    }
};

Go

func fullJustify(words []string, maxWidth int) []string {
	partition := func(n, cnt int) []string {
		var res []string
		base, mod := n/cnt, n%cnt
		for i, j := 0, 0; i < cnt; i, j = i+1, j+1 {
			t := strings.Repeat(" ", base)
			if j < mod {
				t += " "
			}
			res = append(res, t)
		}
		return res
	}

	var ans []string
	for i, n := 0, len(words); i < n; {
		t := []string{words[i]}
		cnt := len(words[i])
		i++
		for i < n && cnt+1+len(words[i]) <= maxWidth {
			cnt += 1 + len(words[i])
			t = append(t, words[i])
			i++
		}
		if i == n || len(t) == 1 {
			left := strings.Join(t, " ")
			right := strings.Repeat(" ", maxWidth-len(left))
			ans = append(ans, left+right)
			if i == n {
				break
			}
			continue
		}
		wordsWidth := cnt - len(t) + 1
		spaceWidth := maxWidth - wordsWidth
		spaces := partition(spaceWidth, len(t)-1)
		sb := t[0]
		for j := 0; j < len(t)-1; j++ {
			sb += spaces[j] + t[j+1]
		}
		ans = append(ans, sb)
	}
	return ans
}

C#

using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Solution {
    public IList<string> FullJustify(string[] words, int maxWidth) {
        var result = new List<string>();
        var buffer = new List<string>();
        var sb = new StringBuilder();
        var len = 0;

        for (var i = 0; i < words.Length; ++i)
        {
            var newLen = words[i].Length + (len == 0 ? 0 : len + 1);
            if (newLen <= maxWidth)
            {
                buffer.Add(words[i]);
                len = newLen;
            }
            else
            {
                if (buffer.Count == 1)
                {
                    sb.Append(buffer[0]);
                    sb.Append(' ', maxWidth - buffer[0].Length);
                }
                else
                {
                    var spaceCount = maxWidth - len + buffer.Count - 1;
                    for (var j = 0; j < buffer.Count - 1; ++j)
                    {
                        sb.Append(buffer[j]);
                        var spaceToAdd = (spaceCount - 1) / (buffer.Count - j - 1) + 1;
                        sb.Append(' ', spaceToAdd);
                        spaceCount -= spaceToAdd;
                    }
                    sb.Append(buffer.Last());
                }
                result.Add(sb.ToString());
                buffer.Clear();
                buffer.Add(words[i]);
                sb.Clear();
                len = words[i].Length;
            }
        }

        if (buffer.Count > 0)
        {
            for (var j = 0; j < buffer.Count; ++j)
            {
                if (sb.Length > 0)
                {
                    sb.Append(' ');
                }
                sb.Append(buffer[j]);
            }
            if (sb.Length < maxWidth)
            {
                sb.Append(' ', maxWidth - sb.Length);
            }
            result.Add(sb.ToString());
        }

        return result;
    }
}

...