代码随想录算法训练营day8 | 344. 反转字符串,541. 反转字符串 II,剑指 Offer 05. 替换空格,151.翻转字符串里的单词,剑指 Offer 58 - II. 左旋转字符串

本文介绍了几种反转字符串的Java实现,包括使用双指针交换、位运算交换以及处理特殊翻转条件的方法。每种方法都分析了其时间复杂度和空间复杂度,主要涉及字符串操作和算法设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

344. 反转字符串

541. 反转字符串 II

剑指 Offer 05. 替换空格

151.翻转字符串里的单词

剑指 Offer 58 - II. 左旋转字符串


344. 反转字符串

344. 反转字符串

难度:easy

类型:双指针,字符串

思路:

        题目很简单,可以通过双指针位运算来实现交换。

        对于位运算,这篇文章讲得不错:(62条消息) 通过位运算实现数值交换_位运算交换_我还能抢救一下的博客-CSDN博客

代码:

class Solution {
    public void reverseString(char[] s) {
        for (int i = 0; i < s.length / 2; i++) {
            char tem = s[i];
            s[i] = s[s.length - 1 - i];
            s[s.length - 1 - i] = tem;
        }
    }
}

// 位运算
class Solution {
    public void reverseString(char[] s) {
        for (int i = 0; i < s.length / 2; i++) {
            s[i] ^= s[s.length - 1 - i];
            s[s.length - 1 - i] ^= s[i];
            s[i] ^= s[s.length - 1 - i];
        }
    }
}
// 双指针
class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;
        while (left < right) {
            char tem = s[left];
            s[left] = s[right];
            s[right] = tem;
            left++;
            right--;
        }
    }
}

复杂度分析:

  • 时间复杂度:O(n)
  • 空间复杂度: O(1)

541. 反转字符串 II

541. 反转字符串 II

难度:easy

类型:字符串,双指针

 

思路:

        题意是说每隔2k为一个翻转区间,每个区间里反转前k个元素。若不足2k个再单独讨论。

        每2k个元素一个反转可通过for循环来实现,特殊情况代码如下: 

            int end = Math.min(i + k - 1, len - 1);

        很机智的做法! 

代码:

class Solution {
    public String reverseStr(String s, int k) {
        int len = s.length();
        char[] c = s.toCharArray();
        for (int i = 0; i < len; i += 2 * k) {
            int end = Math.min(i + k - 1, len - 1);
            reverseCharArray(c, i, end);
        }
        return new String(c);
    }
    // 反转字符串中的给定范围,左闭右闭
    public char[] reverseCharArray(char[] c, int start, int end) {
        while (start < end) {
            char tem = c[start];
            c[start] = c[end];
            c[end] = tem;
            start++;
            end--;
        }
        return c;
    }
}

复杂度分析:

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

剑指 Offer 05. 替换空格

剑指 Offer 05. 替换空格

难度:easy

类型:双指针

思路:

        两种方法:

        1.StringBuilder:遍历字符串s的每个元素,利用StringBuilder,遇到空格就直接替换成“%20”进行拼接。

        2.双指针:先遍历字符串,对字符串进行扩容,遇到一个空格则在字符串尾部增加两个空格。然后再用双指针进行操作,left指针指向原字符串尾部,right指针指向扩容后的字符串尾部。扩容从尾部到头部,left从尾部向头部遍历,遇到字母就放到right指向的位置(right--),遇到空格则在right指向位置存入%20。(若从头部进行,则每替换一个空格,其后面的元素都要后移。)

代码:

// 利用StringBuilder进行操作
class Solution {
    public String replaceSpace(String s) {
        if (s == null || s.length() == 0) {
            return s;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) != ' ') {
                sb.append(s.charAt(i));
            } else {
                sb.append("%20");
            }
        }
        return sb.toString();
    }
}

// 双指针法

复杂度分析:

  • 时间复杂度:O(n)
  • 空间复杂度: O(1)

151.翻转字符串里的单词

151.翻转字符串里的单词

难度:medium

类型:字符串,双指针

思路:

解题思路如下:

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转

举个例子,源字符串为:"the sky is blue "

  • 移除多余空格 : "the sky is blue"
  • 字符串反转:"eulb si yks eht"
  • 单词反转:"blue is sky the"

代码:

复杂度分析:

  • 时间复杂度:
  • 空间复杂度: 

剑指 Offer 58 - II. 左旋转字符串

难度:easy

类型:字符串,双指针

思路:

         先将[0,k-1]和[k,s.length()-1]分别反转,再反转整个字符串 ;

        例如,对于示例1:

        初始s: "abcdefg"

        反转区间:"ba gfedc"

        整体翻转:"cdefg ab"

代码:

// 先将[0,k-1]和[k,s.length()-1]分别反转,再反转整个字符串 
class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] c = s.toCharArray();
        reverseMethod(c, 0, n - 1);
        reverseMethod(c, n, c.length - 1);
        reverseMethod(c, 0,c.length - 1);
        // return String.valueOf(c);
        return new String(c);
    }

    // 左闭右闭
    public char[] reverseMethod(char[] c, int start, int end) {
        while (start < end) {
            char tem = c[start];
            c[start] = c[end];
            c[end] = tem;
            start++;
            end--;
        }
        return c;
    }
}

复杂度分析:

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

### 代码随想录算法训练营 Day20 学习内容与作业 #### 动态规划专题深入探讨 动态规划是一种通过把原问题分解为相对简单的子问题的方式来求解复杂问题的方法[^1]。 #### 主要学习内容 - **背包问题系列** - 背包问题是典型的动态规划应用场景之一。这类题目通常涉及给定容量的背包以及一系列具有不同价值和重量的物品,目标是在不超过总容量的情况下最大化所选物品的价值。 - **状态转移方程构建技巧** - 构建合适的状态转移方程对于解决动态规划问题是至关重要的。这涉及到定义好dp数组(或表格),并找到从前一个状态到下一个状态之间的关系表达式[^2]。 - **优化空间复杂度方法** - 对于某些特定类型的DP问题,可以采用滚动数组等方式来减少所需的空间开销,从而提高程序效率[^3]。 #### 实战练习题解析 ##### 题目:零钱兑换 (Coin Change) 描述:给定不同面额的硬币 coins 和一个总金额 amount。编写函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 `-1`。 解决方案: ```python def coinChange(coins, amount): dp = [float('inf')] * (amount + 1) dp[0] = 0 for i in range(1, amount + 1): for coin in coins: if i >= coin and dp[i - coin] != float('inf'): dp[i] = min(dp[i], dp[i - coin] + 1) return dp[-1] if dp[-1] != float('inf') else -1 ``` 此段代码实现了基于自底向上的迭代方式解决问题,其中 `dp[i]` 表示达到金额 `i` 所需最小数量的硬币数目[^4]。 ##### 题目:完全平方数 (Perfect Squares) 描述:给出正整数 n ,找出若干个不同的 完全平方数 (比如 1, 4, 9 ...)使得它们的和等于n 。问至少需要几个这样的完全平方数? 解答思路同上一题类似,只是这的“硬币”变成了各个可能的完全平方数值。 ```python import math def numSquares(n): square_nums = set([i*i for i in range(int(math.sqrt(n))+1)]) dp = [float('inf')] *(n+1) dp[0] = 0 for i in range(1,n+1): for sq in square_nums: if i>=sq: dp[i]=min(dp[i],dp[i-sq]+1); return dp[n]; ``` 这段代码同样运用了动态规划的思想去寻找最优解路径,并利用集合存储所有小于等于输入值的最大平方根内的平方数作为候选集[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值