代码随想录算法 - 字符串 Part1

本文介绍了多个关于字符串操作的编程题目,包括反转字符数组、字符串反转II、替换数字中的数字字符、反转单词顺序以及右旋字符串。解决方案涉及双指针法、字符串切片和字符数组操作,强调在限定空间复杂度下的代码实现。
摘要由CSDN通过智能技术生成

题目链接344.反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
解题思路:看到这道题目没啥好说的,直接一个双指针交换搞定
 

class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;
        // 临时变量,暂存字符
        char temp;  
        // 直到左右指针相遇
        while(left < right){
            // 暂存左指针字符
            temp = s[left];     
            s[left++] = s[right];   
            s[right--] = temp;      
        }
    }
}

题目链接541.反转字符串II

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。


解题思路:看到这道题目一脸懵逼没看懂啥意思,搞了半天才明白是:从头开始,第0到k个反转 k+1 到2k正常,2k+1到3k反转。。。所以解法就很明确了循环一遍字符串,每隔2k个反转前k个,尾数不够k个时全部反转。直接用下标法或者转为数组再for循环都行。

class Solution {
    public String reverseStr(String s, int k) {
        char[] charArray = s.toCharArray();
        for (int i = 0; i <= charArray.length - 1; i += 2 * k) {
            int start = i;
            int end = Math.min(charArray.length - 1, start + k - 1);
            while (start < end) {
                char temp = charArray[start];
                charArray[start++] = charArray[end];
                charArray[end--] = temp;
            }
        }
        return String.valueOf(charArray);
    }
}

易错点:靠又看错下标,第k个字符,下标是k-1。。。

题目链接54.替换数字

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。


解题思路:看到这道题目的第一想法是直接循环一遍遇到数字直接替换成number。

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            // 判断是否为数字
            if (Character.isDigit(s.charAt(i))) {
                sb.append("number");
            } else sb.append(s.charAt(i));
        }
        System.out.println(sb);
    }
}

题目链接151.反转字符串中的单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串


解题思路:看到这道题目的第一想法和反转字符串类似,多了对空格的处理。主要分为三步:
1.去除字符串中多余的空格,并且每个单词间只有一个空格
2.将整个字符串进行反转
3.将每个单词进行反转

class Solution {
    public String reverseWords(String s) {
        s = s.trim();
        // 去除空格
        StringBuilder s1 = removeExtraSpaces(s);
        // 反转字符串
        reverseString(s1, 0, s1.length() - 1);
        // 反转每个单词
        reverseEachWord(s1);
        return s1.toString();
    }
    
    private StringBuilder removeExtraSpaces(String s) {
        int start = 0;
        int end = s.length() - 1;
        StringBuilder sb = new StringBuilder();

        while (start <= end) {
            char c = s.charAt(start);
            // sb最后一位不为' '时添加' '
            if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }
            start++;
        }
        return sb;
    }

    //对指定区间进行反转,左闭右闭
    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 s) {
        //起始下标
        int start = 0;
        int end = 1;
        while (start < s.length()) {
            while (end < s.length() && s.charAt(end) != ' ') {
                end++;
            }
            reverseString(s, start, end - 1);
            start = end + 1;
            end = start + 1;
        }
    }
}

题目链接55.右旋字符串

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。 

例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。


解题思路:看到这道题目的第一想法是直接反转三次即可。

  1. 反转区间为前n的子串
  2. 反转区间为n到末尾的子串
  3. 反转整个字符串
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = Integer.parseInt(in.nextLine());
        String s = in.nextLine();
        StringBuilder sb = new StringBuilder(s);
        reserveString(sb, 0, n - 1);
        reserveString(sb, n, s.length() - 1);
        reserveString(sb, 0, sb.length() - 1);
        System.out.println(sb);
    }

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

代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值