Algorithmus leetcode|68. Links- und Rechtsausrichtung des Textes (Rost schlägt hart)



68. Text links und rechts ausrichten:

Formatieren Sie bei gegebenem Wortarray wordsund Länge maxWidthdie Wörter in maxWidthText mit genau den Zeichen pro Zeile, linksbündig und rechtsbündig.

Sie sollten einen „Greedy-Algorithmus“ verwenden, um die angegebenen Wörter zu platzieren, d. h. so viele Wörter wie möglich in jede Zeile einfügen. Füllen Sie bei Bedarf Leerzeichen auf ' ', sodass jede Zeile genau maxWidth- Zeichen enthält.

Die Anforderung besteht darin, die Anzahl der Leerzeichen zwischen den Wörtern möglichst gleichmäßig zu verteilen. Wenn die Leerzeichen zwischen Wörtern in einer Zeile nicht gleichmäßig verteilt sind, platzieren Sie links mehr Leerzeichen als rechts.

Die letzte Textzeile sollte linksbündig ausgerichtet sein, ohne dass zwischen den Wörtern zusätzliche Leerzeichen eingefügt werden dürfen.

Beachten:

  • Ein Wort ist eine Zeichenfolge, die aus Nicht-Leerzeichen besteht.
  • Die Länge jedes Wortes ist größer als 0 und kleiner oder gleich maxWidth .
  • Das Eingabewort-Array wordsenthält mindestens ein Wort.

Beispiel 1:

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

输出:

	[
	  "This    is    an",
	  "example  of text",
	  "justification.  "
	]

Beispiel 2:

输入:
	
	words = ["What","must","be","acknowledgment","shall","be"], maxWidth = 16
	
输出:

	[
	  "What   must   be",
	  "acknowledgment  ",
	  "shall be        "
	]
	
解释: 

	 注意最后一行的格式应为 "shall be    " 而不是 "shall     be",
     因为最后一行应为左对齐,而不是左右两端对齐。       
     第二行同样为左对齐,这是因为这行只包含一个单词。

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

Hinweis:

  • 1 <= words.length <= 300
  • 1 <= words[i].length <= 20
  • words[i]Bestehend aus englischen Kleinbuchstaben und Symbolen
  • 1 <= maxWidth <= 100
  • words[i].length <= maxWidth

analysieren:

  • Angesichts dieses Algorithmusproblems geriet der zweite Leiter erneut in tiefe Gedanken.
  • Zunächst müssen wir die Bedeutung des Titels sorgfältig verstehen.
  • Jede Zeile hat eine maximale Breite. Platzieren Sie so viele Wörter wie möglich innerhalb des Breitenbereichs, und die Abstände zwischen den Wörtern sind so gleichmäßig wie möglich, d. h. der maximale Unterschied beträgt ein Leerzeichen, und die meisten Leerzeichen müssen zwischen den Wörtern liegen links.
  • Es ist nicht schwer zu verstehen, aber die Implementierung enthält viele Details, was umständlich und fehleranfällig ist. Sie sollten versuchen, Methoden oder Funktionen wiederzuverwenden.
  • Wir benötigen eine Methode oder Funktion, die eine bestimmte Anzahl von Leerzeichen zwischen Wörtern füllt, die in eine Methode oder Funktion, die eine bestimmte Anzahl von Leerzeichen zu einer Zeichenfolge zusammenfügt, und eine Methode oder Funktion, die eine bestimmte Zeichenfolge zwischen Wörtern einfügt, aufgeteilt werden kann Das kann an vielen Orten wiederverwendet werden.

Antwort:

Rost:

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);
        }
    }
}

gehen:

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;
    }
}

Vielen Dank, dass Sie diesen Artikel gelesen haben ~
Willkommen bei [Gefällt mir] [Favorit] [Kommentar] Gehen Sie dreimal hintereinander ~ Es ist
nicht schwer aufzugeben, aber es muss cool sein ~
Ich hoffe, wir können uns alle jeden Tag ein wenig verbessern ~
Dieser Artikel wurde vom White Hat des zweiten Meisters geschrieben: https://le-yi.blog.csdn.net/Blog original~


Supongo que te gusta

Origin blog.csdn.net/leyi520/article/details/132143428
Recomendado
Clasificación