LeetCode每日1题--翻转字符串里的单词

简介: LeetCode每日1题--翻转字符串里的单词

前言


算法的重要性不言而喻!区分度高!

现在学习的门槛低了,只有能上网每个人都可以学编程!培训班6个月就可以培养出来能干活的人,你怎么从这些人中脱颖而出?没错!就是学算法,学一些底层和基础的东西。

说的功利点是为了竞争,卷死对手。真心话说就是能提高自己的基础能力,为技术可持续发展做好充分的准备!!!

提前入门学习书籍:CPrimerPlus、大话数据结构

image.png


刷题网站


代码随想录 (programmercarl.com)

leetcode

我是按照代码随想录提供的刷题顺序进行刷题的,大家也可以去刷leetcode最热200道,都可以

刷题嘛,最重要的就是坚持了!!!


画图软件


OneNote

这个要经常用,遇见不懂的流程的话就拿它画一画!


笔记软件


Typoral


题目


image.png


解析


使用语言的特性


这里采用Leecode上官方的解法,官方给的图很清晰,而且也很好理解。这里我们做一个简单的了解即可,因为这种方式是调用API来完成,并不是能达到锻炼我们操作字符串的能力!

Java中提供了对字符串的split、reverse、join等方法,我们可以直接调用API来完成操作:

  1. 首先用split按空格分割字符串数组

image.png

2.在使用reverse把字符串数组进行反转

  1. 最后使用join将字符串数组拼成字符串

image.png

完整代码如下:


class Solution {
    public String reverseWords(String s) {
        s = s.trim();
        List<String> wordList = Arrays.asList(s.split("\s+"));
        Collections.reverse(wordList);
        return String.join(" ", wordList);
    }
}


编写函数完成


这道题我们当然要自己来编写函数来解啊,这才能得到锻炼

思路还是一样的:

  1. 去除首尾以及中间多余空格
  2. 反转整个字符串
  3. 反转单词

去除首尾以及中间多余空格


private StringBuilder removeSpace(String s) {
    int start = 0;
    int end = s.length() - 1;
    while (s.charAt(start) == ' ') start++;
    while (s.charAt(end) == ' ') end--;
    //上面这两步就完成了对首尾空格的去除
    StringBuilder sb = new StringBuilder();
    while (start <= end) {
        char c = s.charAt(start);
        if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
            sb.append(c);
        }
        start++;
    }
    return sb;
}

反转整个字符串

这里利用了StringBuilder直接交换单词顺序

经过反转字符串,单词的顺序还是反着的,所以我们还需要再写一个方法来做字母的反转


public void reverseString(StringBuilder sb, int start, int end) {
    while (start < end) {
        char temp = sb.charAt(start);
        sb.setCharAt(start, sb.charAt(end));
        sb.setCharAt(end, temp);
        start++;
        end--;
    }
}

反转字母

字母的反转我们也可以用上面字符串反转的方法,对每一组字符串都进行反转就可得到最终的反转结果


private void reverseEachWord(StringBuilder sb) {
    int start = 0;
    int end = 1;
    int n = sb.length();
    while (start < n) {
        //            对空格不进行反转,选择跳过
        while (end < n && sb.charAt(end) != ' ') {
            end++;
        }
        //对字母进行再次反转
        //这里的end-1是因为end的索引是从1开始的,不减1到后面会越界
        reverseString(sb, start, end - 1);
        /**
             * 注意这里是意思是反转完第一组单词后,进行第二组单词的反转
             * 此时要给start指针和end指针重新赋值,start指针的赋值为end+1,也就是跳过了空字符串的情况
             * 上一步经过反转的end指针的位置是end-1
             */
        start = end + 1;
        end = start + 1;
    }
}

完整代码如下


