题目:

给定一个单词数组 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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/text-justification
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

属实打脑壳,数学思维,就是处理代码的时候转不过来弯,看了别人的代码,加上自己的注解

每一行的情况分为三种:

1.一行只有一个单词:先放入单词,计算出剩余的空格数,右边全部添加空格即可;

2.最后一行:除了每个单词后面的一个空格,不再添加额外空格,计算出额外的空格数,添加至末尾即可;

3.普通情况一行多词:先均匀分配空格数,不能均匀分配剩下的,从左边开始空格依次加1。

先写主框架,框架里面添加使用的方法名,然后遇到一个方法补充一个方法,在方法里面写上具体的处理逻辑,再回到主框架在方法名中添加具体的参数。

代码:

  1 class Solution {
2 public List<String> fullJustify(String[] words, int maxWidth) {
3 List<String> res = new ArrayList<>();
4 //统计每行单词的长度
5 int count = 0;
6 //开始单词的位置
7 int start = 0;
8
9 for(int i = 0; i < words.length; i++){
10 //单词的长度
11 count += words[i].length();
12 //如果当前单词的长度大于最大长度
13 if(count > maxWidth){
14 //向结果中添加,只添加当前单词的前一个单词,不然没法加空格
15 res.add(fillword(words, start, i-1, maxWidth));
16 //更新起始位置
17 start = i;
18 //统计单词的长度从当前位置开始
19 count = words[i].length();
20 }
21 //遍历完每个单词时需要加上一个固定空格
22 count++;
23 }
24 //处理剩下的单词
25 res.add(fillword(words, start, words.length - 1, maxWidth));
26 return res;
27 }
28
29 //每一行处理过程,分三种情况
30 //start单词开始位置,end结束位置
31 public String fillword(String[] words, int start, int end, int maxWidth) {
32 StringBuilder sb = new StringBuilder();
33 //当前行只有一个单词,不是最后一行
34 if(start == end){
35 oneWordfill(words, start, maxWidth, sb);
36 }else if(end == words.length-1){
37 //最后一行
38 lastRowfill(words, start, end, maxWidth, sb);
39 }else{
40 //普通情况,一行多个单词
41 normalfill(words, start ,end, maxWidth, sb);
42 }
43 return sb.toString();
44 }
45
46 //处理一行只有一个单词的方法
47 public void oneWordfill(String[] words, int start, int maxWidth, StringBuilder sb){
48 //添加单词到开头
49 sb.append(words[start]);
50 //该行剩下的其他位置添加空格
51 int spacenums = maxWidth - words[start].length();
52 for(int i = 0; i < spacenums; i++){
53 sb.append(" ");
54 }
55 }
56
57 //处理最后一行的方法
58 public void lastRowfill(String[] words, int start, int end, int maxWidth, StringBuilder sb){
59 for(int i = start; i <= end; i++){
60 sb.append(words[i]);
61 //还没打末尾时单词之间添加一个空格
62 if(i != end){
63 sb.append(" ");
64 } else{
65 //单词添加完后,剩下的位置全为空格
66 //统计空格数,并添加空格到末尾
67 int spacenums = maxWidth - sb.length();
68 for(int j = 0; j < spacenums; j++){
69 sb.append(" ");
70 }
71 }
72 }
73 }
74
75 //处理一般情况,平均分配空格,不能平均左边空格多于右边
76 public void normalfill(String[] words, int start, int end, int maxWidth, StringBuilder sb){
77 //先统计这行单词长度
78 int wordslength = 0;
79 for(int i = start; i <= end; i++){
80 wordslength += words[i].length();
81 }
82 //统计均分的空格数,end-start为总的间隔数
83 //比如从第三个单词开始,到第6个单词之间有三个间隔可以放空格
84 int spaceavg = (maxWidth - wordslength) / (end - start);
85 //不能均分之后的空格数
86 //4个单词有3个间隔,一共有5个空格,均分一个空格之后,还留2个,结果就是第一个和第二个间隔后面两个空格,剩下的空隙一个空格
87 int remainspace = (maxWidth - wordslength) % (end - start);
88
89 for(int i = start; i <= end; i++){
90 //添加单词进去
91 sb.append(words[i]);
92 if(i != end){
93 //添加平均分配的空格
94 for(int j = 0; j < spaceavg; j++){
95 sb.append(" ");
96 }
97 //添加剩余空格
98 if(remainspace > 0){
99 sb.append(" ");
100 remainspace--;
101 }
102 }
103 }
104 }
105 }

记录一下我自己的疑惑点:

我以为在当前单词后面添加空格会直到if语句不成立才会停止,这样就会添加多余空格。实际不是!!!

比如我理解的是:

4个单词有3个间隔,第一个单词后3个空格,第二个单词后2个,第三个单词后1个,但是实际是第一个单词后面2个空格,第一个单词后面2个空格,第三个单词后面1个空格。
正确执行过程:
先添加第一个单词,然后添加平均分配的空格1个,执行下一个if语句,添加一个多余空格,执行完后,remainspace=1,就继续添加第二个单词,添加平均分配的空格1个,在执行if语句,添加一个多余的空格,执行完后remainspace由1变为0,再添加第三个单词,添加平均分配的空格1个,由于remainspace = 0 没法执行if语句,不再添加多余空格了,再继续添加第四个单词,由于已经到末尾单词了,不会添加平均空格了。整个过程结束,最终空格数在三个间隔中应该是 2 2 1。

