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

代码随想录算法训练营第十五天|右旋字符串

文档讲解:代码随想录

难度:easy

附:冲

passion!!!passion!!!passion!!! 

卡码网题目链接(opens new window)

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

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

输入:输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。

输出:输出共一行,为进行了右旋转操作后的字符串。

样例输入:

2
abcdefg 

样例输出:

fgabcde

数据范围:1 <= k < 10000, 1 <= s.length < 10000;

为了让本题更有意义,提升一下本题难度:不能申请额外空间,只能在本串上操作。 (Java不能在字符串上修改,所以使用java一定要开辟新空间)

思路

使用整体反转+局部反转

  1. 首先对整体反转
  2. 然后最后k个就是前k个,对前k个反转来恢复顺序
  3. 最后对剩下部分反转来完成

补充

 XOR 交换算法

XOR 交换算法是一种不需要临时变量就能交换两个值的方法。它的核心是利用 异或运算(XOR) 的性质:

  • 异或运算的性质:

    • a ^ a = 0

    • a ^ 0 = a

    • 异或运算是可逆的,即 (a ^ b) ^ b = a

  • 具体步骤:

    1. ch[start] ^= ch[end]:将 ch[start] 和 ch[end] 的值异或,结果存入 ch[start]

    2. ch[end] ^= ch[start]:用新的 ch[start] 值异或 ch[end],结果存入 ch[end],此时 ch[end] 变为原来的 ch[start]

    3. ch[start] ^= ch[end]:用新的 ch[end] 值异或 ch[start],结果存入 ch[start],此时 ch[start] 变为原来的 ch[end]

通过这三步,ch[start] 和 ch[end] 的值就完成了交换。

反转字符串的逻辑
  • start 指针从字符串的开头(索引 0)开始,end 指针从字符串的末尾(索引 strlen(ch) - 1)开始。

  • 每次交换 ch[start] 和 ch[end] 的值后,start 向右移动(start++),end 向左移动(end--)。

  • 当 start 不再小于 end 时,循环结束,此时字符串已经完全反转。

示例

假设 ch 是字符串 "hello"

  • 初始状态:start = 0end = 4ch = ['h', 'e', 'l', 'l', 'o']

  • 第一次交换后:ch = ['o', 'e', 'l', 'l', 'h']

  • 第二次交换后:ch = ['o', 'l', 'l', 'e', 'h']

  • 当 start 和 end 相遇时,循环结束,字符串变为 "olleh"

代码

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();

        int len = s.length();  //获取字符串长度
        char[] chars = s.toCharArray();
        reverseString(chars, 0, len - 1);  //反转整个字符串
        reverseString(chars, 0, n - 1);  //反转前一段字符串,此时的字符串首尾尾是0,n - 1
        reverseString(chars, n, len - 1);  //反转后一段字符串,此时的字符串首尾尾是n,len - 1
        
        System.out.println(chars);

    }

    public static void reverseString(char[] ch, int start, int end) {
        //异或法反转字符串,参照题目 344.反转字符串的解释
        while (start < end) {
            ch[start] ^= ch[end];
            ch[end] ^= ch[start];
            ch[start] ^= ch[end];
            start++;
            end--;
        }
    }
}

相关文章:

  • Linux的文件上传下载的lrzsz库的安装与使用
  • 《当人工智能遇上广域网:跨越地理距离的通信变革》
  • 08_双向循环神经网络
  • React 中useMemo和useCallback Hook 的作用,在什么场景下使用它们?
  • 图书管理系统系统-Java、SpringBoot、Vue和MySQL开发的图书馆管理系统
  • 文心快码 使用体验与介绍
  • 分布式算法:Paxos Raft 两种共识算法
  • 结合代码理解Spring AOP的概念(切面、切入点、连接点等)
  • Rocky Linux 软件安装:Last metadata expiration check:
  • leetcode_双指针 15.三数之和
  • 【前端扫盲】liquid模板语言
  • css重点知识汇总(二)
  • Jboss
  • [c语言日寄]枚举类型
  • Spring Boot框架中常用注解
  • 自然资源数据要素支撑场景建设
  • QEMU源码全解析 —— 块设备虚拟化(7)
  • 探秘鸿蒙 HarmonyOS NEXT:鸿蒙存储核心技术全解析
  • SLAM十四讲【四】相机与图像
  • MySQL 字符集
  • 西班牙遭遇史上最严重停电,已进入国家紧急状态
  • 伊朗外长:美伊谈判进展良好,讨论了很多技术细节
  • 网贷放款后自动扣除高额会员费,多家网贷平台被指变相收取“砍头息”
  • 孙燕姿演唱会本周末开唱,小票根如何在上海释放大活力
  • 2024年上海发生科技融资997起,位于全国第一
  • 68岁民营科技企业家、中国环保产业协会原副会长宋七棣逝世