​LeetCode刷题实战68:文本左右对齐

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 文本左右对齐,我们先来看题面:

https://leetcode-cn.com/problems/minimum-path-sum/

Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth characters and is fully (left and right) justified.

You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly maxWidth characters.

Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.

For the last line of text, it should be left justified and no extra space is inserted between words.

题意

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

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

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

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

说明:

单词是指由非空格字符组成的字符序列。

每个单词的长度大于 0,小于等于 maxWidth。

输入单词数组 words 至少包含一个单词。

样例

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

解题

https://blog.csdn.net/qq_41231926/article/details/82847865

思路:依次遍历数组中的每一个元素,每一层放尽可能多的字符

本题没有应用到什么算法方面的知识,根据题意写就行了,算是LeetCode中困难难度的简单题。需要注意以下几个注意点:

(1)最后一行的对齐方式是左对齐,需要特殊处理。

(2)如果一行中只有一个单词,其后需要填充空格至maxWidth长度。

(3)如果一行中有多个单词,其单词之间空格的计算可以先算平均分配每两个单词之间能分配到的空格数averageSpace,再将多余的空格数remainSpace从左到右依次填充进两个单词的间隔里。

整个实现过程我们只遍历了数组words一次,因此时间复杂度是O(n)级别的,其中n为words数组的长度。空间复杂度是O(1)。

我们来看下代码

public class Solution {
 
  public List<String> fullJustify(String[] words, int maxWidth) {
    List<String> list = new ArrayList<>();
    int n = words.length;
    if(n == 0) {
      return list;
    }
    //index represents which position in array words we are traversing now
    int index = 0;
    while(index < n) {
      //every String in list contains 1 word or more
      int len = words[index].length();
      int i = index + 1;
      for (; i < words.length; i++) {
        if(len + words[i].length() + 1 > maxWidth) {
          break;
        }
        len += words[i].length() + 1;
      }
      //levelLen represents how many characters that isn't space in erery String
      int levelLen = 0;
      for (int j = index; j < i; j++) {
        levelLen += words[j].length();
      }
      //numSpace represents how many space between 2 words
      int numSpace = i - index - 1;
      //string represents every String
      String string = "";
      if(i != words.length) {
        //if we haven't traversed all the words
        if(numSpace != 0) {
          //if this String has more than one word
          int[] spaces = new int[numSpace];
          int averageSpace = (maxWidth - levelLen) / numSpace;
          int remainSpace = maxWidth - levelLen - numSpace * averageSpace;
          for (int j = 0; j < numSpace; j++) {
            if(j + 1 <= remainSpace) {
              spaces[j] = 1 + averageSpace;
            }else {
              spaces[j] = averageSpace;
            }
          }
          for (int j = index, k = 0; j < i && k < numSpace;) {
            string += words[j];
            j++;
            for (int num = 0; num < spaces[k]; num++) {
              string += " ";
            }
            k++;
          }
        }
        string += words[i - 1];
        if(numSpace == 0) {
          //if this String only has one word, fill space in the remain position
          while(string.length() < maxWidth) {
            string += " ";
          }
        }
      }else {
        //if we have traversed all the words, the last String we need to put all words on the left 
        for (int j = index; j < i - 1; j++) {
          string += words[j] + " ";
        }
        string += words[i - 1];
        while(string.length() < maxWidth) {
          string += " ";
        }
      }
      list.add(string);
      index = i;
    }
    return list;
  }
}

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力。

上期推文:

LeetCode40-60题汇总,速度收藏!

LeetCode刷题实战61:旋转链表

LeetCode刷题实战62:不同路径

LeetCode刷题实战63:不同路径 II

LeetCode刷题实战64:最小路径和

LeetCode刷题实战66:加一

LeetCode刷题实战67:二进制求和

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值