力扣68(java)-文本左右对齐(困难)的更多相关文章

  1. Java实现 LeetCode 68 文本左右对齐

    68. 文本左右对齐 给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本. 你应该使用"贪心算法"来放置 ...

  2. Leetcode 68.文本左右对齐

    文本左右对齐 给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本. 你应该使用"贪心算法"来放置给定的单 ...

  3. [leetcode] 68. 文本左右对齐(国区第240位AC的~)

    68. 文本左右对齐 国区第240位AC的~我还以为坑很多呢,一次过,嘿嘿,开心 其实很简单,注意题意:使用"贪心算法"来放置给定的单词:也就是说,尽可能多地往每行中放置单词. 也 ...

  4. LeetCode(68):文本左右对齐

    Hard! 题目描述: 给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本. 你应该使用“贪心算法”来放置给定的单词:也就是 ...

  5. 力扣算法经典第一题——两数之和(Java两种方式实现)

    一.题目 难度:简单 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数, 并返回它们的数组下标. 你可以假设每种输入只会对应一 ...

  6. JS数据结构第六篇 --- 二叉树力扣练习题

    1.第226题:翻转二叉树 递归+迭代两种实现方式: /** 反转二叉树 * Definition for a binary tree node. * function TreeNode(val) { ...

  7. 力扣1438. 绝对差不超过限制的最长连续子数组-C语言实现-中等难度

    题目 传送门 文本 给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit . 如果不存在满足条 ...

  8. 力扣1052. 爱生气的书店老板-C语言实现-中等难度

    题目 传送门 文本 今天,书店老板有一家店打算试营业 customers.length 分钟.每分钟都有一些顾客(customers[i])会进入书店,所有这些顾客都会在那一分钟结束后离开. 在某些时 ...

  9. 力扣832. 翻转图像-C语言实现-简单题

    题目 传送门 文本 给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果. 水平翻转图片就是将图片的每一行都进行翻转,即逆序.例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, ...

  10. 力扣896. 单调数列-C语言实现-简单题

    题目 传送门 文本 如果数组是单调递增或单调递减的,那么它是单调的. 如果对于所有 i <= j,A[i] <= A[j],那么数组 A 是单调递增的. 如果对于所有 i <= j, ...

随机推荐

  1. Linux查看用户的7个命令

    Linux是中国IT实验室的一个技术频道.包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类      在Linux系统里,我们会经常用Linux查看用户的命令,在这里我们一些 ...

  2. 杂谈之WEB前端工程师身价

    了解javascript语言规范么?+1000 知道各浏览器的css差异么?+1000 javascript差异呢?+1000 知道html各标签的含义并很好地运用么?+1000 知道如何跨浏览器解决 ...

  3. FFmpeg介绍与编译

    目录 FFmpeg FFmpeg核心模块 FFmpeg编译 FFmpeg FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制 ...

  4. 快速排序——Java

    快排的思想想必大家都懂,前后两个指针,向中间靠拢.我这个partition函数能保证所有相同的数都被比较一次,靠拢在一起. 代码: public class Main { public static ...

  5. Java课堂

    import java.awt.*; import java.awt.event.*; import java.util.*; public class Main{ public static dou ...

  6. 文旅新体验!3DCAT助力广州非遗“元宇宙”街区炫酷亮相

    2022年6月12日,2022年"文化和自然遗产日"广州非遗宣传展示主会场暨广州非遗街区(北京路)开街仪式在南越王博物院(王宫展区)举行. 本次活动由广州市文化广电旅游局主办,广州 ...

  7. java的对象内存和数据类型

    一.三种情况的对象内存图 (1)Java内存分配介绍: 栈: 队: 方法区(jdk7):加载字节码文件.(从jdk8开始取消方法区,新增元空间,把原来方法区的多种功能进行拆分,有的功能放到堆中,有的功 ...

  8. 记录--【vue3】写hook三天,治好了我的组件封装强迫症。

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 我以前很喜欢封装组件,什么东西不喜欢别人的,总喜欢自己搞搞,这让人很有成就感,虽然是重复造轮子,但是能从无聊的crud业务中暂时解脱 ...

  9. 《Go程序设计语言》学习笔记之结构体

    <Go程序设计语言>学习笔记之结构体 一. 环境 Centos8.5, go1.17.5 linux/amd64 二. 概念 结构体是将零个或者多个任意类型的命名变量组合在一起的聚合数据类 ...

  10. LOTO示波器客户应用案例展示

    LOTO示波器客户应用案例展示 LOTO示波器以软件功能为核心,采用独特的积木式可扩展的硬件架构,为多行业的电子电路研发工程师提供高性价比的解决方案.我们初步汇总了一些客户实测的应用案例展示如下: 1 ...