当前位置: 首页 > article >正文

面试经典150题——文本左右对齐(困难)

​"It always seems impossible until it’s done."

- Nelson Mandela

1. 题目描述:

这个题目标为困难题目,但是如果我们静下心来把题目读懂了,其实无非就是不同情况下不同考虑而已,也没什么思维上的复杂,还比不上我们上一篇文章讲的KMP算法烧脑。

2. 题目分析与解析

解题思路:其实用下面一张流程图就可以很好的理解并做出该题。

其实就是一系列的情况的分类而已,并没有太复杂。

3.代码实现

首先我们来实现主循环部分,我就直接把注释写在代码里了。

public List<String> fullJustify(String[] words, int maxWidth) {
    // 记录总的结果
    ArrayList<String> ret = new ArrayList<>();
    // 记录当前行的单词
    ArrayList<String> lineRet = new ArrayList<>();
    // 记录当前行的字符串长度
    int len = 0;
    // 记录当前行有多少个单词
    int wordCount = 0;
    // 开始遍历每个单词
    for (int i = 0; i < words.length; i++) {
        String word = words[i];
        // +1是因为要保证每一个单词后有至少要有一个空格
        int strLen = word.length() + 1;
        // 加入当前行的总长
        len += strLen;
        // 可以放入当前行(len-1是因为一行的最后一个单词后没有空格)
        if (len - 1 <= maxWidth) {
            //当是最后一行
            if (i == words.length - 1) {
                StringBuilder lastLine = new StringBuilder();
                // 最后一行的单词之间只有一个空格,末尾要加空格
                for (String item : lineRet) {
                    lastLine.append(item).append(" ");
                }
                // 加上当前单词
                lastLine.append(word);
                // 补充结尾空格
                for (int j = lastLine.length(); j < maxWidth; j++) {
                    lastLine.append(" ");
                }
                ret.add(lastLine.toString());
            // 不是最后一行
            } else {
                lineRet.add(word);
                wordCount++;
            }
        // 放不下当前行
        } else {
            // 如果只有一个单词,左对齐
            if (wordCount == 1) {
                // 计算要补上的空格数
                int spaceLen = maxWidth - lineRet.get(0).length();
                StringBuilder sb = new StringBuilder();
                // 补上空格
                for (int j = 0; j < spaceLen; j++) {
                    sb.append(" ");
                }
                String spaces = sb.toString();
                ret.add(lineRet.get(0) + spaces);
                
            // 如果包含很多个单词,那就左右对齐,同时保证空格数尽量平均,且左边更多
            } else {
                // 改行总共应该有多少个空格
                int spaceCount = maxWidth - len + strLen + wordCount;
                // 包装函数获取左右对齐的字符串,sb即为当前行结果
                StringBuilder sb = getSb(spaceCount, wordCount, lineRet);
                ret.add(sb.toString());
            }
            // 清0
            lineRet.clear();
            len = 0;
            wordCount = 0;
            i--;
        }
    }
    return ret;
}

现在我们来看一下对于包含很多个单词,左右对齐,同时保证空格数尽量平均,且左边更多的过程的函数getSb(spaceCount, wordCount, lineRet)。

	/**
     * 获取左右对齐的字符串
     *
     * @param spaceCount 总共的空格数
     * @param wordCount  当前行单词数
     * @param lineRet    当前行的单词
     * @return 左右对齐的字符串
     */
private static StringBuilder getSb(int spaceCount, int wordCount, ArrayList<String> lineRet) {
    // 计算每个间隔平均放几个空格
    int space = spaceCount / (wordCount - 1);
    // 多余的空格
    int extraSpace = spaceCount % (wordCount - 1);
    StringBuilder sb = new StringBuilder();
    for (int j = 0; j < lineRet.size(); j++) {
        sb.append(lineRet.get(j));
        // 最后一个单词后不加空格
        if (j != lineRet.size() - 1) {
            for (int k = 0; k < space; k++) {
                sb.append(" ");
            }
            // 每一次进来就相当于从左到右加一个多余的空格,那么我左边肯定比右边空格多
            if (extraSpace > 0) {
                sb.append(" ");
                extraSpace--;
            }
        }
    }
    return sb;
}

好了代码到这就完成了,是不是很easy?遇到困难题不要慌,没准就是吓唬吓唬你!

4. 运行结果

当然还有很大的优化空间,但是思路是正确的,我看了下官方思路也是相同的,优化的话就是很多for循环是不必要的,可以用join函数实现。


http://www.kler.cn/a/228410.html

相关文章:

  • AWTK-WEB 快速入门(3) - C 语言 Http 应用程序
  • 论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(一)
  • 【Pandas】pandas Series groupby
  • Golang 中强大的重试机制,解决瞬态错误
  • 【物联网】keil仿真环境设置 keilV5可以适用ARM7
  • 深度学习-89-大语言模型LLM之AI应用开发的基本概念
  • MagicVideo-V2:多阶段高保真视频生成框架
  • git将项目的某次签入遴选(Cherry-Pick)另一个项目
  • Open CASCADE学习|分割曲线
  • PyTorch、NCNN、CV::Mat三者张量的shape
  • springboot基于javaWEB的旅游推荐系统设计与实现+vue
  • Element UI+Spring Boot进行CRUD的实例
  • 【Android】240204 android studio build.gradle.kts APK名字带日期
  • LeetCode每日一题 | 1686. 石子游戏 VI
  • 工厂模式与抽象工厂模式
  • 跨平台开发:浅析uni-app及其他主流APP开发方式
  • 为什么MFC中线程操作界面UI会出现异常问题,如何来避免或解决这种问题?
  • 基于OpenCV灰度图像转GCode的双向扫描实现
  • 产品研发时方向摇摆不定,变更频繁,该如何解决?
  • Linux---yum命令详解
  • java处理ppt方案详解
  • ChatGPT之制作短视频
  • Fink CDC数据同步(五)Kafka数据同步Hive
  • 机器学习系列——(十一)回归
  • PDF下载添加水印和访问密码
  • Hive与PrestoSQL中的并列列转行