package com.caq.string;
import java.util.Arrays;
public class ReverseString3 {
    public static void main(String[] args) {
        String s = "hello  world !  ";
        ReverseString3 re = new ReverseString3();
        String s3 = re.reverseWors(s);
        System.out.println(s3);
    }
    /**
     * 1.去除首尾以及中间多余空格
     * 2.反转整个字符串
     * 3.反转单词
     */
    public String reverseWors(String s) {
        // 1.去除首尾以及中间多余空格
        StringBuilder sb = removeSpace(s);
        // 2.反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        // 3.反转各个单词
        reverseEachWord(sb);
        return sb.toString();
    }
    /**
     * 移除空格
     *
     * @param s
     * @return
     */
    private StringBuilder removeSpace(String s) {
        int start = 0;
        int end = s.length() - 1;
        while (s.charAt(start) == ' ') start++;
        while (s.charAt(end) == ' ') end--;
        StringBuilder sb = new StringBuilder();
        while (start <= end) {
            char c = s.charAt(start);
            if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }
            start++;
        }
        return sb;
    }
    /**
     * 反转字符串
     * 反转数组就是最基本的双指针
     * 这里反转字符串借助StringBuilder完成
     */
    public void reverseString(StringBuilder sb, int start, int end) {
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
    }
    /**
     * 反转字母
     * 怎么反转的呢,一组一组的去反转
     *
     * @param sb
     */
    private void reverseEachWord(StringBuilder sb) {
        int start = 0;
        int end = 1;
        int n = sb.length();
        while (start < n) {
//            对空格不进行反转,选择跳过
            while (end < n && sb.charAt(end) != ' ') {
                end++;
            }
            //对字母进行再次反转
            //这里的end-1是因为end的索引是从1开始的,不减1到后面会越界
            reverseString(sb, start, end - 1);
            /**
             * 注意这里是意思是反转完第一组单词后,进行第二组单词的反转
             * 此时要给start指针和end指针重新赋值,start指针的赋值为end+1,也就是跳过了空字符串的情况
             * 上一步经过反转的end指针的位置是end-1
             */
            start = end + 1;
            end = start + 1;
        }
    }
}



相关文章
|
8月前
|
Go 索引
【LeetCode 热题100】394:字符串解码(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 394:字符串解码。题目要求对编码字符串如 `k[encoded_string]` 进行解码,其中 `encoded_string` 需重复 `k` 次。文章提供了两种解法:使用栈模拟和递归 DFS,并附有 Go 语言实现代码。栈解法通过数字栈与字符串栈记录状态,适合迭代;递归解法则利用函数调用处理嵌套结构,代码更简洁。两者时间复杂度均为 O(n),但递归需注意栈深度问题。文章还总结了解题注意事项及适用场景,帮助读者更好地掌握字符串嵌套解析技巧。
220 6
|
9月前
|
存储 机器学习/深度学习 缓存
🚀 力扣热题 394:字符串解码(详细解析)(Go语言版)
文章提供了两种解法:栈结构和递归解法。栈解法通过维护数字栈与字符串栈,依次处理 `[` 和 `]`,构造解码结果;递归解法则利用函数调用逐层解析嵌套结构。两者时间复杂度均为 $O(n)$,空间复杂度也为 $O(n)$。栈解法直观易懂,适合初学者;递归解法优雅简洁,适合处理深度嵌套规则。掌握这两种方法,可灵活应对类似问题,提升解题能力。
309 11
|
C++
Leetcode第43题(字符串相乘)
本篇介绍了一种用C++实现的字符串表示的非负整数相乘的方法,通过逆向编号字符串,将乘法运算转化为二维数组的累加过程,最后处理进位并转换为字符串结果,解决了两个大数相乘的问题。
124 9
|
JavaScript
力扣3333.找到初始输入字符串Ⅱ
【10月更文挑战第9天】力扣3333.找到初始输入字符串Ⅱ
172 1
|
算法 C++
Leetcode第八题(字符串转换整数(atoi))
这篇文章介绍了LeetCode上第8题“字符串转换整数(atoi)”的解题思路和C++的实现方法,包括处理前导空格、正负号、连续数字字符以及整数溢出的情况。
184 0
Leetcode(最后一个单词长度)
这篇文章介绍了两种解决LeetCode第58题的方法,即计算给定字符串中最后一个单词的长度,方法包括翻转字符串和逆向遍历统计。
99 0
【LeetCode 22】459.重复的子字符串
【LeetCode 22】459.重复的子字符串
141 0
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
120 0
【LeetCode 19】541.反转字符串II
【LeetCode 19】541.反转字符串II
109 0
【LeetCode 18】6.2.反转字符串
【LeetCode 18】6.2.反转字符串
91 0